Adjust the value of _GLOBAL_OFFSET_TABLE_ for got bigger than 0x8000
bytes, so that the 16 bit relocations have a greater chance of working. * tilegx.cc (Target_tilegx::do_finalize_sections): Adjust global_offset_table_ value for larget got. (Target_tilegx::Relocate::relocate): Handle adjusted got value.
This commit is contained in:
parent
a330419054
commit
e867b64722
2 changed files with 23 additions and 5 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2012-10-02 Jiong Wang <jiwang@tilera.com>
|
||||||
|
|
||||||
|
* tilegx.cc (Target_tilegx::do_finalize_sections): Adjust
|
||||||
|
global_offset_table_ value for larget got.
|
||||||
|
(Target_tilegx::Relocate::relocate): Handle adjusted got value.
|
||||||
|
|
||||||
2012-09-29 Alan Modra <amodra@gmail.com>
|
2012-09-29 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* powerpc.cc (Target_powerpc::iplt_): New output section.
|
* powerpc.cc (Target_powerpc::iplt_): New output section.
|
||||||
|
|
|
@ -4256,6 +4256,13 @@ Target_tilegx<size, big_endian>::do_finalize_sections(
|
||||||
{
|
{
|
||||||
uint64_t data_size = this->got_->current_data_size();
|
uint64_t data_size = this->got_->current_data_size();
|
||||||
symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
|
symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
|
||||||
|
|
||||||
|
// If the .got section is more than 0x8000 bytes, we add
|
||||||
|
// 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
|
||||||
|
// bit relocations have a greater chance of working.
|
||||||
|
if (data_size >= 0x8000)
|
||||||
|
symtab->get_sized_symbol<size>(sym)->set_value(
|
||||||
|
symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters->doing_static_link()
|
if (parameters->doing_static_link()
|
||||||
|
@ -4347,7 +4354,10 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
|
||||||
// Get the GOT offset if needed.
|
// Get the GOT offset if needed.
|
||||||
// For tilegx, the GOT pointer points to the start of the GOT section.
|
// For tilegx, the GOT pointer points to the start of the GOT section.
|
||||||
bool have_got_offset = false;
|
bool have_got_offset = false;
|
||||||
unsigned int got_offset = 0;
|
int got_offset = 0;
|
||||||
|
int got_base = target->got_ != NULL
|
||||||
|
? target->got_->current_data_size() >= 0x8000 ? 0x8000 : 0
|
||||||
|
: 0;
|
||||||
unsigned int got_type = GOT_TYPE_STANDARD;
|
unsigned int got_type = GOT_TYPE_STANDARD;
|
||||||
bool always_apply_relocation = false;
|
bool always_apply_relocation = false;
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
|
@ -4361,13 +4371,14 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
|
||||||
if (gsym != NULL)
|
if (gsym != NULL)
|
||||||
{
|
{
|
||||||
gold_assert(gsym->has_got_offset(got_type));
|
gold_assert(gsym->has_got_offset(got_type));
|
||||||
got_offset = gsym->got_offset(got_type);
|
got_offset = gsym->got_offset(got_type) - got_base;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
|
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
|
||||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||||
got_offset = object->local_got_offset(r_sym, got_type);
|
got_offset =
|
||||||
|
object->local_got_offset(r_sym, got_type) - got_base;
|
||||||
}
|
}
|
||||||
have_got_offset = true;
|
have_got_offset = true;
|
||||||
break;
|
break;
|
||||||
|
@ -4590,12 +4601,13 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
|
||||||
if (have_got_offset) {
|
if (have_got_offset) {
|
||||||
if (gsym != NULL) {
|
if (gsym != NULL) {
|
||||||
gold_assert(gsym->has_got_offset(got_type));
|
gold_assert(gsym->has_got_offset(got_type));
|
||||||
got_offset = gsym->got_offset(got_type);
|
got_offset = gsym->got_offset(got_type) - got_base;
|
||||||
} else {
|
} else {
|
||||||
unsigned int r_sym
|
unsigned int r_sym
|
||||||
= elfcpp::elf_r_sym<size>(rela.get_r_info());
|
= elfcpp::elf_r_sym<size>(rela.get_r_info());
|
||||||
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
gold_assert(object->local_has_got_offset(r_sym, got_type));
|
||||||
got_offset = object->local_got_offset(r_sym, got_type);
|
got_offset =
|
||||||
|
object->local_got_offset(r_sym, got_type) - got_base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue