This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] bfd: allow negative offsets to _GLOBAL_OFFSET_TABLE_ in elf64 SPARC
- From: Jose E.Marchesi <jemarch at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 19 Sep 2016 12:23:44 -0000
- Subject: [binutils-gdb] bfd: allow negative offsets to _GLOBAL_OFFSET_TABLE_ in elf64 SPARC
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b19753ce31da347605dfa903c6fd2158e2444f0d
commit b19753ce31da347605dfa903c6fd2158e2444f0d
Author: Jose E. Marchesi <jose.marchesi@oracle.com>
Date: Mon Sep 19 05:19:14 2016 -0700
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 <jose.marchesi@oracle.com>
* 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.
Diff:
---
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 <jose.marchesi@oracle.com>
+
+ * 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 <thomas.preudhomme@arm.com>
* 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;