[GOLD] override get_comdat_behavior
Alan Modra
amodra@gmail.com
Wed Oct 17 15:03:00 GMT 2012
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.
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 11:59:14 -0000
@@ -348,7 +348,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.get_comdat_behavior(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 11:59:13 -0000
@@ -2632,6 +2632,12 @@ class Target_arm : public Sized_target<3
bool is_32bit,
Output_section* output_section);
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ Comdat_behavior
+ get_comdat_behavior(const char* name)
+ { return gold::get_comdat_behavior(name); }
+
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
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 11:59:13 -0000
@@ -609,6 +609,12 @@ class Target_i386 : public Sized_target<
bool is_32bit,
Output_section* output_section);
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ Comdat_behavior
+ get_comdat_behavior(const char* name)
+ { return gold::get_comdat_behavior(name); }
+
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.64
diff -u -p -r1.64 powerpc.cc
--- gold/powerpc.cc 16 Oct 2012 00:23:00 -0000 1.64
+++ gold/powerpc.cc 17 Oct 2012 11:59:14 -0000
@@ -602,6 +602,27 @@ class Target_powerpc : public Sized_targ
}
}
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ Comdat_behavior
+ get_comdat_behavior(const char* name)
+ {
+ Comdat_behavior ret = gold::get_comdat_behavior(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;
+ }
+
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
@@ -5005,43 +5075,6 @@ Target_powerpc<size, big_endian>::reloca
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>(
relinfo,
@@ -5054,9 +5087,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 11:59:14 -0000
@@ -312,6 +312,12 @@ class Target_sparc : public Sized_target
}
}
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ Comdat_behavior
+ get_comdat_behavior(const char* name)
+ { return gold::get_comdat_behavior(name); }
+
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
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 11:59:14 -0000
@@ -514,6 +514,12 @@ class Target_tilegx : public Sized_targe
{
}
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ Comdat_behavior
+ get_comdat_behavior(const char* name)
+ { return gold::get_comdat_behavior(name); }
+
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
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 11:59:14 -0000
@@ -747,6 +747,12 @@ class Target_x86_64 : public Sized_targe
}
}
+ // Decide what the linker should do for relocations that refer to
+ // discarded comdat sections.
+ Comdat_behavior
+ get_comdat_behavior(const char* name)
+ { return gold::get_comdat_behavior(name); }
+
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
--
Alan Modra
Australia Development Lab, IBM
More information about the Binutils
mailing list