From 19fec8c1d313c6757a53dc7f09776dc9770ee2ef Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 5 Oct 2012 00:45:54 +0000 Subject: [PATCH] * i386.cc (Output_data_plt_i386::address_for_global, address_for_local): Add plt offset to returned value. Adjust uses. * sparc.cc (Output_data_plt_sparc::address_for_global, address_for_local): Likewise. * tilegx.cc (Output_data_plt_tilegx::address_for_global, address_for_local): Likewise. * x86_64.cc (Output_data_plt_x86_64::address_for_global, address_for_local): Likewise. * target.h (Target::plt_address_for_global, plt_address_for_local): Update comment. * output.cc (Output_reloc::symbol_value): Don't add plt offset here. (Output_data_got::Got_entry::write): Nor here. * output.h: Comment fix. --- gold/ChangeLog | 16 ++++++++++++++++ gold/i386.cc | 17 +++++++++-------- gold/output.cc | 25 ++++++------------------- gold/output.h | 4 ++-- gold/sparc.cc | 15 ++++++++------- gold/target.h | 8 ++------ gold/tilegx.cc | 22 +++++++++++----------- gold/x86_64.cc | 17 +++++++++-------- 8 files changed, 63 insertions(+), 61 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 125d462728..7b3bc92528 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,19 @@ +2012-10-05 Alan Modra + + * i386.cc (Output_data_plt_i386::address_for_global, + address_for_local): Add plt offset to returned value. Adjust uses. + * sparc.cc (Output_data_plt_sparc::address_for_global, + address_for_local): Likewise. + * tilegx.cc (Output_data_plt_tilegx::address_for_global, + address_for_local): Likewise. + * x86_64.cc (Output_data_plt_x86_64::address_for_global, + address_for_local): Likewise. + * target.h (Target::plt_address_for_global, plt_address_for_local): + Update comment. + * output.cc (Output_reloc::symbol_value): Don't add plt offset here. + (Output_data_got::Got_entry::write): Nor here. + * output.h: Comment fix. + 2012-10-02 Jiong Wang * tilegx.cc (Target_tilegx::do_finalize_sections): Adjust diff --git a/gold/i386.cc b/gold/i386.cc index 47779d0e8c..9c52e93166 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -1151,16 +1151,19 @@ Output_data_plt_i386::address_for_global(const Symbol* gsym) if (gsym->type() == elfcpp::STT_GNU_IFUNC && gsym->can_use_relative_reloc(false)) offset = (this->count_ + 1) * this->get_plt_entry_size(); - return this->address() + offset; + return this->address() + offset + gsym->plt_offset(); } // Return the PLT address to use for a local symbol. These are always // IRELATIVE relocs. uint64_t -Output_data_plt_i386::address_for_local(const Relobj*, unsigned int) +Output_data_plt_i386::address_for_local(const Relobj* object, + unsigned int r_sym) { - return this->address() + (this->count_ + 1) * this->get_plt_entry_size(); + return (this->address() + + (this->count_ + 1) * this->get_plt_entry_size() + + object->local_plt_offset(r_sym)); } // The first entry in the PLT for an executable. @@ -2677,8 +2680,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, else if (gsym != NULL && gsym->use_plt_offset(Scan::get_reference_flags(r_type))) { - symval.set_output_value(target->plt_address_for_global(gsym) - + gsym->plt_offset()); + symval.set_output_value(target->plt_address_for_global(gsym)); psymval = &symval; } else if (gsym == NULL && psymval->is_ifunc_symbol()) @@ -2686,8 +2688,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); if (object->local_has_plt_offset(r_sym)) { - symval.set_output_value(target->plt_address_for_local(object, r_sym) - + object->local_plt_offset(r_sym)); + symval.set_output_value(target->plt_address_for_local(object, r_sym)); psymval = &symval; } } @@ -3649,7 +3650,7 @@ uint64_t Target_i386::do_dynsym_value(const Symbol* gsym) const { gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset()); - return this->plt_address_for_global(gsym) + gsym->plt_offset(); + return this->plt_address_for_global(gsym); } // Return a string used to fill a code section with nops to take up diff --git a/gold/output.cc b/gold/output.cc index 96fdd9fa81..6e5cd2510a 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1129,11 +1129,7 @@ Output_reloc::symbol_value( const Sized_symbol* sym; sym = static_cast*>(this->u1_.gsym); if (this->use_plt_offset_ && sym->has_plt_offset()) - { - uint64_t plt_address = - parameters->target().plt_address_for_global(sym); - return plt_address + sym->plt_offset(); - } + return parameters->target().plt_address_for_global(sym); else return sym->value() + addend; } @@ -1151,11 +1147,7 @@ Output_reloc::symbol_value( this->u1_.relobj->sized_relobj(); gold_assert(relobj != NULL); if (this->use_plt_offset_) - { - uint64_t plt_address = - parameters->target().plt_address_for_local(relobj, lsi); - return plt_address + relobj->local_plt_offset(lsi); - } + return parameters->target().plt_address_for_local(relobj, lsi); const Symbol_value* symval = relobj->local_symbol(lsi); return symval->value(relobj, addend); } @@ -1385,8 +1377,7 @@ Output_data_got::Got_entry::write( // RELATIVE relocation. Symbol* gsym = this->u_.gsym; if (this->use_plt_or_tls_offset_ && gsym->has_plt_offset()) - val = (parameters->target().plt_address_for_global(gsym) - + gsym->plt_offset()); + val = parameters->target().plt_address_for_global(gsym); else { switch (parameters->size_and_endianness()) @@ -1442,11 +1433,7 @@ Output_data_got::Got_entry::write( const unsigned int lsi = this->local_sym_index_; bool is_tls = object->local_is_tls(lsi); if (this->use_plt_or_tls_offset_ && !is_tls) - { - uint64_t plt_address = - parameters->target().plt_address_for_local(object, lsi); - val = plt_address + object->local_plt_offset(lsi); - } + val = parameters->target().plt_address_for_local(object, lsi); else { uint64_t lval = object->local_symbol_value(lsi, 0); @@ -2609,9 +2596,9 @@ Output_section::add_relaxed_input_section(Layout* layout, // For a relaxed section, we use the current data size. Linker scripts // get all the input sections, including relaxed one from an output - // section and add them back to them same output section to compute the + // section and add them back to the same output section to compute the // output section size. If we do not account for sizes of relaxed input - // sections, an output section would be incorrectly sized. + // sections, an output section would be incorrectly sized. off_t offset_in_section = this->current_data_size_for_child(); off_t aligned_offset_in_section = align_address(offset_in_section, poris->addralign()); diff --git a/gold/output.h b/gold/output.h index d5bcc27ddb..d52d0756bf 100644 --- a/gold/output.h +++ b/gold/output.h @@ -2247,7 +2247,7 @@ class Output_data_got : public Output_data_got_base add_global_plt(Symbol* gsym, unsigned int got_type); // Like add_global, but for a TLS symbol where the value will be - // offset using Target::tls_offset_for_global + // offset using Target::tls_offset_for_global. bool add_global_tls(Symbol* gsym, unsigned int got_type) { return add_global_plt(gsym, got_type); } @@ -2277,7 +2277,7 @@ class Output_data_got : public Output_data_got_base add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type); // Like add_local, but for a TLS symbol where the value will be - // offset using Target::tls_offset_for_local + // offset using Target::tls_offset_for_local. bool add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type) { return add_local_plt(object, sym_index, got_type); } diff --git a/gold/sparc.cc b/gold/sparc.cc index 71dd3d53c3..4ec3037c4a 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -1619,7 +1619,7 @@ Output_data_plt_sparc::address_for_global(const Symbol* gsym) if (gsym->type() == elfcpp::STT_GNU_IFUNC && gsym->can_use_relative_reloc(false)) offset = plt_index_to_offset(this->count_ + 4); - return this->address() + offset; + return this->address() + offset + gsym->plt_offset(); } // Return the PLT address to use for a local symbol. These are always @@ -1628,10 +1628,12 @@ Output_data_plt_sparc::address_for_global(const Symbol* gsym) template uint64_t Output_data_plt_sparc::address_for_local( - const Relobj*, - unsigned int) + const Relobj* object, + unsigned int r_sym) { - return this->address() + plt_index_to_offset(this->count_ + 4); + return (this->address() + + plt_index_to_offset(this->count_ + 4) + + object->local_plt_offset(r_sym)); } static const unsigned int sparc_nop = 0x01000000; @@ -3199,7 +3201,7 @@ Target_sparc::Relocate::relocate( { elfcpp::Elf_Xword value; - value = target->plt_address_for_global(gsym) + gsym->plt_offset(); + value = target->plt_address_for_global(gsym); symval.set_output_value(value); @@ -3210,8 +3212,7 @@ Target_sparc::Relocate::relocate( unsigned int r_sym = elfcpp::elf_r_sym(rela.get_r_info()); if (object->local_has_plt_offset(r_sym)) { - symval.set_output_value(target->plt_address_for_local(object, r_sym) - + object->local_plt_offset(r_sym)); + symval.set_output_value(target->plt_address_for_local(object, r_sym)); psymval = &symval; } } diff --git a/gold/target.h b/gold/target.h index 65c15fce02..3464a2ba45 100644 --- a/gold/target.h +++ b/gold/target.h @@ -256,16 +256,12 @@ class Target reloc_addend(void* arg, unsigned int type, uint64_t addend) const { return this->do_reloc_addend(arg, type, addend); } - // Return the PLT address to use for a global symbol. This is used - // for STT_GNU_IFUNC symbols. The symbol's plt_offset is relative - // to this PLT address. + // Return the PLT address to use for a global symbol. uint64_t plt_address_for_global(const Symbol* sym) const { return this->do_plt_address_for_global(sym); } - // Return the PLT address to use for a local symbol. This is used - // for STT_GNU_IFUNC symbols. The symbol's plt_offset is relative - // to this PLT address. + // Return the PLT address to use for a local symbol. uint64_t plt_address_for_local(const Relobj* object, unsigned int symndx) const { return this->do_plt_address_for_local(object, symndx); } diff --git a/gold/tilegx.cc b/gold/tilegx.cc index a209a97106..3c618028a6 100644 --- a/gold/tilegx.cc +++ b/gold/tilegx.cc @@ -2194,7 +2194,7 @@ Output_data_plt_tilegx::address_for_global( if (gsym->type() == elfcpp::STT_GNU_IFUNC && gsym->can_use_relative_reloc(false)) offset = (this->count_ + 1) * this->get_plt_entry_size(); - return this->address() + offset; + return this->address() + offset + gsym->plt_offset(); } // Return the PLT address to use for a local symbol. These are always @@ -2202,10 +2202,13 @@ Output_data_plt_tilegx::address_for_global( template uint64_t -Output_data_plt_tilegx::address_for_local(const Relobj*, - unsigned int) +Output_data_plt_tilegx::address_for_local( + const Relobj* object, + unsigned int r_sym) { - return this->address() + (this->count_ + 1) * this->get_plt_entry_size(); + return (this->address() + + (this->count_ + 1) * this->get_plt_entry_size() + + object->local_plt_offset(r_sym)); } // Set the final size. @@ -4334,8 +4337,7 @@ Target_tilegx::Relocate::relocate( if (gsym != NULL && gsym->use_plt_offset(Scan::get_reference_flags(r_type))) { - symval.set_output_value(target->plt_address_for_global(gsym) - + gsym->plt_offset()); + symval.set_output_value(target->plt_address_for_global(gsym)); psymval = &symval; } else if (gsym == NULL && psymval->is_ifunc_symbol()) @@ -4343,8 +4345,7 @@ Target_tilegx::Relocate::relocate( unsigned int r_sym = elfcpp::elf_r_sym(rela.get_r_info()); if (object->local_has_plt_offset(r_sym)) { - symval.set_output_value(target->plt_address_for_local(object, r_sym) - + object->local_plt_offset(r_sym)); + symval.set_output_value(target->plt_address_for_local(object, r_sym)); psymval = &symval; } } @@ -4557,8 +4558,7 @@ Target_tilegx::Relocate::relocate( if (opt_t == tls::TLSOPT_NONE) { Symbol *tls_sym = relinfo->symtab->lookup("__tls_get_addr"); symval.set_output_value( - target->plt_address_for_global(tls_sym) - + tls_sym->plt_offset()); + target->plt_address_for_global(tls_sym)); psymval = &symval; TilegxReloc::imm_x_pcrel_general(view, object, psymval, addend, address, r_howto); @@ -4870,7 +4870,7 @@ uint64_t Target_tilegx::do_dynsym_value(const Symbol* gsym) const { gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset()); - return this->plt_address_for_global(gsym) + gsym->plt_offset(); + return this->plt_address_for_global(gsym); } // Return the value to use for the base of a DW_EH_PE_datarel offset diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 5914160b2a..0fbfec62db 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -1385,7 +1385,7 @@ Output_data_plt_x86_64::address_for_global(const Symbol* gsym) if (gsym->type() == elfcpp::STT_GNU_IFUNC && gsym->can_use_relative_reloc(false)) offset = (this->count_ + 1) * this->get_plt_entry_size(); - return this->address() + offset; + return this->address() + offset + gsym->plt_offset(); } // Return the PLT address to use for a local symbol. These are always @@ -1393,9 +1393,12 @@ Output_data_plt_x86_64::address_for_global(const Symbol* gsym) template uint64_t -Output_data_plt_x86_64::address_for_local(const Relobj*, unsigned int) +Output_data_plt_x86_64::address_for_local(const Relobj* object, + unsigned int r_sym) { - return this->address() + (this->count_ + 1) * this->get_plt_entry_size(); + return (this->address() + + (this->count_ + 1) * this->get_plt_entry_size() + + object->local_plt_offset(r_sym)); } // Set the final size. @@ -3234,8 +3237,7 @@ Target_x86_64::Relocate::relocate( if (gsym != NULL && gsym->use_plt_offset(Scan::get_reference_flags(r_type))) { - symval.set_output_value(target->plt_address_for_global(gsym) - + gsym->plt_offset()); + symval.set_output_value(target->plt_address_for_global(gsym)); psymval = &symval; } else if (gsym == NULL && psymval->is_ifunc_symbol()) @@ -3243,8 +3245,7 @@ Target_x86_64::Relocate::relocate( unsigned int r_sym = elfcpp::elf_r_sym(rela.get_r_info()); if (object->local_has_plt_offset(r_sym)) { - symval.set_output_value(target->plt_address_for_local(object, r_sym) - + object->local_plt_offset(r_sym)); + symval.set_output_value(target->plt_address_for_local(object, r_sym)); psymval = &symval; } } @@ -4253,7 +4254,7 @@ uint64_t Target_x86_64::do_dynsym_value(const Symbol* gsym) const { gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset()); - return this->plt_address_for_global(gsym) + gsym->plt_offset(); + return this->plt_address_for_global(gsym); } // Return a string used to fill a code section with nops to take up