From 95a2c8d6f73bc3c7ac6641b2cbe9a7d7deefada8 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 11 Nov 2010 10:43:30 +0000 Subject: gold/ * symtab.h (Symbol::NON_PIC_REF): Remove. (Symbol::RELATIVE_REF, Symbol::TLS_REF): New Reference_flags. (Symbol::FUNCTION_CALL): Renumber. Reword comment. (Symbol::needs_dynamic_reloc): Don't check NON_PIC_REF. (Symbol::use_plt_offset): Take a flags argument and pass it directly to needs_dynamic_reloc. Restrict check for undefined weak symbols to function calls. * arm.cc (Target_arm::Scan::get_reference_flags): New function. (Target_arm::Scan::global): Use it. (Target_arm::Scan::scan_reloc_for_stub): Likewise. (Target_arm::Relocate::relocate): Likewise. (Target_arm::Relocate::should_apply_static_reloc): Replace flags parameter with an r_type parameter. Use get_reference_flags to get the flags. (Target_arm::Relocate::relocate): Update accordingly. * i386.cc (Target_i386::Scan::get_reference_flags): New function. (Target_i386::Scan::reloc_needs_plt_for_ifunc): Use it. (Target_i386::Scan::global): Likewise. (Target_i386::Relocate::relocate): Likewise. (Target_i386::Relocate::should_apply_static_reloc): Replace flags parameter with an r_type parameter. Use get_reference_flags to get the flags. (Target_i386::Relocate::relocate): Update accordingly. * powerpc.cc (Target_powerpc::Scan::get_reference_flags): New function. (Target_powerpc::Scan::global): Use it. (Target_powerpc::Scan::scan_reloc_for_stub): Likewise. (Target_powerpc::Relocate::relocate): Likewise. * sparc.cc (Target_sparc::Scan::get_reference_flags): New function. (Target_sparc::Scan::global): Use it. (Target_sparc::Scan::scan_reloc_for_stub): Likewise. (Target_sparc::Relocate::relocate): Likewise. * x86_64.cc (Target_x86_64::Scan::get_reference_flags): New function. (Target_x86_64::Scan::reloc_needs_plt_for_ifunc): Use it. (Target_x86_64::Scan::global): Likewise. (Target_x86_64::Relocate::relocate): Likewise. --- gold/powerpc.cc | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 11 deletions(-) (limited to 'gold/powerpc.cc') diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 49af65f..661477a 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -188,6 +188,9 @@ class Target_powerpc : public Sized_target : issued_non_pic_error_(false) { } + static inline int + get_reference_flags(unsigned int r_type); + inline void local(Symbol_table* symtab, Layout* layout, Target_powerpc* target, Sized_relobj* object, @@ -1105,6 +1108,69 @@ optimize_tls_reloc(bool /* is_final */, int r_type) } } +// Get the Reference_flags for a particular relocation. + +template +int +Target_powerpc::Scan::get_reference_flags( + unsigned int r_type) +{ + switch (r_type) + { + case elfcpp::R_POWERPC_NONE: + case elfcpp::R_POWERPC_GNU_VTINHERIT: + case elfcpp::R_POWERPC_GNU_VTENTRY: + case elfcpp::R_PPC64_TOC: + // No symbol reference. + return 0; + + case elfcpp::R_POWERPC_ADDR16: + case elfcpp::R_POWERPC_ADDR16_LO: + case elfcpp::R_POWERPC_ADDR16_HI: + case elfcpp::R_POWERPC_ADDR16_HA: + case elfcpp::R_POWERPC_ADDR32: + case elfcpp::R_PPC64_ADDR64: + return Symbol::ABSOLUTE_REF; + + case elfcpp::R_POWERPC_REL24: + case elfcpp::R_PPC_LOCAL24PC: + case elfcpp::R_PPC_REL16: + case elfcpp::R_PPC_REL16_LO: + case elfcpp::R_PPC_REL16_HI: + case elfcpp::R_PPC_REL16_HA: + return Symbol::RELATIVE_REF; + + case elfcpp::R_PPC_PLTREL24: + return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF; + + case elfcpp::R_POWERPC_GOT16: + case elfcpp::R_POWERPC_GOT16_LO: + case elfcpp::R_POWERPC_GOT16_HI: + case elfcpp::R_POWERPC_GOT16_HA: + case elfcpp::R_PPC64_TOC16: + case elfcpp::R_PPC64_TOC16_LO: + case elfcpp::R_PPC64_TOC16_HI: + case elfcpp::R_PPC64_TOC16_HA: + case elfcpp::R_PPC64_TOC16_DS: + case elfcpp::R_PPC64_TOC16_LO_DS: + // Absolute in GOT. + return Symbol::ABSOLUTE_REF; + + case elfcpp::R_POWERPC_GOT_TPREL16: + case elfcpp::R_POWERPC_TLS: + return Symbol::TLS_REF; + + case elfcpp::R_POWERPC_COPY: + case elfcpp::R_POWERPC_GLOB_DAT: + case elfcpp::R_POWERPC_JMP_SLOT: + case elfcpp::R_POWERPC_RELATIVE: + case elfcpp::R_POWERPC_DTPMOD: + default: + // Not expected. We will give an error later. + return 0; + } +} + // Report an unsupported relocation against a local symbol. template @@ -1400,7 +1466,7 @@ Target_powerpc::Scan::global( gsym->set_needs_dynsym_value(); } // Make a dynamic relocation if necessary. - if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF)) + if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { if (gsym->may_need_copy_reloc()) { @@ -1450,10 +1516,7 @@ Target_powerpc::Scan::global( if (gsym->needs_plt_entry()) target->make_plt_entry(symtab, layout, gsym); // Make a dynamic relocation if necessary. - int flags = Symbol::NON_PIC_REF; - if (gsym->type() == elfcpp::STT_FUNC) - flags |= Symbol::FUNCTION_CALL; - if (gsym->needs_dynamic_reloc(flags)) + if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { if (gsym->may_need_copy_reloc()) { @@ -1682,12 +1745,7 @@ Target_powerpc::Relocate::relocate( // Pick the value to use for symbols defined in shared objects. Symbol_value symval; if (gsym != NULL - && gsym->use_plt_offset(r_type == elfcpp::R_POWERPC_REL24 - || r_type == elfcpp::R_PPC_LOCAL24PC - || r_type == elfcpp::R_PPC_REL16 - || r_type == elfcpp::R_PPC_REL16_LO - || r_type == elfcpp::R_PPC_REL16_HI - || r_type == elfcpp::R_PPC_REL16_HA)) + && gsym->use_plt_offset(Scan::get_reference_flags(r_type))) { elfcpp::Elf_Xword value; -- cgit v1.1