aboutsummaryrefslogtreecommitdiff
path: root/gold/powerpc.cc
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-12-15 14:59:58 +1030
committerAlan Modra <amodra@gmail.com>2017-12-15 15:09:15 +1030
commit2778747c56d0837ec7defb80e756a7e6ca81b8ce (patch)
tree7ab40351ac51653621c4430ee1bfe7a5e4be3a8b /gold/powerpc.cc
parent828d584679845b6a1d01151f7df3592d15fe8405 (diff)
downloadgdb-2778747c56d0837ec7defb80e756a7e6ca81b8ce.zip
gdb-2778747c56d0837ec7defb80e756a7e6ca81b8ce.tar.gz
gdb-2778747c56d0837ec7defb80e756a7e6ca81b8ce.tar.bz2
[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.
Diffstat (limited to 'gold/powerpc.cc')
-rw-r--r--gold/powerpc.cc8
1 files changed, 4 insertions, 4 deletions
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;