[GOLD] override get_comdat_behavior
Alan Modra
amodra@gmail.com
Thu Oct 18 00:02:00 GMT 2012
On Thu, Oct 18, 2012 at 09:00:53AM +1030, Alan Modra wrote:
> On Wed, Oct 17, 2012 at 11:33:55AM -0700, Ian Lance Taylor wrote:
> > On Wed, Oct 17, 2012 at 8:02 AM, Alan Modra <amodra@gmail.com> wrote:
> > > Powerpc use of .got2 section in -fPIC code can lead to "relocation
> > > refers to discarded section" warnings in testcases like gcc's
> > > g++.old-deja/g++.other/comdat5.C when comdat group sections for a
> > > function are dropped but not the function's .got2 entries. This type
> > > of problem shows up in other sections shared between functions on
> > > powerpc64, eg. .opd and .toc. Fixed by suppressing the warning the
> > > same way bfd ld does. OK to apply?
> > >
> > > * target-reloc.h (relocate_section): Call get_comdat_behavior
> > > from class Relocate.
> > > * arm.cc (Relocate::get_comdat_behavior): New.
> > > * i386.cc (Relocate::get_comdat_behavior): New.
> > > * sparc.cc (Relocate::get_comdat_behavior): New.
> > > * tilegx.cc (Relocate::get_comdat_behavior): New.
> > > * x86_64.cc (Relocate::get_comdat_behavior): New.
> > > * powerpc.cc (Relocate::get_comdat_behavior): New.
> > > (Target_powerpc::relocate_section): Don't zap opd relocs.
> >
> >
> > You can implement this without requiring every target to have a
> > trivial get_comdat_behavior method. Add a new template parameter to
> > relocate_section in target-reloc.h. Give it a default value.
> >
> > template<..., typename Relocate_comdat_behaviour = Default_comdat_behavior>
> > inline void
> > Relocate_section(...)
>
> I thought about doing that but
>
> error: default template arguments may not be used in function templates without -std=c++0x or -std=gnu++
So now without the default template arg.
* target-reloc.h (class Default_comdat_behavior): New, package up..
(get_comdat_behaviour): ..this.
(relocate_section): Add Relocate_comdat_behavior template arg,
adjust code to suit.
* arm.cc (Target_arm::relocate_section): Adjust to suit.
(Target_arm::scan_reloc_section): Likewise.
* i386.cc (Target_i386::relocate_section): Likewise.
* sparc.cc (Target_sparc::relocate_section): Likewise.
* tilegx.cc (Target_tilegx::relocate_section): Likewise.
* x86_64.cc (Target_x86_64::relocate_section): Likewise.
* powerpc.cc (class Relocate_comdat_behavior): New.
(Target_powerpc::relocate_section): Don't zap opd relocs. Supply
gold::relocate_section with new template arg.
Index: gold/target-reloc.h
===================================================================
RCS file: /cvs/src/src/gold/target-reloc.h,v
retrieving revision 1.54
diff -u -p -r1.54 target-reloc.h
--- gold/target-reloc.h 12 Sep 2012 22:43:53 -0000 1.54
+++ gold/target-reloc.h 17 Oct 2012 23:29:19 -0000
@@ -124,20 +124,24 @@ enum Comdat_behavior
CB_WARNING // Print a warning.
};
-// Decide what the linker should do for relocations that refer to discarded
-// comdat sections. This decision is based on the name of the section being
-// relocated.
-
-inline Comdat_behavior
-get_comdat_behavior(const char* name)
+class Default_comdat_behavior
{
- if (Layout::is_debug_info_section(name))
- return CB_PRETEND;
- if (strcmp(name, ".eh_frame") == 0
- || strcmp(name, ".gcc_except_table") == 0)
- return CB_IGNORE;
- return CB_WARNING;
-}
+ public:
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections. This decision is based on the name of
+ // the section being relocated.
+
+ inline Comdat_behavior
+ get(const char* name)
+ {
+ if (Layout::is_debug_info_section(name))
+ return CB_PRETEND;
+ if (strcmp(name, ".eh_frame") == 0
+ || strcmp(name, ".gcc_except_table") == 0)
+ return CB_IGNORE;
+ return CB_WARNING;
+ }
+};
// Give an error for a symbol with non-default visibility which is not
// defined locally.
@@ -220,6 +224,11 @@ issue_undefined_symbol_error(const Symbo
// a single function, relocate(), which implements the machine
// specific part of a relocation.
+// The template parameter Relocate_comdat_behavior is a class type
+// which provides a single function, get(), which determines what the
+// linker should do for relocations that refer to discarded comdat
+// sections.
+
// SIZE is the ELF size: 32 or 64. BIG_ENDIAN is the endianness of
// the data. SH_TYPE is the section type: SHT_REL or SHT_RELA.
// RELOCATE implements operator() to do a relocation.
@@ -241,7 +250,8 @@ issue_undefined_symbol_error(const Symbo
// relocation.
template<int size, bool big_endian, typename Target_type, int sh_type,
- typename Relocate>
+ typename Relocate,
+ typename Relocate_comdat_behavior>
inline void
relocate_section(
const Relocate_info<size, big_endian>* relinfo,
@@ -258,6 +268,7 @@ relocate_section(
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
Relocate relocate;
+ Relocate_comdat_behavior relocate_comdat_behavior;
Sized_relobj_file<size, big_endian>* object = relinfo->object;
unsigned int local_count = object->local_symbol_count();
@@ -348,7 +359,7 @@ relocate_section(
if (comdat_behavior == CB_UNDETERMINED)
{
std::string name = object->section_name(relinfo->data_shndx);
- comdat_behavior = get_comdat_behavior(name.c_str());
+ comdat_behavior = relocate_comdat_behavior.get(name.c_str());
}
if (comdat_behavior == CB_PRETEND)
{
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.155
diff -u -p -r1.155 arm.cc
--- gold/arm.cc 12 Sep 2012 22:43:53 -0000 1.155
+++ gold/arm.cc 17 Oct 2012 23:39:04 -0000
@@ -9518,7 +9518,7 @@ Target_arm<big_endian>::relocate_section
}
gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
- Arm_relocate>(
+ Arm_relocate, gold::Default_comdat_behavior>(
relinfo,
this,
prelocs,
@@ -11150,6 +11150,7 @@ Target_arm<big_endian>::scan_reloc_secti
Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);
unsigned int local_count = arm_object->local_symbol_count();
+ gold::Default_comdat_behavior default_comdat_behavior;
Comdat_behavior comdat_behavior = CB_UNDETERMINED;
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
@@ -11323,7 +11324,7 @@ Target_arm<big_endian>::scan_reloc_secti
if (comdat_behavior == CB_UNDETERMINED)
{
std::string name = arm_object->section_name(relinfo->data_shndx);
- comdat_behavior = get_comdat_behavior(name.c_str());
+ comdat_behavior = default_comdat_behavior.get(name.c_str());
}
if (comdat_behavior == CB_PRETEND)
{
Index: gold/i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.149
diff -u -p -r1.149 i386.cc
--- gold/i386.cc 5 Oct 2012 00:45:54 -0000 1.149
+++ gold/i386.cc 17 Oct 2012 23:29:18 -0000
@@ -3487,7 +3487,7 @@ Target_i386::relocate_section(const Relo
gold_assert(sh_type == elfcpp::SHT_REL);
gold::relocate_section<32, false, Target_i386, elfcpp::SHT_REL,
- Target_i386::Relocate>(
+ Target_i386::Relocate, gold::Default_comdat_behavior>(
relinfo,
this,
prelocs,
Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.65
diff -u -p -r1.65 powerpc.cc
--- gold/powerpc.cc 17 Oct 2012 14:33:41 -0000 1.65
+++ gold/powerpc.cc 17 Oct 2012 23:29:18 -0000
@@ -619,6 +619,32 @@ class Target_powerpc : public Sized_targ
enum skip_tls call_tls_get_addr_;
};
+ class Relocate_comdat_behavior
+ {
+ public:
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ inline Comdat_behavior
+ get(const char* name)
+ {
+ gold::Default_comdat_behavior default_behavior;
+ Comdat_behavior ret = default_behavior.get(name);
+ if (ret == CB_WARNING)
+ {
+ if (size == 32
+ && (strcmp(name, ".fixup") == 0
+ || strcmp(name, ".got2") == 0))
+ ret = CB_IGNORE;
+ if (size == 64
+ && (strcmp(name, ".opd") == 0
+ || strcmp(name, ".toc") == 0
+ || strcmp(name, ".toc1") == 0))
+ ret = CB_IGNORE;
+ }
+ return ret;
+ }
+ };
+
// A class which returns the size required for a relocation type,
// used while scanning relocs during a relocatable link.
class Relocatable_size_for_reloc
@@ -5051,48 +5077,13 @@ Target_powerpc<size, big_endian>::reloca
{
typedef Target_powerpc<size, big_endian> Powerpc;
typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
+ typedef typename Target_powerpc<size, big_endian>::Relocate_comdat_behavior
+ Powerpc_comdat_behavior;
gold_assert(sh_type == elfcpp::SHT_RELA);
- unsigned char *opd_rel = NULL;
- Powerpc_relobj<size, big_endian>* const object
- = static_cast<Powerpc_relobj<size, big_endian>*>(relinfo->object);
- if (size == 64
- && relinfo->data_shndx == object->opd_shndx())
- {
- // Rewrite opd relocs, omitting those for discarded sections
- // to silence gold::relocate_section errors.
- const int reloc_size
- = Reloc_types<elfcpp::SHT_RELA, size, big_endian>::reloc_size;
- opd_rel = new unsigned char[reloc_count * reloc_size];
- const unsigned char* rrel = prelocs;
- unsigned char* wrel = opd_rel;
-
- for (size_t i = 0;
- i < reloc_count;
- ++i, rrel += reloc_size, wrel += reloc_size)
- {
- typename Reloc_types<elfcpp::SHT_RELA, size, big_endian>::Reloc
- reloc(rrel);
- typename elfcpp::Elf_types<size>::Elf_WXword r_info
- = reloc.get_r_info();
- unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
- Address r_off = reloc.get_r_offset();
- if (r_type == elfcpp::R_PPC64_TOC)
- r_off -= 8;
- bool is_discarded = object->get_opd_discard(r_off);
-
- // Reloc number is reported in some errors, so keep all relocs.
- if (is_discarded)
- memset(wrel, 0, reloc_size);
- else
- memcpy(wrel, rrel, reloc_size);
- }
- prelocs = opd_rel;
- }
-
gold::relocate_section<size, big_endian, Powerpc, elfcpp::SHT_RELA,
- Powerpc_relocate>(
+ Powerpc_relocate, Powerpc_comdat_behavior>(
relinfo,
this,
prelocs,
@@ -5103,9 +5094,6 @@ Target_powerpc<size, big_endian>::reloca
address,
view_size,
reloc_symbol_changes);
-
- if (opd_rel != NULL)
- delete[] opd_rel;
}
class Powerpc_scan_relocatable_reloc
Index: gold/sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.62
diff -u -p -r1.62 sparc.cc
--- gold/sparc.cc 5 Oct 2012 00:45:54 -0000 1.62
+++ gold/sparc.cc 17 Oct 2012 23:29:18 -0000
@@ -4138,7 +4138,7 @@ Target_sparc<size, big_endian>::relocate
gold_assert(sh_type == elfcpp::SHT_RELA);
gold::relocate_section<size, big_endian, Sparc, elfcpp::SHT_RELA,
- Sparc_relocate>(
+ Sparc_relocate, gold::Default_comdat_behavior>(
relinfo,
this,
prelocs,
Index: gold/tilegx.cc
===================================================================
RCS file: /cvs/src/src/gold/tilegx.cc,v
retrieving revision 1.3
diff -u -p -r1.3 tilegx.cc
--- gold/tilegx.cc 5 Oct 2012 00:45:54 -0000 1.3
+++ gold/tilegx.cc 17 Oct 2012 23:29:19 -0000
@@ -4733,8 +4733,8 @@ Target_tilegx<size, big_endian>::relocat
gold_assert(sh_type == elfcpp::SHT_RELA);
- gold::relocate_section<size, big_endian, Tilegx,
- elfcpp::SHT_RELA, Tilegx_relocate>(
+ gold::relocate_section<size, big_endian, Tilegx, elfcpp::SHT_RELA,
+ Tilegx_relocate, gold::Default_comdat_behavior>(
relinfo,
this,
prelocs,
Index: gold/x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.158
diff -u -p -r1.158 x86_64.cc
--- gold/x86_64.cc 5 Oct 2012 00:45:54 -0000 1.158
+++ gold/x86_64.cc 17 Oct 2012 23:29:19 -0000
@@ -4060,7 +4060,8 @@ Target_x86_64<size>::relocate_section(
gold_assert(sh_type == elfcpp::SHT_RELA);
gold::relocate_section<size, false, Target_x86_64<size>, elfcpp::SHT_RELA,
- typename Target_x86_64<size>::Relocate>(
+ typename Target_x86_64<size>::Relocate,
+ gold::Default_comdat_behavior>(
relinfo,
this,
prelocs,
--
Alan Modra
Australia Development Lab, IBM
More information about the Binutils
mailing list