From: Kirill A. Korinsky Subject: ld.bfd: handle modern SPARC GOTDATA relocations To: OpenBSD tech Cc: kmos@openbsd.org Date: Tue, 04 Aug 2026 21:59:42 +0200 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