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.
This commit is contained in:
parent
31821be097
commit
13cf9988bc
@ -1,3 +1,16 @@
|
||||
2012-04-16 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* 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.
|
||||
|
||||
2012-04-16 Cary Coutant <ccoutant@google.com>
|
||||
|
||||
* archive.cc (Library_base::should_include_member): Check for
|
||||
|
@ -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
|
||||
|
@ -1021,12 +1021,13 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
// A reloc against a global symbol.
|
||||
|
||||
Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Address address, bool is_relative, bool is_symbolless);
|
||||
Address address, bool is_relative, bool is_symbolless,
|
||||
bool use_plt_offset);
|
||||
|
||||
Output_reloc(Symbol* gsym, unsigned int type,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address, bool is_relative,
|
||||
bool is_symbolless);
|
||||
bool is_symbolless, bool use_plt_offset);
|
||||
|
||||
// A reloc against a local symbol or local section symbol.
|
||||
|
||||
@ -1226,8 +1227,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
bool is_symbolless_ : 1;
|
||||
// True if the relocation is against a section symbol.
|
||||
bool is_section_symbol_ : 1;
|
||||
// True if the addend should be the PLT offset. This is used only
|
||||
// for RELATIVE relocations to local symbols.
|
||||
// True if the addend should be the PLT offset.
|
||||
// (Used only for RELA, but stored here for space.)
|
||||
bool use_plt_offset_ : 1;
|
||||
// If the reloc address is an input section in an object, the
|
||||
@ -1255,17 +1255,18 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
|
||||
Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Address address, Addend addend, bool is_relative,
|
||||
bool is_symbolless)
|
||||
: rel_(gsym, type, od, address, is_relative, is_symbolless),
|
||||
bool is_symbolless, bool use_plt_offset)
|
||||
: rel_(gsym, type, od, address, is_relative, is_symbolless,
|
||||
use_plt_offset),
|
||||
addend_(addend)
|
||||
{ }
|
||||
|
||||
Output_reloc(Symbol* gsym, unsigned int type,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address, Addend addend,
|
||||
bool is_relative, bool is_symbolless)
|
||||
bool is_relative, bool is_symbolless, bool use_plt_offset)
|
||||
: rel_(gsym, type, relobj, shndx, address, is_relative,
|
||||
is_symbolless), addend_(addend)
|
||||
is_symbolless, use_plt_offset), addend_(addend)
|
||||
{ }
|
||||
|
||||
// A reloc against a local symbol.
|
||||
@ -1558,14 +1559,14 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, false, false)); }
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, false, false, false)); }
|
||||
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
false, false)); }
|
||||
false, false, false)); }
|
||||
|
||||
void
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
@ -1574,7 +1575,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
gold_assert(addend == 0);
|
||||
this->add(od, Output_reloc_type(gsym, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
false, false));
|
||||
false, false, false));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1587,7 +1588,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
false, false));
|
||||
false, false, false));
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a global symbol. The final relocation
|
||||
@ -1596,7 +1597,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
void
|
||||
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Address address)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, true, true)); }
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, true, true,
|
||||
false)); }
|
||||
|
||||
void
|
||||
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
@ -1604,7 +1606,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
unsigned int shndx, Address address)
|
||||
{
|
||||
this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
true, true));
|
||||
true, true, false));
|
||||
}
|
||||
|
||||
// Add a global relocation which does not use a symbol for the relocation,
|
||||
@ -1613,7 +1615,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
void
|
||||
add_symbolless_global_addend(Symbol* gsym, unsigned int type,
|
||||
Output_data* od, Address address)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, false, true)); }
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, false, true,
|
||||
false)); }
|
||||
|
||||
void
|
||||
add_symbolless_global_addend(Symbol* gsym, unsigned int type,
|
||||
@ -1622,7 +1625,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
unsigned int shndx, Address address)
|
||||
{
|
||||
this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
false, true));
|
||||
false, true, false));
|
||||
}
|
||||
|
||||
// Add a reloc against a local symbol.
|
||||
@ -1825,7 +1828,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Address address, Addend addend)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, addend,
|
||||
false, false)); }
|
||||
false, false, false)); }
|
||||
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
@ -1833,7 +1836,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
unsigned int shndx, Address address,
|
||||
Addend addend)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
addend, false, false)); }
|
||||
addend, false, false, false)); }
|
||||
|
||||
void
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
@ -1842,7 +1845,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
this->add(od, Output_reloc_type(gsym, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend),
|
||||
false, false));
|
||||
false, false, false));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1855,7 +1858,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend),
|
||||
false, false));
|
||||
false, false, false));
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a global symbol. The final output
|
||||
@ -1865,16 +1868,17 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
|
||||
void
|
||||
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Address address, Addend addend)
|
||||
Address address, Addend addend, bool use_plt_offset)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, addend, true,
|
||||
true)); }
|
||||
true, use_plt_offset)); }
|
||||
|
||||
void
|
||||
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address, Addend addend)
|
||||
unsigned int shndx, Address address, Addend addend,
|
||||
bool use_plt_offset)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
addend, true, true)); }
|
||||
addend, true, true, use_plt_offset)); }
|
||||
|
||||
// Add a global relocation which does not use a symbol for the relocation,
|
||||
// but which gets its addend from a symbol.
|
||||
@ -1883,7 +1887,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
add_symbolless_global_addend(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Address address, Addend addend)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, addend,
|
||||
false, true)); }
|
||||
false, true, false)); }
|
||||
|
||||
void
|
||||
add_symbolless_global_addend(Symbol* gsym, unsigned int type,
|
||||
@ -1891,7 +1895,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address, Addend addend)
|
||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
addend, false, true)); }
|
||||
addend, false, true, false)); }
|
||||
|
||||
// Add a reloc against a local symbol.
|
||||
|
||||
|
@ -1486,7 +1486,7 @@ Target_powerpc<size, big_endian>::Scan::global(
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_POWERPC_RELATIVE,
|
||||
output_section, object,
|
||||
data_shndx, reloc.get_r_offset(),
|
||||
reloc.get_r_addend());
|
||||
reloc.get_r_addend(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1505,7 +1505,7 @@ Target_powerpc<size, big_endian>::Scan::global(
|
||||
output_section, object,
|
||||
data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend());
|
||||
reloc.get_r_addend(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1574,7 +1574,7 @@ Target_powerpc<size, big_endian>::Scan::global(
|
||||
|
||||
gsym->set_got_offset(GOT_TYPE_STANDARD, off);
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_POWERPC_RELATIVE,
|
||||
got, off, 0);
|
||||
got, off, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2333,7 +2333,7 @@ Target_sparc<size, big_endian>::Scan::global(
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_SPARC_RELATIVE,
|
||||
output_section, object,
|
||||
data_shndx, reloc.get_r_offset(),
|
||||
reloc.get_r_addend());
|
||||
reloc.get_r_addend(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2387,7 +2387,7 @@ Target_sparc<size, big_endian>::Scan::global(
|
||||
|
||||
gsym->set_got_offset(GOT_TYPE_STANDARD, off);
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_SPARC_RELATIVE,
|
||||
got, off, 0);
|
||||
got, off, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1667,24 +1667,24 @@ Target_x86_64<size>::reserve_global_got_entry(unsigned int got_index,
|
||||
this->got_, got_offset, 0);
|
||||
else
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_RELATIVE,
|
||||
this->got_, got_offset, 0);
|
||||
this->got_, got_offset, 0, false);
|
||||
}
|
||||
break;
|
||||
case GOT_TYPE_TLS_OFFSET:
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_TPOFF64,
|
||||
this->got_, got_offset, 0);
|
||||
this->got_, got_offset, 0, false);
|
||||
break;
|
||||
case GOT_TYPE_TLS_PAIR:
|
||||
this->got_->reserve_slot(got_index + 1);
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_DTPMOD64,
|
||||
this->got_, got_offset, 0);
|
||||
this->got_, got_offset, 0, false);
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_DTPOFF64,
|
||||
this->got_, got_offset + 8, 0);
|
||||
this->got_, got_offset + 8, 0, false);
|
||||
break;
|
||||
case GOT_TYPE_TLS_DESC:
|
||||
this->got_->reserve_slot(got_index + 1);
|
||||
rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_TLSDESC,
|
||||
this->got_, got_offset, 0);
|
||||
this->got_, got_offset, 0, false);
|
||||
break;
|
||||
default:
|
||||
gold_unreachable();
|
||||
@ -2505,7 +2505,7 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
|
||||
output_section, object,
|
||||
data_shndx,
|
||||
reloc.get_r_offset(),
|
||||
reloc.get_r_addend());
|
||||
reloc.get_r_addend(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2612,7 +2612,7 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
|
||||
unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
|
||||
rela_dyn->add_global_relative(gsym,
|
||||
elfcpp::R_X86_64_RELATIVE,
|
||||
got, got_off, 0);
|
||||
got, got_off, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user