summaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>2012-04-17 01:50:39 +0000
committerDavid S. Miller <davem@redhat.com>2012-04-17 01:50:39 +0000
commit13cf9988bc2852ba66d6096578a518c94bfccdcd (patch)
tree683c5e39327f7de26f38a4205562ed60446491b4 /gold/output.cc
parent31821be097c4154d3d7d201d9f4939a47af97ac6 (diff)
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.cc19
1 files changed, 14 insertions, 5 deletions
diff --git a/gold/output.cc b/gold/output.cc
index ca190392d1..2236916054 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