diff options
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 16 | ||||
-rw-r--r-- | gold/powerpc.cc | 23 | ||||
-rw-r--r-- | gold/resolve.cc | 4 | ||||
-rw-r--r-- | gold/symtab.cc | 1 | ||||
-rw-r--r-- | gold/symtab.h | 12 | ||||
-rw-r--r-- | gold/target.h | 2 |
6 files changed, 52 insertions, 6 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 813b27f..d612f1d 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,18 @@ +2017-08-28 Alan Modra <amodra@gmail.com> + + PR 21847 + * powerpc.cc (Target_powerpc::is_elfv2_localentry0): Test + non_zero_localentry. + (Target_powerpc::resolve): New function. + (powerpc_info): Set has_resolve for 64-bit. + * target.h (Sized_target::resolve): Return bool. + * resolve.cc (Symbol_table::resolve): Continue with normal + processing when target resolve returns false. + * symtab.h (Symbol::non_zero_localentry, set_non_zero_localentry): + New accessors. + (Symbol::non_zero_localentry_): New flag bit. + * symtab.cc (Symbol::init_fields): Init non_zero_localentry_. + 2017-08-08 Romain Geissler <romain.geissler@gmail.com> Alan Modra <amodra@gmail.com> @@ -39,6 +54,7 @@ 2017-07-31 Alan Modra <amodra@gmail.com> + PR 21847 * powerpc.cc (Target_powerpc::scan_relocs): Warn on --plt-localentry without ld.so checks. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 6f610cb..c29850b 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1026,7 +1026,8 @@ class Target_powerpc : public Sized_target<size, big_endian> && this->plt_localentry0() && gsym->type() == elfcpp::STT_FUNC && gsym->is_defined() - && gsym->nonvis() >> 3 == 0); + && gsym->nonvis() >> 3 == 0 + && !gsym->non_zero_localentry()); } bool @@ -1051,6 +1052,22 @@ class Target_powerpc : public Sized_target<size, big_endian> return false; } + // Remember any symbols seen with non-zero localentry, even those + // not providing a definition + bool + resolve(Symbol* to, const elfcpp::Sym<size, big_endian>& sym, Object*, + const char*) + { + if (size == 64) + { + unsigned char st_other = sym.get_st_other(); + if ((st_other & elfcpp::STO_PPC64_LOCAL_MASK) != 0) + to->set_non_zero_localentry(); + } + // We haven't resolved anything, continue normal processing. + return false; + } + int abiversion() const { return this->processor_specific_flags() & elfcpp::EF_PPC64_ABI; } @@ -1603,7 +1620,7 @@ Target::Target_info Target_powerpc<64, true>::powerpc_info = true, // is_big_endian elfcpp::EM_PPC64, // machine_code false, // has_make_symbol - false, // has_resolve + true, // has_resolve false, // has_code_fill true, // is_default_stack_executable false, // can_icf_inline_merge_sections @@ -1631,7 +1648,7 @@ Target::Target_info Target_powerpc<64, false>::powerpc_info = false, // is_big_endian elfcpp::EM_PPC64, // machine_code false, // has_make_symbol - false, // has_resolve + true, // has_resolve false, // has_code_fill true, // is_default_stack_executable false, // can_icf_inline_merge_sections diff --git a/gold/resolve.cc b/gold/resolve.cc index 8f4d2e3..7c22606 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -266,8 +266,8 @@ Symbol_table::resolve(Sized_symbol<size>* to, { Sized_target<size, big_endian>* sized_target; sized_target = parameters->sized_target<size, big_endian>(); - sized_target->resolve(to, sym, object, version); - return; + if (sized_target->resolve(to, sym, object, version)) + return; } if (!object->is_dynamic()) diff --git a/gold/symtab.cc b/gold/symtab.cc index 43909ff..7e0a3f8 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -81,6 +81,7 @@ Symbol::init_fields(const char* name, const char* version, this->undef_binding_weak_ = false; this->is_predefined_ = false; this->is_protected_ = false; + this->non_zero_localentry_ = false; } // Return the demangled version of the symbol's name, but only diff --git a/gold/symtab.h b/gold/symtab.h index 77552ae..c371731 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -883,6 +883,16 @@ class Symbol set_is_protected() { this->is_protected_ = true; } + // Return state of PowerPC64 ELFv2 specific flag. + bool + non_zero_localentry() const + { return this->non_zero_localentry_; } + + // Set PowerPC64 ELFv2 specific flag. + void + set_non_zero_localentry() + { this->non_zero_localentry_ = true; } + protected: // Instances of this class should always be created at a specific // size. @@ -1084,6 +1094,8 @@ class Symbol // The visibility_ field will be STV_DEFAULT in this case because we // must treat it as such from outside the shared object. bool is_protected_ : 1; + // Used by PowerPC64 ELFv2 to track st_other localentry (bit 36). + bool non_zero_localentry_ : 1; }; // The parts of a symbol which are size specific. Using a template diff --git a/gold/target.h b/gold/target.h index 5ca8435..cf6d902 100644 --- a/gold/target.h +++ b/gold/target.h @@ -852,7 +852,7 @@ class Sized_target : public Target // pre-existing symbol. SYM is the new symbol, seen in OBJECT. // VERSION is the version of SYM. This will only be called if // has_resolve() returns true. - virtual void + virtual bool resolve(Symbol*, const elfcpp::Sym<size, big_endian>&, Object*, const char*) { gold_unreachable(); } |