diff options
author | David S. Miller <davem@redhat.com> | 2012-04-17 01:50:39 +0000 |
---|---|---|
committer | David S. Miller <davem@redhat.com> | 2012-04-17 01:50:39 +0000 |
commit | 13cf9988bc2852ba66d6096578a518c94bfccdcd (patch) | |
tree | 683c5e39327f7de26f38a4205562ed60446491b4 /gold/output.cc | |
parent | 31821be097c4154d3d7d201d9f4939a47af97ac6 (diff) | |
download | fsf-binutils-gdb-13cf9988bc2852ba66d6096578a518c94bfccdcd.zip fsf-binutils-gdb-13cf9988bc2852ba66d6096578a518c94bfccdcd.tar.gz fsf-binutils-gdb-13cf9988bc2852ba66d6096578a518c94bfccdcd.tar.bz2 |
gold: Allow use_plt_offset to be specified for global relocations.
gold/
* output.h (Output_reloc): Allow use_plt_offset for global relocs too.
(class Output_data_reloc): Adjust calls to Output_reloc_type.
(Output_data_reloc::add_global_relative): (RELA only) Add use_plt_offset.
* output.cc (Output_reloc::Output_reloc): Add use_plt_offset flag for
global relocs too.
(Output_reloc::symbol_value): Respect use_plt_offset_ for global symbols.
* powerpc.cc (Target_powerpc::Scan::global): Adjust add_global_relative
calls.
* sparc.cc (Target_sparc::Scan::global): Likewise.
* x86_64.cc (Target_x86_64::Scan::global): Likewise.
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/gold/output.cc b/gold/output.cc index ca19039..2236916 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -705,10 +705,11 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc( Output_data* od, Address address, bool is_relative, - bool is_symbolless) + bool is_symbolless, + bool use_plt_offset) : address_(address), local_sym_index_(GSYM_CODE), type_(type), is_relative_(is_relative), is_symbolless_(is_symbolless), - is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) + is_section_symbol_(false), use_plt_offset_(use_plt_offset), shndx_(INVALID_CODE) { // this->type_ is a bitfield; make sure TYPE fits. gold_assert(this->type_ == type); @@ -726,10 +727,11 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc( unsigned int shndx, Address address, bool is_relative, - bool is_symbolless) + bool is_symbolless, + bool use_plt_offset) : address_(address), local_sym_index_(GSYM_CODE), type_(type), is_relative_(is_relative), is_symbolless_(is_symbolless), - is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) + is_section_symbol_(false), use_plt_offset_(use_plt_offset), shndx_(shndx) { gold_assert(shndx != INVALID_CODE); // this->type_ is a bitfield; make sure TYPE fits. @@ -1116,7 +1118,14 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value( { const Sized_symbol<size>* sym; sym = static_cast<const Sized_symbol<size>*>(this->u1_.gsym); - return sym->value() + addend; + 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(); + } + else + return sym->value() + addend; } gold_assert(this->local_sym_index_ != SECTION_CODE && this->local_sym_index_ != TARGET_CODE |