From 2778747c56d0837ec7defb80e756a7e6ca81b8ce Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 15 Dec 2017 14:59:58 +1030 Subject: [PATCH] [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. --- gold/ChangeLog | 7 +++++++ gold/powerpc.cc | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index bc0413dfcaa..108631edc83 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2017-12-15 Alan Modra + + 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 * plugin.cc (Plugin::load): Include hooks for register_new_input diff --git a/gold/powerpc.cc b/gold/powerpc.cc index d52951984cd..91353418c50 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -3102,10 +3102,10 @@ Target_powerpc::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* gsym = static_cast*>(sym); if (gsym != NULL ? (gsym->use_plt_offset(Scan::get_reference_flags(this->r_type_, target)) @@ -3132,10 +3132,10 @@ Target_powerpc::Branch_info::make_stub( Target_powerpc* target = static_cast*>( parameters->sized_target()); - 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* gsym = static_cast*>(sym); bool ok = true; -- 2.30.2