diff options
author | Alan Modra <amodra@gmail.com> | 2012-10-18 04:18:18 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-10-18 04:18:18 +0000 |
commit | 168a472611f2e89e2acebf2b44569a00a34e966d (patch) | |
tree | 474ac04b3f001f552592bd8b081522bb17e06938 /gold/powerpc.cc | |
parent | 522307fe68d5bfe54b1211dde54873be239e8925 (diff) | |
download | ppe42-binutils-168a472611f2e89e2acebf2b44569a00a34e966d.tar.gz ppe42-binutils-168a472611f2e89e2acebf2b44569a00a34e966d.zip |
* 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.
Diffstat (limited to 'gold/powerpc.cc')
-rw-r--r-- | gold/powerpc.cc | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 69386020ec..5e4006ce72 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -619,6 +619,32 @@ class Target_powerpc : public Sized_target<size, big_endian> 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>::relocate_section( { 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>::relocate_section( address, view_size, reloc_symbol_changes); - - if (opd_rel != NULL) - delete[] opd_rel; } class Powerpc_scan_relocatable_reloc |