diff options
author | Alan Modra <amodra@gmail.com> | 2017-12-15 14:59:58 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-12-15 15:09:15 +1030 |
commit | 2778747c56d0837ec7defb80e756a7e6ca81b8ce (patch) | |
tree | 7ab40351ac51653621c4430ee1bfe7a5e4be3a8b /gold | |
parent | 828d584679845b6a1d01151f7df3592d15fe8405 (diff) | |
download | gdb-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')
-rw-r--r-- | gold/ChangeLog | 7 | ||||
-rw-r--r-- | 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; |