Download raw body.
ld.bfd: handle modern SPARC GOTDATA relocations
tech@,
Modern GAS emits R_SPARC_GOTDATA_OP_HIX22, R_SPARC_GOTDATA_OP_LOX10, and
R_SPARC_GOTDATA_OP, which are unknown to BFD 2.17 and cause the final link
to fail with "Bad value".
This diff fixed bulding devel/gmp which passed make test.
Ok?
Index: gnu/usr.bin/binutils-2.17/bfd/bfd-in2.h
===================================================================
RCS file: /home/cvs/src/gnu/usr.bin/binutils-2.17/bfd/bfd-in2.h,v
diff -u -p -r1.12 bfd-in2.h
--- gnu/usr.bin/binutils-2.17/bfd/bfd-in2.h 11 Jan 2024 12:31:37 -0000 1.12
+++ gnu/usr.bin/binutils-2.17/bfd/bfd-in2.h 4 Aug 2026 19:35:03 -0000
@@ -2373,6 +2373,11 @@ relocation types already defined. */
BFD_RELOC_SPARC_UA16,
BFD_RELOC_SPARC_UA32,
BFD_RELOC_SPARC_UA64,
+ BFD_RELOC_SPARC_GOTDATA_HIX22,
+ BFD_RELOC_SPARC_GOTDATA_LOX10,
+ BFD_RELOC_SPARC_GOTDATA_OP_HIX22,
+ BFD_RELOC_SPARC_GOTDATA_OP_LOX10,
+ BFD_RELOC_SPARC_GOTDATA_OP,
/* I think these are specific to SPARC a.out (e.g., Sun 4). */
BFD_RELOC_SPARC_BASE13,
Index: gnu/usr.bin/binutils-2.17/bfd/elfxx-sparc.c
===================================================================
RCS file: /home/cvs/src/gnu/usr.bin/binutils-2.17/bfd/elfxx-sparc.c,v
diff -u -p -r1.7 elfxx-sparc.c
--- gnu/usr.bin/binutils-2.17/bfd/elfxx-sparc.c 15 Apr 2017 10:23:35 -0000 1.7
+++ gnu/usr.bin/binutils-2.17/bfd/elfxx-sparc.c 4 Aug 2026 19:38:17 -0000
@@ -256,7 +256,12 @@ static reloc_howto_type _bfd_sparc_elf_h
HOWTO(R_SPARC_TLS_DTPOFF32,0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_TLS_DTPOFF32",FALSE,0,0xffffffff,TRUE),
HOWTO(R_SPARC_TLS_DTPOFF64,0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_TLS_DTPOFF64",FALSE,0,MINUS_ONE,TRUE),
HOWTO(R_SPARC_TLS_TPOFF32,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF32",FALSE,0,0x00000000,TRUE),
- HOWTO(R_SPARC_TLS_TPOFF64,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF64",FALSE,0,0x00000000,TRUE)
+ HOWTO(R_SPARC_TLS_TPOFF64,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF64",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_GOTDATA_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_GOTDATA_HIX22",FALSE,0,0x003fffff,FALSE),
+ HOWTO(R_SPARC_GOTDATA_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_GOTDATA_LOX10",FALSE,0,0x000003ff,FALSE),
+ HOWTO(R_SPARC_GOTDATA_OP_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_GOTDATA_OP_HIX22",FALSE,0,0x003fffff,FALSE),
+ HOWTO(R_SPARC_GOTDATA_OP_LOX10,0,2,0,FALSE,0,complain_overflow_dont,sparc_elf_lox10_reloc,"R_SPARC_GOTDATA_OP_LOX10",FALSE,0,0x000003ff,FALSE),
+ HOWTO(R_SPARC_GOTDATA_OP,0,0,0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOTDATA_OP",FALSE,0,0x00000000,TRUE)
};
static reloc_howto_type sparc_vtinherit_howto =
HOWTO (R_SPARC_GNU_VTINHERIT, 0,2,0,FALSE,0,complain_overflow_dont, NULL, "R_SPARC_GNU_VTINHERIT", FALSE,0, 0, FALSE);
@@ -340,6 +345,11 @@ static const struct elf_reloc_map sparc_
{ BFD_RELOC_SPARC_TLS_DTPOFF64, R_SPARC_TLS_DTPOFF64 },
{ BFD_RELOC_SPARC_TLS_TPOFF32, R_SPARC_TLS_TPOFF32 },
{ BFD_RELOC_SPARC_TLS_TPOFF64, R_SPARC_TLS_TPOFF64 },
+ { BFD_RELOC_SPARC_GOTDATA_HIX22, R_SPARC_GOTDATA_HIX22 },
+ { BFD_RELOC_SPARC_GOTDATA_LOX10, R_SPARC_GOTDATA_LOX10 },
+ { BFD_RELOC_SPARC_GOTDATA_OP_HIX22, R_SPARC_GOTDATA_OP_HIX22 },
+ { BFD_RELOC_SPARC_GOTDATA_OP_LOX10, R_SPARC_GOTDATA_OP_LOX10 },
+ { BFD_RELOC_SPARC_GOTDATA_OP, R_SPARC_GOTDATA_OP },
{ BFD_RELOC_SPARC_PLT32, R_SPARC_PLT32 },
{ BFD_RELOC_SPARC_PLT64, R_SPARC_PLT64 },
{ BFD_RELOC_SPARC_HIX22, R_SPARC_HIX22 },
@@ -1147,6 +1157,10 @@ _bfd_sparc_elf_check_relocs (bfd *abfd,
case R_SPARC_GOT10:
case R_SPARC_GOT13:
case R_SPARC_GOT22:
+ case R_SPARC_GOTDATA_HIX22:
+ case R_SPARC_GOTDATA_LOX10:
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
case R_SPARC_TLS_GD_HI22:
case R_SPARC_TLS_GD_LO10:
/* This symbol requires a global offset table entry. */
@@ -1607,6 +1621,10 @@ _bfd_sparc_elf_gc_sweep_hook (bfd *abfd,
case R_SPARC_GOT10:
case R_SPARC_GOT13:
case R_SPARC_GOT22:
+ case R_SPARC_GOTDATA_HIX22:
+ case R_SPARC_GOTDATA_LOX10:
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
if (h != NULL)
{
if (h->got.refcount > 0)
@@ -2563,6 +2581,19 @@ _bfd_sparc_elf_relocate_section (bfd *ou
switch (r_type)
{
+ case R_SPARC_GOTDATA_HIX22:
+ case R_SPARC_GOTDATA_LOX10:
+ if (htab->sgot == NULL)
+ abort ();
+ relocation -= (htab->sgot->output_section->vma
+ + htab->sgot->output_offset + got_base);
+ break;
+
+ case R_SPARC_GOTDATA_OP:
+ continue;
+
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
case R_SPARC_GOT10:
case R_SPARC_GOT13:
case R_SPARC_GOT22:
@@ -3332,12 +3363,16 @@ _bfd_sparc_elf_relocate_section (bfd *ou
r = bfd_reloc_ok;
}
- else if (r_type == R_SPARC_HIX22)
+ else if (r_type == R_SPARC_HIX22
+ || r_type == R_SPARC_GOTDATA_HIX22
+ || r_type == R_SPARC_GOTDATA_OP_HIX22)
{
bfd_vma x;
relocation += rel->r_addend;
- relocation = relocation ^ MINUS_ONE;
+ if (r_type == R_SPARC_HIX22
+ || (bfd_signed_vma) relocation < 0)
+ relocation = relocation ^ MINUS_ONE;
x = bfd_get_32 (input_bfd, contents + rel->r_offset);
x = (x & ~(bfd_vma) 0x3fffff) | ((relocation >> 10) & 0x3fffff);
@@ -3348,12 +3383,18 @@ _bfd_sparc_elf_relocate_section (bfd *ou
bfd_arch_bits_per_address (input_bfd),
relocation);
}
- else if (r_type == R_SPARC_LOX10)
+ else if (r_type == R_SPARC_LOX10
+ || r_type == R_SPARC_GOTDATA_LOX10
+ || r_type == R_SPARC_GOTDATA_OP_LOX10)
{
bfd_vma x;
relocation += rel->r_addend;
- relocation = (relocation & 0x3ff) | 0x1c00;
+ if (r_type == R_SPARC_LOX10
+ || (bfd_signed_vma) relocation < 0)
+ relocation = (relocation & 0x3ff) | 0x1c00;
+ else
+ relocation &= 0x3ff;
x = bfd_get_32 (input_bfd, contents + rel->r_offset);
x = (x & ~(bfd_vma) 0x1fff) | relocation;
Index: gnu/usr.bin/binutils-2.17/bfd/libbfd.h
===================================================================
RCS file: /home/cvs/src/gnu/usr.bin/binutils-2.17/bfd/libbfd.h,v
diff -u -p -r1.8 libbfd.h
--- gnu/usr.bin/binutils-2.17/bfd/libbfd.h 11 Jan 2024 12:31:37 -0000 1.8
+++ gnu/usr.bin/binutils-2.17/bfd/libbfd.h 4 Aug 2026 19:41:03 -0000
@@ -853,6 +853,11 @@ static const char *const bfd_reloc_code_
"BFD_RELOC_SPARC_UA16",
"BFD_RELOC_SPARC_UA32",
"BFD_RELOC_SPARC_UA64",
+ "BFD_RELOC_SPARC_GOTDATA_HIX22",
+ "BFD_RELOC_SPARC_GOTDATA_LOX10",
+ "BFD_RELOC_SPARC_GOTDATA_OP_HIX22",
+ "BFD_RELOC_SPARC_GOTDATA_OP_LOX10",
+ "BFD_RELOC_SPARC_GOTDATA_OP",
"BFD_RELOC_SPARC_BASE13",
"BFD_RELOC_SPARC_BASE22",
"BFD_RELOC_SPARC_10",
Index: gnu/usr.bin/binutils-2.17/bfd/reloc.c
===================================================================
RCS file: /home/cvs/src/gnu/usr.bin/binutils-2.17/bfd/reloc.c,v
diff -u -p -r1.4 reloc.c
--- gnu/usr.bin/binutils-2.17/bfd/reloc.c 25 Feb 2017 22:53:36 -0000 1.4
+++ gnu/usr.bin/binutils-2.17/bfd/reloc.c 4 Aug 2026 19:35:03 -0000
@@ -1768,6 +1768,16 @@ ENUMX
BFD_RELOC_SPARC_UA32
ENUMX
BFD_RELOC_SPARC_UA64
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_HIX22
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_LOX10
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_OP_HIX22
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_OP_LOX10
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_OP
ENUMDOC
SPARC ELF relocations. There is probably some overlap with other
relocation types already defined.
Index: gnu/usr.bin/binutils-2.17/include/elf/sparc.h
===================================================================
RCS file: /home/cvs/src/gnu/usr.bin/binutils-2.17/include/elf/sparc.h,v
diff -u -p -r1.1.1.1 sparc.h
--- gnu/usr.bin/binutils-2.17/include/elf/sparc.h 24 Apr 2011 20:14:48 -0000 1.1.1.1
+++ gnu/usr.bin/binutils-2.17/include/elf/sparc.h 4 Aug 2026 19:35:03 -0000
@@ -151,6 +151,12 @@ START_RELOC_NUMBERS (elf_sparc_reloc_typ
RELOC_NUMBER (R_SPARC_TLS_DTPOFF64, 77)
RELOC_NUMBER (R_SPARC_TLS_TPOFF32, 78)
RELOC_NUMBER (R_SPARC_TLS_TPOFF64, 79)
+
+ RELOC_NUMBER (R_SPARC_GOTDATA_HIX22, 80)
+ RELOC_NUMBER (R_SPARC_GOTDATA_LOX10, 81)
+ RELOC_NUMBER (R_SPARC_GOTDATA_OP_HIX22, 82)
+ RELOC_NUMBER (R_SPARC_GOTDATA_OP_LOX10, 83)
+ RELOC_NUMBER (R_SPARC_GOTDATA_OP, 84)
EMPTY_RELOC (R_SPARC_max_std)
--
wbr, Kirill
ld.bfd: handle modern SPARC GOTDATA relocations