From 565ed01a4e0e3584f24580177822a5271b1c0c8b Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 28 Aug 2017 16:27:33 +0930 Subject: [PATCH] [GOLD] Symbol flag for PowerPC64 localentry:0 tracking This patch provides a flag for PowerPC64 ELFv2 use in class Symbol, and modifies Sized_target::resolve to return whether the symbol has been resolved. If not, normal processing continues. I use this for PowerPC64 ELFv2 to keep track of whether a symbol has any definition with non-zero localentry, in order to disable --plt-localentry for that symbol. 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_. --- gold/ChangeLog | 16 ++++++++++++++++ gold/powerpc.cc | 23 ++++++++++++++++++++--- gold/resolve.cc | 4 ++-- gold/symtab.cc | 1 + gold/symtab.h | 12 ++++++++++++ gold/target.h | 2 +- 6 files changed, 52 insertions(+), 6 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 813b27f716..d612f1db63 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,18 @@ +2017-08-28 Alan Modra + + 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 Alan Modra @@ -39,6 +54,7 @@ 2017-07-31 Alan Modra + 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 6f610cbe8c..c29850b617 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1026,7 +1026,8 @@ class Target_powerpc : public Sized_target && 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 return false; } + // Remember any symbols seen with non-zero localentry, even those + // not providing a definition + bool + resolve(Symbol* to, const elfcpp::Sym& 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 8f4d2e3330..7c22606800 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -266,8 +266,8 @@ Symbol_table::resolve(Sized_symbol* to, { Sized_target* sized_target; sized_target = parameters->sized_target(); - 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 43909ffeb8..7e0a3f80d2 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 77552ae7ca..c371731b5e 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 5ca8435c5b..cf6d902310 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&, Object*, const char*) { gold_unreachable(); } -- 2.34.1