From: Maciej W. Rozycki Date: Thu, 30 Oct 2025 14:24:23 +0000 (+0000) Subject: MIPS/GAS: Add HI16/LO16 pairing for REL TLS relocs X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ad26c67309c780aa06c6066924a04f15b9a6c029;p=thirdparty%2Fbinutils-gdb.git MIPS/GAS: Add HI16/LO16 pairing for REL TLS relocs Complementing commit 7ea90d9316d3 ("MIPS: Fix linker for REL TLS HI16/LO16 relocs") also add pairing for HI16/LO16 REL TLS relocations in GAS, which is where it needs to be done in the first place and which is required for later linker operation on the objects produced. Pairing also corrects in-place addend installation for the high-part relocations, which used not to happen in the absence of this fix for ones not already followed by the corresponding low-part relocation. Add test cases to verify relocation ordering and addend installation. --- diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index f7ee46c68f2..42d2cb5e435 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -4352,6 +4352,28 @@ lo16_reloc_p (bfd_reloc_code_real_type reloc) || reloc == BFD_RELOC_MICROMIPS_LO16); } +static inline bool +tls_hi16_reloc_p (bfd_reloc_code_real_type reloc) +{ + return (reloc == BFD_RELOC_MIPS_TLS_DTPREL_HI16 + || reloc == BFD_RELOC_MIPS_TLS_TPREL_HI16 + || reloc == BFD_RELOC_MIPS16_TLS_DTPREL_HI16 + || reloc == BFD_RELOC_MIPS16_TLS_TPREL_HI16 + || reloc == BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16 + || reloc == BFD_RELOC_MICROMIPS_TLS_TPREL_HI16); +} + +static inline bool +tls_lo16_reloc_p (bfd_reloc_code_real_type reloc) +{ + return (reloc == BFD_RELOC_MIPS_TLS_DTPREL_LO16 + || reloc == BFD_RELOC_MIPS_TLS_TPREL_LO16 + || reloc == BFD_RELOC_MIPS16_TLS_DTPREL_LO16 + || reloc == BFD_RELOC_MIPS16_TLS_TPREL_LO16 + || reloc == BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16 + || reloc == BFD_RELOC_MICROMIPS_TLS_TPREL_LO16); +} + static inline bool jalr_reloc_p (bfd_reloc_code_real_type reloc) { @@ -4403,6 +4425,7 @@ reloc_needs_lo_p (bfd_reloc_code_real_type reloc) { return (HAVE_IN_PLACE_ADDENDS && (hi16_reloc_p (reloc) + || tls_hi16_reloc_p (reloc) /* VxWorks R_MIPS_GOT16 relocs never need a matching %lo(); all GOT16 relocations evaluate to "G". */ || (got16_reloc_p (reloc) && mips_pic != VXWORKS_PIC))); @@ -4414,10 +4437,34 @@ reloc_needs_lo_p (bfd_reloc_code_real_type reloc) static inline bfd_reloc_code_real_type matching_lo_reloc (bfd_reloc_code_real_type reloc) { - return (mips16_reloc_p (reloc) ? BFD_RELOC_MIPS16_LO16 - : micromips_reloc_p (reloc) ? BFD_RELOC_MICROMIPS_LO16 - : reloc == BFD_RELOC_HI16_S_PCREL ? BFD_RELOC_LO16_PCREL - : BFD_RELOC_LO16); + switch (reloc) + { + case BFD_RELOC_HI16_S: + case BFD_RELOC_MIPS_GOT16: + return BFD_RELOC_LO16; + case BFD_RELOC_HI16_S_PCREL: + return BFD_RELOC_LO16_PCREL; + case BFD_RELOC_MIPS_TLS_DTPREL_HI16: + return BFD_RELOC_MIPS_TLS_DTPREL_LO16; + case BFD_RELOC_MIPS_TLS_TPREL_HI16: + return BFD_RELOC_MIPS_TLS_TPREL_LO16; + case BFD_RELOC_MIPS16_HI16_S: + case BFD_RELOC_MIPS16_GOT16: + return BFD_RELOC_MIPS16_LO16; + case BFD_RELOC_MIPS16_TLS_DTPREL_HI16: + return BFD_RELOC_MIPS16_TLS_DTPREL_LO16; + case BFD_RELOC_MIPS16_TLS_TPREL_HI16: + return BFD_RELOC_MIPS16_TLS_TPREL_LO16; + case BFD_RELOC_MICROMIPS_HI16_S: + case BFD_RELOC_MICROMIPS_GOT16: + return BFD_RELOC_MICROMIPS_LO16; + case BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16: + return BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16; + case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16: + return BFD_RELOC_MICROMIPS_TLS_TPREL_LO16; + default: + abort (); + } } /* Return true if the given fixup is followed by a matching R_MIPS_LO16 @@ -7942,6 +7989,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr, || reloc_type[0] == BFD_RELOC_MIPS_16 || reloc_type[0] == BFD_RELOC_MIPS_RELGOT || reloc_type[0] == BFD_RELOC_MIPS16_GPREL + || tls_hi16_reloc_p (reloc_type[0]) + || tls_lo16_reloc_p (reloc_type[0]) || hi16_reloc_p (reloc_type[0]) || lo16_reloc_p (reloc_type[0]))) ip->fixp[0]->fx_no_overflow = 1; @@ -18304,6 +18353,7 @@ mips_fix_adjustable (fixS *fixp) this, it seems better not to force the issue, and instead keep the original symbol. This will work with either linker behavior. */ if ((lo16_reloc_p (fixp->fx_r_type) + || tls_lo16_reloc_p (fixp->fx_r_type) || reloc_needs_lo_p (fixp->fx_r_type)) && HAVE_IN_PLACE_ADDENDS && (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0) diff --git a/gas/testsuite/gas/mips/micromips-tls-hilo-addend.d b/gas/testsuite/gas/mips/micromips-tls-hilo-addend.d new file mode 100644 index 00000000000..8c694998496 --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-tls-hilo-addend.d @@ -0,0 +1,62 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#as: -mabi=32 -march=mips1 -mno-pdr --defsym micromips=1 +#name: MIPS and microMIPS TLS HI/LO REL relocation addends +#source: mips-tls-hilo-match.s + +.*: +file format .*mips.* + +Disassembly of section \.text: +00000000 <[^>]*> 24025678 li v0,22136 + 0: R_MIPS_LO16 var1 +00000004 <[^>]*> 24039384 li v1,-27772 + 4: R_MIPS_LO16 var1 +00000008 <[^>]*> 24045678 li a0,22136 + 8: R_MIPS_TLS_DTPREL_LO16 var2 +0000000c <[^>]*> 24059384 li a1,-27772 + c: R_MIPS_TLS_DTPREL_LO16 var2 +00000010 <[^>]*> 24065678 li a2,22136 + 10: R_MIPS_TLS_TPREL_LO16 var3 +00000014 <[^>]*> 03e00008 jr ra +00000018 <[^>]*> 24079384 li a3,-27772 + 18: R_MIPS_TLS_TPREL_LO16 var3 +0000001c <[^>]*> 3040 5678 li v0,22136 + 1c: R_MICROMIPS_LO16 var1 +00000020 <[^>]*> 3060 9384 li v1,-27772 + 20: R_MICROMIPS_LO16 var1 +00000024 <[^>]*> 3080 5678 li a0,22136 + 24: R_MICROMIPS_TLS_DTPREL_LO16 var2 +00000028 <[^>]*> 30a0 9384 li a1,-27772 + 28: R_MICROMIPS_TLS_DTPREL_LO16 var2 +0000002c <[^>]*> 30c0 5678 li a2,22136 + 2c: R_MICROMIPS_TLS_TPREL_LO16 var3 +00000030 <[^>]*> 459f jr ra +00000032 <[^>]*> 30e0 9384 li a3,-27772 + 32: R_MICROMIPS_TLS_TPREL_LO16 var3 + \.\.\. +00000038 <[^>]*> 2407b1a3 li a3,-20061 + 38: R_MIPS_TLS_TPREL_HI16 var3 +0000003c <[^>]*> 24061234 li a2,4660 + 3c: R_MIPS_TLS_TPREL_HI16 var3 +00000040 <[^>]*> 2405b1a3 li a1,-20061 + 40: R_MIPS_TLS_DTPREL_HI16 var2 +00000044 <[^>]*> 24041234 li a0,4660 + 44: R_MIPS_TLS_DTPREL_HI16 var2 +00000048 <[^>]*> 2403b1a3 li v1,-20061 + 48: R_MIPS_HI16 var1 +0000004c <[^>]*> 03e00008 jr ra +00000050 <[^>]*> 24021234 li v0,4660 + 50: R_MIPS_HI16 var1 +00000054 <[^>]*> 30e0 b1a3 li a3,-20061 + 54: R_MICROMIPS_TLS_TPREL_HI16 var3 +00000058 <[^>]*> 30c0 1234 li a2,4660 + 58: R_MICROMIPS_TLS_TPREL_HI16 var3 +0000005c <[^>]*> 30a0 b1a3 li a1,-20061 + 5c: R_MICROMIPS_TLS_DTPREL_HI16 var2 +00000060 <[^>]*> 3080 1234 li a0,4660 + 60: R_MICROMIPS_TLS_DTPREL_HI16 var2 +00000064 <[^>]*> 3060 b1a3 li v1,-20061 + 64: R_MICROMIPS_HI16 var1 +00000068 <[^>]*> 459f jr ra +0000006a <[^>]*> 3040 1234 li v0,4660 + 6a: R_MICROMIPS_HI16 var1 + \.\.\. diff --git a/gas/testsuite/gas/mips/micromips-tls-hilo-match.d b/gas/testsuite/gas/mips/micromips-tls-hilo-match.d new file mode 100644 index 00000000000..f4e4a56c2e1 --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-tls-hilo-match.d @@ -0,0 +1,31 @@ +#readelf: -Wr +#as: -mabi=32 -march=mips1 -mno-pdr --defsym micromips=1 +#name: MIPS and microMIPS TLS HI/LO REL relocation matching +#source: mips-tls-hilo-match.s + +Relocation section '\.rel\.text' at offset .* contains 24 entries: + Offset Info Type Sym\. Value Symbol's Name +00000050 00000905 R_MIPS_HI16 00000000 var1 +00000000 00000906 R_MIPS_LO16 00000000 var1 +00000048 00000905 R_MIPS_HI16 00000000 var1 +00000004 00000906 R_MIPS_LO16 00000000 var1 +00000044 00000a2c R_MIPS_TLS_DTPREL_HI16 00000000 var2 +00000008 00000a2d R_MIPS_TLS_DTPREL_LO16 00000000 var2 +00000040 00000a2c R_MIPS_TLS_DTPREL_HI16 00000000 var2 +0000000c 00000a2d R_MIPS_TLS_DTPREL_LO16 00000000 var2 +0000003c 00000b31 R_MIPS_TLS_TPREL_HI16 00000000 var3 +00000010 00000b32 R_MIPS_TLS_TPREL_LO16 00000000 var3 +00000038 00000b31 R_MIPS_TLS_TPREL_HI16 00000000 var3 +00000018 00000b32 R_MIPS_TLS_TPREL_LO16 00000000 var3 +0000006a 00000986 R_MICROMIPS_HI16 00000000 var1 +0000001c 00000987 R_MICROMIPS_LO16 00000000 var1 +00000064 00000986 R_MICROMIPS_HI16 00000000 var1 +00000020 00000987 R_MICROMIPS_LO16 00000000 var1 +00000060 00000aa4 R_MICROMIPS_TLS_DTPREL_HI16 00000000 var2 +00000024 00000aa5 R_MICROMIPS_TLS_DTPREL_LO16 00000000 var2 +0000005c 00000aa4 R_MICROMIPS_TLS_DTPREL_HI16 00000000 var2 +00000028 00000aa5 R_MICROMIPS_TLS_DTPREL_LO16 00000000 var2 +00000058 00000ba9 R_MICROMIPS_TLS_TPREL_HI16 00000000 var3 +0000002c 00000baa R_MICROMIPS_TLS_TPREL_LO16 00000000 var3 +00000054 00000ba9 R_MICROMIPS_TLS_TPREL_HI16 00000000 var3 +00000032 00000baa R_MICROMIPS_TLS_TPREL_LO16 00000000 var3 diff --git a/gas/testsuite/gas/mips/mips-tls-hilo-match.s b/gas/testsuite/gas/mips/mips-tls-hilo-match.s new file mode 100644 index 00000000000..112caa87086 --- /dev/null +++ b/gas/testsuite/gas/mips/mips-tls-hilo-match.s @@ -0,0 +1,72 @@ + .text + .globl fun1 + .ent fun1 +fun1: + li $2, %lo(var1 + 0x12345678) + li $3, %lo(var1 + 0xb1a29384) + li $4, %dtprel_lo(var2 + 0x12345678) + li $5, %dtprel_lo(var2 + 0xb1a29384) + li $6, %tprel_lo(var3 + 0x12345678) + li $7, %tprel_lo(var3 + 0xb1a29384) + jr $31 + .end fun1 + + .set push + .ifdef micromips + .set micromips + .else + .set mips16 + .endif + + .globl fun2 + .ent fun2 +fun2: + li $2, %lo(var1 + 0x12345678) + li $3, %lo(var1 + 0xb1a29384) + li $4, %dtprel_lo(var2 + 0x12345678) + li $5, %dtprel_lo(var2 + 0xb1a29384) + li $6, %tprel_lo(var3 + 0x12345678) + li $7, %tprel_lo(var3 + 0xb1a29384) + jr $31 + .end fun2 + + .set pop + .align 2 + + .globl fun3 + .ent fun3 +fun3: + li $7, %tprel_hi(var3 + 0xb1a29384) + li $6, %tprel_hi(var3 + 0x12345678) + li $5, %dtprel_hi(var2 + 0xb1a29384) + li $4, %dtprel_hi(var2 + 0x12345678) + li $3, %hi(var1 + 0xb1a29384) + li $2, %hi(var1 + 0x12345678) + jr $31 + .end fun3 + + .set push + .ifdef micromips + .set micromips + .else + .set mips16 + .endif + + .globl fun4 + .ent fun4 +fun4: + li $7, %tprel_hi(var3 + 0xb1a29384) + li $6, %tprel_hi(var3 + 0x12345678) + li $5, %dtprel_hi(var2 + 0xb1a29384) + li $4, %dtprel_hi(var2 + 0x12345678) + li $3, %hi(var1 + 0xb1a29384) + li $2, %hi(var1 + 0x12345678) + jr $31 + .end fun4 + + .set pop + .align 2 + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .space 16 + .align 4, 0 diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index 48b1fe7bf46..be02e7f3d59 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -1057,6 +1057,8 @@ if { [istarget mips*-*-vxworks*] } { run_dump_test "mips16e2-hilo-n32" } run_dump_test "mips16-hilo-match" + run_dump_test "mips16-tls-hilo-match" + run_dump_test "mips16-tls-hilo-addend" run_dump_test "mips16-reloc-error" run_dump_test "mips16e2-reloc-error" run_dump_test "mips16-reg-error" @@ -1655,6 +1657,8 @@ if { [istarget mips*-*-vxworks*] } { run_dump_test "micromips-hilo-n64" } run_dump_test "micromips-hilo-match" + run_dump_test "micromips-tls-hilo-match" + run_dump_test "micromips-tls-hilo-addend" run_dump_test_arches "mcu" [mips_arch_list_matching mips32r2 \ !octeon] diff --git a/gas/testsuite/gas/mips/mips16-tls-hilo-addend.d b/gas/testsuite/gas/mips/mips16-tls-hilo-addend.d new file mode 100644 index 00000000000..90b8550da16 --- /dev/null +++ b/gas/testsuite/gas/mips/mips16-tls-hilo-addend.d @@ -0,0 +1,63 @@ +#objdump: -dr --prefix-addresses --show-raw-insn +#as: -mabi=32 -march=mips1 -mno-pdr +#name: MIPS and MIPS16 TLS HI/LO REL relocation addends +#source: mips-tls-hilo-match.s + +.*: +file format .*mips.* + +Disassembly of section \.text: +00000000 <[^>]*> 24025678 li v0,22136 + 0: R_MIPS_LO16 var1 +00000004 <[^>]*> 24039384 li v1,-27772 + 4: R_MIPS_LO16 var1 +00000008 <[^>]*> 24045678 li a0,22136 + 8: R_MIPS_TLS_DTPREL_LO16 var2 +0000000c <[^>]*> 24059384 li a1,-27772 + c: R_MIPS_TLS_DTPREL_LO16 var2 +00000010 <[^>]*> 24065678 li a2,22136 + 10: R_MIPS_TLS_TPREL_LO16 var3 +00000014 <[^>]*> 03e00008 jr ra +00000018 <[^>]*> 24079384 li a3,-27772 + 18: R_MIPS_TLS_TPREL_LO16 var3 +0000001c <[^>]*> f66a 6a18 li v0,22136 + 1c: R_MIPS16_LO16 var1 +00000020 <[^>]*> f392 6b04 li v1,37764 + 20: R_MIPS16_LO16 var1 +00000024 <[^>]*> f66a 6c18 li a0,22136 + 24: R_MIPS16_TLS_DTPREL_LO16 var2 +00000028 <[^>]*> f392 6d04 li a1,37764 + 28: R_MIPS16_TLS_DTPREL_LO16 var2 +0000002c <[^>]*> f66a 6e18 li a2,22136 + 2c: R_MIPS16_TLS_TPREL_LO16 var3 +00000030 <[^>]*> f392 6f04 li a3,37764 + 30: R_MIPS16_TLS_TPREL_LO16 var3 +00000034 <[^>]*> e820 jr ra +00000036 <[^>]*> 6500 nop +00000038 <[^>]*> 2407b1a3 li a3,-20061 + 38: R_MIPS_TLS_TPREL_HI16 var3 +0000003c <[^>]*> 24061234 li a2,4660 + 3c: R_MIPS_TLS_TPREL_HI16 var3 +00000040 <[^>]*> 2405b1a3 li a1,-20061 + 40: R_MIPS_TLS_DTPREL_HI16 var2 +00000044 <[^>]*> 24041234 li a0,4660 + 44: R_MIPS_TLS_DTPREL_HI16 var2 +00000048 <[^>]*> 2403b1a3 li v1,-20061 + 48: R_MIPS_HI16 var1 +0000004c <[^>]*> 03e00008 jr ra +00000050 <[^>]*> 24021234 li v0,4660 + 50: R_MIPS_HI16 var1 +00000054 <[^>]*> f1b6 6f03 li a3,45475 + 54: R_MIPS16_TLS_TPREL_HI16 var3 +00000058 <[^>]*> f222 6e14 li a2,4660 + 58: R_MIPS16_TLS_TPREL_HI16 var3 +0000005c <[^>]*> f1b6 6d03 li a1,45475 + 5c: R_MIPS16_TLS_DTPREL_HI16 var2 +00000060 <[^>]*> f222 6c14 li a0,4660 + 60: R_MIPS16_TLS_DTPREL_HI16 var2 +00000064 <[^>]*> f1b6 6b03 li v1,45475 + 64: R_MIPS16_HI16 var1 +00000068 <[^>]*> f222 6a14 li v0,4660 + 68: R_MIPS16_HI16 var1 +0000006c <[^>]*> e820 jr ra +0000006e <[^>]*> 6500 nop + \.\.\. diff --git a/gas/testsuite/gas/mips/mips16-tls-hilo-match.d b/gas/testsuite/gas/mips/mips16-tls-hilo-match.d new file mode 100644 index 00000000000..9e1b30a92a0 --- /dev/null +++ b/gas/testsuite/gas/mips/mips16-tls-hilo-match.d @@ -0,0 +1,31 @@ +#readelf: -Wr +#as: -mabi=32 -march=mips1 -mno-pdr +#name: MIPS and MIPS16 TLS HI/LO REL relocation matching +#source: mips-tls-hilo-match.s + +Relocation section '\.rel\.text' at offset .* contains 24 entries: + Offset Info Type Sym\. Value Symbol's Name +00000050 00000805 R_MIPS_HI16 00000000 var1 +00000000 00000806 R_MIPS_LO16 00000000 var1 +00000048 00000805 R_MIPS_HI16 00000000 var1 +00000004 00000806 R_MIPS_LO16 00000000 var1 +00000044 0000092c R_MIPS_TLS_DTPREL_HI16 00000000 var2 +00000008 0000092d R_MIPS_TLS_DTPREL_LO16 00000000 var2 +00000040 0000092c R_MIPS_TLS_DTPREL_HI16 00000000 var2 +0000000c 0000092d R_MIPS_TLS_DTPREL_LO16 00000000 var2 +0000003c 00000a31 R_MIPS_TLS_TPREL_HI16 00000000 var3 +00000010 00000a32 R_MIPS_TLS_TPREL_LO16 00000000 var3 +00000038 00000a31 R_MIPS_TLS_TPREL_HI16 00000000 var3 +00000018 00000a32 R_MIPS_TLS_TPREL_LO16 00000000 var3 +00000068 00000868 R_MIPS16_HI16 00000000 var1 +0000001c 00000869 R_MIPS16_LO16 00000000 var1 +00000064 00000868 R_MIPS16_HI16 00000000 var1 +00000020 00000869 R_MIPS16_LO16 00000000 var1 +00000060 0000096c R_MIPS16_TLS_DTPREL_HI16 00000000 var2 +00000024 0000096d R_MIPS16_TLS_DTPREL_LO16 00000000 var2 +0000005c 0000096c R_MIPS16_TLS_DTPREL_HI16 00000000 var2 +00000028 0000096d R_MIPS16_TLS_DTPREL_LO16 00000000 var2 +00000058 00000a6f R_MIPS16_TLS_TPREL_HI16 00000000 var3 +0000002c 00000a70 R_MIPS16_TLS_TPREL_LO16 00000000 var3 +00000054 00000a6f R_MIPS16_TLS_TPREL_HI16 00000000 var3 +00000030 00000a70 R_MIPS16_TLS_TPREL_LO16 00000000 var3