From e867b64722d18cb3672b4a07ee2685d7018c220b Mon Sep 17 00:00:00 2001 From: Walter Lee Date: Wed, 3 Oct 2012 00:58:03 +0000 Subject: 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. --- gold/ChangeLog | 6 ++++++ gold/tilegx.cc | 22 +++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index 2479586..125d462 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,9 @@ +2012-10-02 Jiong Wang + + * 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 * powerpc.cc (Target_powerpc::iplt_): New output section. diff --git a/gold/tilegx.cc b/gold/tilegx.cc index 037bf54..a209a97 100644 --- a/gold/tilegx.cc +++ b/gold/tilegx.cc @@ -4256,6 +4256,13 @@ Target_tilegx::do_finalize_sections( { uint64_t data_size = this->got_->current_data_size(); symtab->get_sized_symbol(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(sym)->set_value( + symtab->get_sized_symbol(sym)->value() + 0x8000); } if (parameters->doing_static_link() @@ -4347,7 +4354,10 @@ Target_tilegx::Relocate::relocate( // 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) @@ -4361,13 +4371,14 @@ Target_tilegx::Relocate::relocate( 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(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; @@ -4590,12 +4601,13 @@ Target_tilegx::Relocate::relocate( 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(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; } } -- cgit v1.1