From b19753ce31da347605dfa903c6fd2158e2444f0d Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 19 Sep 2016 05:19:14 -0700 Subject: [PATCH] bfd: allow negative offsets to _GLOBAL_OFFSET_TABLE_ in elf64 SPARC The code compiled with the -fpic model in SPARC uses 13-bit signed immediate PC-relative loads to fetch entries from the GOT table. In theory this would allow using a GOT table (.got section) containing up to 1024 entries in elf32 or 512 entries in elf64. However, in elf64 sparc GNU targets _GLOBAL_OFFSET_TABLE_ is always placed at the beginning of the .got section, making it impossible to use negative offsets. This limits the usage of -fpic to GOT tables containing a maximum of 257 entries in elf64. This patch activates an optimization that is already used in sparc-elf32 also in sparc-elf64, that sets _GLOBAL_OFFSET_TABLE_ to point 0x1000 into the .got section if the section size is bigger than 0x1000. 2016-09-19 Jose E. Marchesi * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Allow negative offsets to _GLOBAL_OFFSET_TABLE_ if the .got section is bigger than 0x1000 bytes. --- bfd/ChangeLog | 6 ++++++ bfd/elfxx-sparc.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b54d0c9..36624ee 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2016-09-19 Jose E. Marchesi + + * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Allow + negative offsets to _GLOBAL_OFFSET_TABLE_ if the .got section is + bigger than 0x1000 bytes. + 2016-09-14 Thomas Preud'homme * elf32-arm.c (elf32_arm_gc_mark_extra_sections): Only mark section diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 63558c7..30daedf 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2661,19 +2661,19 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, /* Allocate .plt and .got entries, and space for local symbols. */ htab_traverse (htab->loc_hash_table, allocate_local_dynrelocs, info); - if (! ABI_64_P (output_bfd) - && !htab->is_vxworks + if (!htab->is_vxworks && elf_hash_table (info)->dynamic_sections_created) { - /* Make space for the trailing nop in .plt. */ - if (htab->elf.splt->size > 0) - htab->elf.splt->size += 1 * SPARC_INSN_BYTES; + if (! ABI_64_P (output_bfd)) + { + /* Make space for the trailing nop in .plt. */ + if (htab->elf.splt->size > 0) + htab->elf.splt->size += 1 * SPARC_INSN_BYTES; + } /* If the .got section is more than 0x1000 bytes, we add 0x1000 to the value of _GLOBAL_OFFSET_TABLE_, so that 13 - bit relocations have a greater chance of working. - - FIXME: Make this optimization work for 64-bit too. */ + bit relocations have a greater chance of working. */ if (htab->elf.sgot->size >= 0x1000 && elf_hash_table (info)->hgot->root.u.def.value == 0) elf_hash_table (info)->hgot->root.u.def.value = 0x1000; -- 2.7.4