[binutils-gdb] [GOLD] PR22602, handle __tls_get_addr forwarders properly

Alan Modra amodra@sourceware.org
Fri Dec 15 07:05:00 GMT 2017


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2778747c56d0837ec7defb80e756a7e6ca81b8ce

commit 2778747c56d0837ec7defb80e756a7e6ca81b8ce
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Dec 15 14:59:58 2017 +1030

    [GOLD] PR22602, handle __tls_get_addr forwarders properly
    
    We never need to resolve_forwards() a symbol found by hash table lookup
    such as target->tls_get_addr_opt() but we do potentially need to do so
    for random symbols seen on relocs.  So these calls were in the wrong
    order, resulting in missing stubs and an assertion failure.
    
    	PR 22602
    	* powerpc.cc (Target_powerpc::Branch_info::mark_pltcall): Resolve
    	forwards before replacing __tls_get_addr.
    	(Target_powerpc::Branch_info::make_stub): Likewise.

Diff:
---
 gold/ChangeLog  | 7 +++++++
 gold/powerpc.cc | 8 ++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index bc0413d..108631e 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,10 @@
+2017-12-15  Alan Modra  <amodra@gmail.com>
+
+	PR 22602
+	* powerpc.cc (Target_powerpc::Branch_info::mark_pltcall): Resolve
+	forwards before replacing __tls_get_addr.
+	(Target_powerpc::Branch_info::make_stub): Likewise.
+
 2017-12-11  Stephen Crane  <sjc@immunant.com>
 
 	* plugin.cc (Plugin::load): Include hooks for register_new_input
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index d529519..9135341 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -3102,10 +3102,10 @@ Target_powerpc<size, big_endian>::Branch_info::mark_pltcall(
     return false;
 
   Symbol* sym = this->object_->global_symbol(this->r_sym_);
-  if (target->replace_tls_get_addr(sym))
-    sym = target->tls_get_addr_opt();
   if (sym != NULL && sym->is_forwarder())
     sym = symtab->resolve_forwards(sym);
+  if (target->replace_tls_get_addr(sym))
+    sym = target->tls_get_addr_opt();
   const Sized_symbol<size>* gsym = static_cast<const Sized_symbol<size>*>(sym);
   if (gsym != NULL
       ? (gsym->use_plt_offset(Scan::get_reference_flags(this->r_type_, target))
@@ -3132,10 +3132,10 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
   Target_powerpc<size, big_endian>* target =
     static_cast<Target_powerpc<size, big_endian>*>(
       parameters->sized_target<size, big_endian>());
-  if (target->replace_tls_get_addr(sym))
-    sym = target->tls_get_addr_opt();
   if (sym != NULL && sym->is_forwarder())
     sym = symtab->resolve_forwards(sym);
+  if (target->replace_tls_get_addr(sym))
+    sym = target->tls_get_addr_opt();
   const Sized_symbol<size>* gsym = static_cast<const Sized_symbol<size>*>(sym);
   bool ok = true;



More information about the Binutils-cvs mailing list