From 168a472611f2e89e2acebf2b44569a00a34e966d Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 18 Oct 2012 04:18:18 +0000 Subject: * 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. --- gold/powerpc.cc | 70 ++++++++++++++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 41 deletions(-) (limited to 'gold/powerpc.cc') diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 6938602..5e4006c 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -619,6 +619,32 @@ class Target_powerpc : public Sized_target 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::relocate_section( { typedef Target_powerpc Powerpc; typedef typename Target_powerpc::Relocate Powerpc_relocate; + typedef typename Target_powerpc::Relocate_comdat_behavior + Powerpc_comdat_behavior; gold_assert(sh_type == elfcpp::SHT_RELA); - unsigned char *opd_rel = NULL; - Powerpc_relobj* const object - = static_cast*>(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::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::Reloc - reloc(rrel); - typename elfcpp::Elf_types::Elf_WXword r_info - = reloc.get_r_info(); - unsigned int r_type = elfcpp::elf_r_type(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( + Powerpc_relocate, Powerpc_comdat_behavior>( relinfo, this, prelocs, @@ -5103,9 +5094,6 @@ Target_powerpc::relocate_section( address, view_size, reloc_symbol_changes); - - if (opd_rel != NULL) - delete[] opd_rel; } class Powerpc_scan_relocatable_reloc -- cgit v1.1