diff options
-rw-r--r-- | gold/ChangeLog | 10 | ||||
-rw-r--r-- | gold/powerpc.cc | 42 |
2 files changed, 35 insertions, 17 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 3f03b6b..ff9fa2a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,15 @@ 2015-04-28 Alan Modra <amodra@gmail.com> + * powerpc.cc (Target_powerpc::do_dynsym_value): Use Address rather + than unsigned int for find_global_entry result temp. Compare + against invalid_address. + (Target_powerpc::do_plt_address_for_global): Likewise. + (Target_powerpc::Relocate::relocate): Likewise. Don't assert + on plt call stub existence for debug info. Do assert for plt + and global entry stub existence if an alloc section. + +2015-04-28 Alan Modra <amodra@gmail.com> + * powerpc.cc (Target_powerpc::Relocate::relocate): Don't assert on missing global entry stub due to bogus debug info. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 3d753b5..9a0bd9d 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -6835,8 +6835,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate( && !parameters->options().output_is_position_independent() && !is_branch_reloc(r_type)) { - unsigned int off = target->glink_section()->find_global_entry(gsym); - if (off != (unsigned int)-1) + Address off = target->glink_section()->find_global_entry(gsym); + if (off != invalid_address) { value = target->glink_section()->global_entry_address() + off; has_stub_value = true; @@ -6852,18 +6852,26 @@ Target_powerpc<size, big_endian>::Relocate::relocate( if (target->stub_tables().size() != 0) stub_table = target->stub_tables()[0]; } - gold_assert(stub_table != NULL); - Address off; - if (gsym != NULL) - off = stub_table->find_plt_call_entry(object, gsym, r_type, - rela.get_r_addend()); - else - off = stub_table->find_plt_call_entry(object, r_sym, r_type, - rela.get_r_addend()); - gold_assert(off != invalid_address); - value = stub_table->stub_address() + off; - has_stub_value = true; + if (stub_table != NULL) + { + Address off; + if (gsym != NULL) + off = stub_table->find_plt_call_entry(object, gsym, r_type, + rela.get_r_addend()); + else + off = stub_table->find_plt_call_entry(object, r_sym, r_type, + rela.get_r_addend()); + if (off != invalid_address) + { + value = stub_table->stub_address() + off; + has_stub_value = true; + } + } } + // We don't care too much about bogus debug references to + // non-local functions, but otherwise there had better be a plt + // call stub or global entry stub as appropriate. + gold_assert(has_stub_value || !(os->flags() & elfcpp::SHF_ALLOC)); } if (r_type == elfcpp::R_POWERPC_GOT16 @@ -8232,8 +8240,8 @@ Target_powerpc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const } else if (this->abiversion() >= 2) { - unsigned int off = this->glink_section()->find_global_entry(gsym); - if (off != (unsigned int)-1) + Address off = this->glink_section()->find_global_entry(gsym); + if (off != invalid_address) return this->glink_section()->global_entry_address() + off; } gold_unreachable(); @@ -8282,8 +8290,8 @@ Target_powerpc<size, big_endian>::do_plt_address_for_global( } else if (this->abiversion() >= 2) { - unsigned int off = this->glink_section()->find_global_entry(gsym); - if (off != (unsigned int)-1) + Address off = this->glink_section()->find_global_entry(gsym); + if (off != invalid_address) return this->glink_section()->global_entry_address() + off; } gold_unreachable(); |