diff --git a/gold/ChangeLog b/gold/ChangeLog index b98b76a9c4..8ab8387588 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,16 @@ +2014-12-04 Alan Modra + + PR 17670 + * symtab.cc (Symbol::set_undefined): Remove assertion. + * powerpc.cc (Target_powerpc::symval_for_branch): Don't assert + on symbols defined in discarded sections, instead return false. + Rearrange params, update all callers. + (Target_powerpc::Branch_info::make_stub): Don't make stubs for + branches to syms in discarded sections. + (Global_symbol_visitor_opd::operator()): Set discarded opd syms + undefined and flag as discarded. + (Target_powerpc::Relocate::relocate): Localize variable. + 2014-12-03 H.J. Lu PR gold/17675 diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 5805c0bd76..0da355f2aa 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1035,11 +1035,11 @@ class Target_powerpc : public Sized_target bool issued_non_pic_error_; }; - Address - symval_for_branch(const Symbol_table* symtab, Address value, + bool + symval_for_branch(const Symbol_table* symtab, const Sized_symbol* gsym, Powerpc_relobj* object, - unsigned int *dest_shndx); + Address *value, unsigned int *dest_shndx); // The class which implements relocation. class Relocate : protected Track_tls @@ -2717,8 +2717,9 @@ Target_powerpc::Branch_info::make_stub( if (size == 64 && target->abiversion() < 2) { unsigned int dest_shndx; - to = target->symval_for_branch(symtab, to, gsym, - this->object_, &dest_shndx); + if (!target->symval_for_branch(symtab, gsym, this->object_, + &to, &dest_shndx)) + return true; } Address delta = to - from; if (delta + max_branch_offset >= 2 * max_branch_offset) @@ -6549,7 +6550,11 @@ class Global_symbol_visitor_opd unsigned int shndx = sym->shndx(&is_ordinary); if (shndx == symobj->opd_shndx() && symobj->get_opd_discard(sym->value())) - sym->set_symtab_index(-1U); + { + sym->set_undefined(); + sym->set_is_defined_in_discarded_section(); + sym->set_symtab_index(-1U); + } } }; @@ -6727,12 +6732,12 @@ ok_lo_toc_insn(uint32_t insn) // Return the value to use for a branch relocation. template -typename Target_powerpc::Address +bool Target_powerpc::symval_for_branch( const Symbol_table* symtab, - Address value, const Sized_symbol* gsym, Powerpc_relobj* object, + Address *value, unsigned int *dest_shndx) { if (size == 32 || this->abiversion() >= 2) @@ -6744,20 +6749,20 @@ Target_powerpc::symval_for_branch( Powerpc_relobj* symobj = object; if (gsym != NULL && gsym->source() != Symbol::FROM_OBJECT) - return value; + return true; if (gsym != NULL) symobj = static_cast*>(gsym->object()); unsigned int shndx = symobj->opd_shndx(); if (shndx == 0) - return value; + return true; Address opd_addr = symobj->get_output_section_offset(shndx); if (opd_addr == invalid_address) - return value; + return true; opd_addr += symobj->output_section_address(shndx); - if (value >= opd_addr && value < opd_addr + symobj->section_size(shndx)) + if (*value >= opd_addr && *value < opd_addr + symobj->section_size(shndx)) { Address sec_off; - *dest_shndx = symobj->get_opd_ent(value - opd_addr, &sec_off); + *dest_shndx = symobj->get_opd_ent(*value - opd_addr, &sec_off); if (symtab->is_section_folded(symobj, *dest_shndx)) { Section_id folded @@ -6766,11 +6771,13 @@ Target_powerpc::symval_for_branch( *dest_shndx = folded.second; } Address sec_addr = symobj->get_output_section_offset(*dest_shndx); - gold_assert(sec_addr != invalid_address); + if (sec_addr == invalid_address) + return false; + sec_addr += symobj->output_section(*dest_shndx)->address(); - value = sec_addr + sec_off; + *value = sec_addr + sec_off; } - return value; + return true; } // Perform a relocation. @@ -6930,10 +6937,9 @@ Target_powerpc::Relocate::relocate( if (target->abiversion() < 2) { Address addend = rela.get_r_addend(); - Address opdent = psymval->value(object, addend); - code = target->symval_for_branch(relinfo->symtab, - opdent, gsym, object, - &dest_shndx); + code = psymval->value(object, addend); + target->symval_for_branch(relinfo->symtab, gsym, object, + &code, &dest_shndx); } bool is_ordinary; if (dest_shndx == 0) @@ -7191,7 +7197,6 @@ Target_powerpc::Relocate::relocate( else if (!has_stub_value) { Address addend = 0; - unsigned int dest_shndx; if (r_type != elfcpp::R_PPC_PLTREL24) addend = rela.get_r_addend(); value = psymval->value(object, addend); @@ -7205,8 +7210,11 @@ Target_powerpc::Relocate::relocate( value += object->ppc64_local_entry_offset(r_sym); } else - value = target->symval_for_branch(relinfo->symtab, value, - gsym, object, &dest_shndx); + { + unsigned int dest_shndx; + target->symval_for_branch(relinfo->symtab, gsym, object, + &value, &dest_shndx); + } } unsigned long max_branch_offset = max_branch_delta(r_type); if (max_branch_offset != 0 diff --git a/gold/symtab.cc b/gold/symtab.cc index 70fb3f04f9..c4330186e5 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -547,7 +547,6 @@ Symbol::set_output_segment(Output_segment* os, Segment_offset_base base) void Symbol::set_undefined() { - gold_assert(this->is_predefined_); this->source_ = IS_UNDEFINED; this->is_predefined_ = false; }