[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.
This commit is contained in:
Alan Modra 2017-12-15 14:59:58 +10:30
parent 828d584679
commit 2778747c56
2 changed files with 11 additions and 4 deletions

View File

@ -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

View File

@ -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;