MIPS/BFD: Fix RELA handling of borrow in the generic linker

Fix an issue with `_bfd_mips_elf_generic_reloc' not taking into account
any borrow from the lower part in the handling of relocations of the
HI/LO kind and resulting in incorrect calculations made for RELA targets
in the generic used for non-ELF output such as S-records.  This doesn't
trigger for REL targets because they call `_bfd_mips_elf_generic_reloc'
indirectly from `_bfd_mips_elf_lo16_reloc' so as to obtain a complete
32-bit addend from relocation pairs and in calculating the addend the
latter function uses a hack to work around the lack of borrow handling
in the former function.

The MIPS/ELF linker is unaffected as it uses its own calculations.

Correct the calculation of the relevant partial relocations made in
`_bfd_mips_elf_generic_reloc' then to take the borrow into account and
remove the hack from `_bfd_mips_elf_lo16_reloc' as no longer needed.

Add generic linker test cases accordingly expecting the same disassembly
from srec output produced as from ELF output produced by the MIPS/ELF
linker.
This commit is contained in:
Maciej W. Rozycki
2025-07-06 19:22:49 +01:00
parent ae236b71ea
commit ce08b3bb19
18 changed files with 138 additions and 18 deletions

View File

@@ -6,9 +6,9 @@
#ld: -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
.*: file format elf.*mips.*
.*: file format (:?elf.*mips.*|srec)
Disassembly of section \.text:
Disassembly of section \.(:?text|sec1):
0*500000 <[^>]*>:
*500000: 41a1 0000 lui at,0x0

View File

@@ -0,0 +1,8 @@
#name: R_MICROMIPS_HI16 and R_MICROMIPS_LO16 relocs srec n32
#source: ../../../gas/testsuite/gas/mips/mips-hilo.s
#source: mips-hilo.s
#as: -mmicromips -march=mips64r2
#objdump: -m mips:micromips -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
#dump: micromips-hilo.d

View File

@@ -0,0 +1,8 @@
#name: R_MICROMIPS_HI16 and R_MICROMIPS_LO16 relocs srec n64
#source: ../../../gas/testsuite/gas/mips/mips-hilo-n64.s
#source: mips-hilo.s
#as: -mmicromips -march=mips64r2
#objdump: -m mips:micromips -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
#dump: micromips-hilo-n64.d

View File

@@ -0,0 +1,8 @@
#name: R_MICROMIPS_HI16 and R_MICROMIPS_LO16 relocs srec
#source: ../../../gas/testsuite/gas/mips/mips-hilo.s
#source: mips-hilo.s
#as: -mmicromips -march=mips32r2
#objdump: -m mips:micromips -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
#dump: micromips-hilo.d

View File

@@ -6,9 +6,9 @@
#ld: -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
.*: file format elf.*mips.*
.*: file format (:?elf.*mips.*|srec)
Disassembly of section \.text:
Disassembly of section \.(:?text|sec1):
0*500000 <[^>]*>:
*500000: 41a4 0000 lui a0,0x0

View File

@@ -816,14 +816,41 @@ run_dump_test "mode-change-error-1"
run_dump_test_o32 "mips16-hilo" noarch
run_dump_test_n32 "mips16-hilo-n32" noarch
run_dump_test_o32 "mips16-hilo-srec" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_n32 "mips16-hilo-srec-n32" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_o32 "mips16e2-hilo" noarch
run_dump_test_n32 "mips16e2-hilo-n32" noarch
run_dump_test_o32 "mips16e2-hilo-srec" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_n32 "mips16e2-hilo-srec-n32" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_o32 "mips-hilo"
run_dump_test_n32 "mips-hilo-n32"
run_dump_test_n64 "mips-hilo-n64"
run_dump_test_o32 "mips-hilo-srec" \
[list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_n32 "mips-hilo-srec-n32" \
[list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_n64 "mips-hilo-srec-n64" \
[list [list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_o32 "micromips-hilo" noarch
run_dump_test_n32 "micromips-hilo-n32" noarch
run_dump_test_n64 "micromips-hilo-n64" noarch
run_dump_test_o32 "micromips-hilo-srec" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_n32 "micromips-hilo-srec-n32" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
run_dump_test_n64 "micromips-hilo-srec-n64" \
[list noarch \
[list objdump [expr { [istarget *el-*-*] ? "-EL" : "-EB" }]]]
if { $linux_gnu } {
run_dump_test_n32 "textrel-1"

View File

@@ -4,9 +4,9 @@
#objdump: -d
#ld: -Tmips-hilo.ld -e 0x500000 -N
.*: file format elf.*mips.*
.*: file format (:?elf.*mips.*|srec)
Disassembly of section \.text:
Disassembly of section \.(:?text|sec1):
0*500000 <[^>]*>:
*500000: 3c010000 lui at,0x0

View File

@@ -0,0 +1,6 @@
#name: R_MIPS_HI16 and R_MIPS_LO16 relocs srec n32
#source: ../../../gas/testsuite/gas/mips/mips-hilo.s
#source: mips-hilo.s
#objdump: -m mips:4000 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#dump: mips-hilo.d

View File

@@ -0,0 +1,6 @@
#name: R_MIPS_HI16 and R_MIPS_LO16 relocs srec n64
#source: ../../../gas/testsuite/gas/mips/mips-hilo-n64.s
#source: mips-hilo.s
#objdump: -m mips:4000 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#dump: mips-hilo-n64.d

View File

@@ -0,0 +1,6 @@
#name: R_MIPS_HI16 and R_MIPS_LO16 relocs srec
#source: ../../../gas/testsuite/gas/mips/mips-hilo.s
#source: mips-hilo.s
#objdump: -m mips:3000 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#dump: mips-hilo.d

View File

@@ -4,9 +4,9 @@
#objdump: -d
#ld: -Tmips-hilo.ld -e 0x500000 -N
.*: file format elf.*mips.*
.*: file format (:?elf.*mips.*|srec)
Disassembly of section \.text:
Disassembly of section \.(:?text|sec1):
0*500000 <[^>]*>:
*500000: 3c040000 lui a0,0x0

View File

@@ -0,0 +1,7 @@
#name: R_MIPS16_HI16 and R_MIPS16_LO16 relocs srec n32
#source: ../../../gas/testsuite/gas/mips/mips16-hilo.s
#source: mips-hilo.s
#as: -march=mips3
#objdump: -mmips:16 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#dump: mips16-hilo.d

View File

@@ -0,0 +1,7 @@
#name: R_MIPS16_HI16 and R_MIPS16_LO16 relocs srec
#source: ../../../gas/testsuite/gas/mips/mips16-hilo.s
#source: mips-hilo.s
#as: -march=mips1
#objdump: -mmips:16 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#dump: mips16-hilo.d

View File

@@ -5,9 +5,9 @@
#objdump: -mmips:16 -dr
#ld: -Tmips-hilo.ld -e 0x500000 -N
.*: file format elf.*mips.*
.*: file format (:?elf.*mips.*|srec)
Disassembly of section .text:
Disassembly of section \.(:?text|sec1):
0*500000 <[^>]*>:
*500000: 6c00 li a0,0

View File

@@ -0,0 +1,8 @@
#name: MIPS16e2 R_MIPS16_HI16 and R_MIPS16_LO16 relocs srec n32
#source: ../../../gas/testsuite/gas/mips/mips-hilo.s
#source: mips-hilo.s
#as: -mips16 -mmips16e2 -march=mips64r2
#objdump: -mmips:16 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
#dump: mips16e2-hilo.d

View File

@@ -0,0 +1,8 @@
#name: MIPS16e2 R_MIPS16_HI16 and R_MIPS16_LO16 relocs srec
#source: ../../../gas/testsuite/gas/mips/mips-hilo.s
#source: mips-hilo.s
#as: -mips16 -mmips16e2 -march=mips32r2
#objdump: -mmips:16 -j .sec1 -D
#ld: --oformat=srec -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
#dump: mips16e2-hilo.d

View File

@@ -6,9 +6,9 @@
#ld: -Tmips-hilo.ld -e 0x500000 -N
#notarget: mips*el-ps2-elf*
.*: file format elf.*mips.*
.*: file format (:?elf.*mips.*|srec)
Disassembly of section \.text:
Disassembly of section \.(:?text|sec1):
0*500000 <[^>]*>:
*500000: f000 6c20 lui a0,0x0