+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>
* powerpc.cc (Target_powerpc::iplt_): New output section.
{
uint64_t data_size = this->got_->current_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()
// Get the GOT offset if needed.
// For tilegx, the GOT pointer points to the start of the GOT section.
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;
bool always_apply_relocation = false;
switch (r_type)
if (gsym != NULL)
{
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
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
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;
break;
if (have_got_offset) {
if (gsym != NULL) {
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 {
unsigned int r_sym
= elfcpp::elf_r_sym<size>(rela.get_r_info());
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;
}
}