[PATCH v2] sparc: define _GLOBAL_OFFSET_TABLE_ when referenced

Alexandre Oliva oliva@adacore.com
Fri Feb 7 08:51:35 GMT 2025


On Feb  6, 2025, Alan Modra <amodra@gmail.com> wrote:

> Looks good, except for

>> +	  if (h != NULL && htab->elf.hgot)

> 	  if (h != NULL && h == htab->elf.hgot)

Ugh.  Sorry, yeah, that didn't look good at all indeed ;-)  :-(


Here's a squashed version of both patches, fixing the error above as
well.  Again, tested with target leon3-elf on x86_64-linux-gnu.  Ok to
install?


GCC testsuite gcc.dg/20050321-2.c hit link errors on undefined
_GLOBAL_OFFSET_TABLE_.  The compiler output referenced only
_GLOBAL_OFFSET_TABLE_-offsets to set it up, and to compute the
GOT-relative address of local symbols, none of which triggered the
machinery that enabled the creation of the dynamic section, so
_GLOBAL_OFFSET_TABLE_ ended up undefined.

Enable the dynamic section if we find a relocation involving
_GLOBAL_OFFSET_TABLE_.  While at that, optimize checks for references
to it.


for  bfd/ChangeLog

	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Check for
	_GLOBAL_OFFSET_TABLE_ references early, then compare hashed
	symbols instead of strings.
	(_bfd_sparc_elf_relocate_section): Compare hashed symbols.

for  ld/ChangeLog

	* testsuite/ld-sparc/got-def.s: New test.
	* testsuite/ld-sparc/sparc.exp: Add it.
---
 bfd/elfxx-sparc.c               |   16 ++++++++++++----
 ld/testsuite/ld-sparc/got-def.s |   15 +++++++++++++++
 ld/testsuite/ld-sparc/sparc.exp |    8 ++++++++
 3 files changed, 35 insertions(+), 4 deletions(-)
 create mode 100644 ld/testsuite/ld-sparc/got-def.s

diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 71061621e8bfb..1cf280f050f64 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1426,6 +1426,16 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  h->plt.refcount += 1;
 	}
 
+      /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.  */
+      if (h != NULL
+	  && htab->elf.sgot == NULL
+	  && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+	{
+	  if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
+	    return false;
+	  BFD_ASSERT (h == htab->elf.hgot);
+	}
+
       /* Compatibility with old R_SPARC_REV32 reloc conflicting
 	 with R_SPARC_TLS_GD_HI22.  */
       if (! ABI_64_P (abfd) && ! checked_tlsgd)
@@ -1645,8 +1655,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  if (h != NULL)
 	    h->non_got_ref = 1;
 
-	  if (h != NULL
-	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+	  if (h != NULL && h == htab->elf.hgot)
 	    break;
 	  /* Fall through.  */
 
@@ -3252,8 +3261,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	case R_SPARC_PC_HH22:
 	case R_SPARC_PC_HM10:
 	case R_SPARC_PC_LM22:
-	  if (h != NULL
-	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+	  if (h != NULL && h == htab->elf.hgot)
 	    break;
 	  /* Fall through.  */
 	case R_SPARC_DISP8:
diff --git a/ld/testsuite/ld-sparc/got-def.s b/ld/testsuite/ld-sparc/got-def.s
new file mode 100644
index 0000000000000..efca9109dfcb1
--- /dev/null
+++ b/ld/testsuite/ld-sparc/got-def.s
@@ -0,0 +1,15 @@
+	.text
+.LLGETPC0:
+	retl
+	 add	%o7, %l7, %l7
+	.global got
+	.type got, #function
+	.proc   04
+got:
+	save    %sp, -160, %sp
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %l7
+	call	.LLGETPC0
+	 add	%l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7
+	mov	%l7, %o0
+	ret
+	 restore
diff --git a/ld/testsuite/ld-sparc/sparc.exp b/ld/testsuite/ld-sparc/sparc.exp
index 9d684899ee2c2..3e21ed738c443 100644
--- a/ld/testsuite/ld-sparc/sparc.exp
+++ b/ld/testsuite/ld-sparc/sparc.exp
@@ -94,6 +94,10 @@ set sparctests {
     {"32-bit: TLS -fpie" "-melf32_sparc -pie tmpdir/libtlslib32.so" ""
      "--32 -K PIC" {tlspie32.s}
      {{objdump -drj.text tlspie32.dd}} "tlspie32"}
+    {"32-bit: GOT definition"
+     "-melf32_sparc" ""
+     "--32 -K PIC" {got-def.s}
+     {} "got-def"}
     {"32-bit: GOTDATA relocations"
      "-shared -melf32_sparc --hash-style=sysv" ""
      "--32 -K PIC" {gotop32.s}
@@ -134,6 +138,10 @@ set sparc64tests {
      "-melf64_sparc -pie -Ttext-segment=0x100000 tmpdir/libtlslib64.so" ""
      "--64 -Av9 -K PIC" {tlspie64.s}
      {{objdump -drj.text tlspie64.dd}} "tlspie64"}
+    {"64-bit: GOT definition"
+     "-melf64_sparc" ""
+     "--64 -Av9 -K PIC" {got-def.s}
+     {} "got-def"}
     {"64-bit: GOTDATA relocations"
      "-shared -melf64_sparc --hash-style=sysv" ""
      "--64 -Av9 -K PIC" {gotop64.s}


-- 
Alexandre Oliva, happy hacker            https://FSFLA.org/blogs/lxo/
   Free Software Activist                   GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive


More information about the Binutils mailing list