]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
s390: Rewrite emitted relocations when rewriting instructions
authorJens Remus <jremus@linux.ibm.com>
Thu, 16 Oct 2025 09:06:17 +0000 (11:06 +0200)
committerJens Remus <jremus@linux.ibm.com>
Thu, 16 Oct 2025 09:06:17 +0000 (11:06 +0200)
When the linker rewrites instructions it may need to rewrite the
associated relocations, so that when emitted with option --emit-relocs,
they make sense with the rewritten instructions.  Otherwise post link
analysis and optimization tools may not be able to perform correct
modifications of executables.

Under certain conditions the linker rewrites:
- GOT access using lgrl to larl, changing the GOTENT to a PC32DBL reloc
- GOT access using lg to larl, changing the GOT20 to a PC32DBL reloc
- Relative long addressing instructions of weak symbols, which
  definitively resolve to zero, to either (1) load address of zero,
  (2) a NOP, or (3) a trapping instruction.

In case of a rewrite of GOT access using lgrl/lg to larl emit the
PC32DBL relocation.  In case of a rewrite of relative long addressing
instructions of weak symbols, which definitively resolve to zero, emit
a NONE relocation and reset the symbol table index and addend.  Update
the gotreloc* and weakundef* tests to check for the respective
relocations.

This aligns with how GNU linker behaves on x86-64, when rewriting
instructions/relocations in elf_x86_64_convert_load_reloc().

bfd/
* elf64-s390.c (elf_s390_relocate_section): Rewrite emitted
relocations when rewriting instructions.
* elf32-s390.c (elf_s390_relocate_section): Likewise.

ld/testsuite/
* ld-s390/s390.exp: Link gotreloc* and weakundef* tests with
option --emit-relocs.
* ld-s390/gotreloc_31-1.dd: Expect rewritten instructions to be
accompanied by a PC32DBL or NONE relocation respectively.
* ld-s390/gotreloc_31-no-pie-1.dd: Likewise.
* ld-s390/gotreloc_64-no-pie-1.dd: Likewise.
* ld-s390/gotreloc_64-norelro-1.dd: Likewise.
* ld-s390/gotreloc_64-relro-1.dd: Likewise.
* ld-s390/weakundef-1.dd: Likewise.
* ld-s390/weakundef-2.dd: Likewise.

Fixes: a63cc5f70ca6 ("Rewrite GOT accesses using larl if possible")
Fixes: 896a639babe2 ("s390: Avoid reloc overflows on undefined weak symbols")
Fixes: 6f8b365b653d ("s390: Avoid reloc overflows on undefined weak symbols (cont)")
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
bfd/elf32-s390.c
bfd/elf64-s390.c
ld/testsuite/ld-s390/gotreloc_31-1.dd
ld/testsuite/ld-s390/gotreloc_31-no-pie-1.dd
ld/testsuite/ld-s390/gotreloc_64-no-pie-1.dd
ld/testsuite/ld-s390/gotreloc_64-norelro-1.dd
ld/testsuite/ld-s390/gotreloc_64-relro-1.dd
ld/testsuite/ld-s390/s390.exp
ld/testsuite/ld-s390/weakundef-1.dd
ld/testsuite/ld-s390/weakundef-2.dd

index 56c613dd7d7f2ef67f2474351141170ce4d3a874..ce3faa023f3373af42dcdf26d0ee77aac88cbaea 100644 (file)
@@ -2282,6 +2282,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                      bfd_put_16 (output_bfd, new_insn,
                                  contents + rel->r_offset - 2);
                      r_type = R_390_PC32DBL;
+                     rel->r_info = ELF32_R_INFO (r_symndx, r_type);
                      rel->r_addend = 2;
                      howto = elf_howto_table + r_type;
                      relocation = h->root.u.def.value
index 555395ca5ad557827b6715e36763696d378e5b47..af36e192f59da82e0ed3844093c0a6e3117de66a 100644 (file)
@@ -2545,6 +2545,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                      bfd_put_16 (output_bfd, new_insn,
                                  contents + rel->r_offset - 2);
                      r_type = R_390_PC32DBL;
+                     rel->r_info = ELF64_R_INFO (r_symndx, r_type);
                      rel->r_addend = 2;
                      howto = elf_howto_table + r_type;
                      relocation = h->root.u.def.value
@@ -2685,6 +2686,8 @@ elf_s390_relocate_section (bfd *output_bfd,
                      /* larl rX,<weak sym> -> lay rX,0(0)  */
                      bfd_put_16 (output_bfd, 0xe300 | reg, insn_start);
                      bfd_put_32 (output_bfd, 0x71, insn_start + 2);
+                     rel->r_info = ELF64_R_INFO (0, R_390_NONE);
+                     rel->r_addend = 0;
                      continue;
                    }
                  /* Replace branch relative and save long (brasl) with a trap.  */
@@ -2693,6 +2696,8 @@ elf_s390_relocate_section (bfd *output_bfd,
                      /* brasl rX,<weak sym> -> jg .+2 (6-byte trap)  */
                      bfd_put_16 (output_bfd, 0xc0f4, insn_start);
                      bfd_put_32 (output_bfd, 0x1, insn_start + 2);
+                     rel->r_info = ELF64_R_INFO (0, R_390_NONE);
+                     rel->r_addend = 0;
                      continue;
                    }
                }
@@ -2797,6 +2802,8 @@ elf_s390_relocate_section (bfd *output_bfd,
                  /* larl rX,<weak sym> -> lay rX,0(0)  */
                  bfd_put_16 (output_bfd, 0xe300 | reg, insn_start);
                  bfd_put_32 (output_bfd, 0x71, insn_start + 2);
+                 rel->r_info = ELF64_R_INFO (0, R_390_NONE);
+                 rel->r_addend = 0;
                  continue;
                }
              /* Replace prefetch data relative long (pfdrl) with a NOP  */
@@ -2805,6 +2812,8 @@ elf_s390_relocate_section (bfd *output_bfd,
                  /* Emit a 6-byte NOP: jgnop .  */
                  bfd_put_16 (output_bfd, 0xc004, insn_start);
                  bfd_put_32 (output_bfd, 0x0, insn_start + 2);
+                 rel->r_info = ELF64_R_INFO (0, R_390_NONE);
+                 rel->r_addend = 0;
                  continue;
                }
              /* Replace the following instructions with a trap:
@@ -2822,6 +2831,8 @@ elf_s390_relocate_section (bfd *output_bfd,
                  /* Emit a 6-byte trap: jg .+2  */
                  bfd_put_16 (output_bfd, 0xc0f4, insn_start);
                  bfd_put_32 (output_bfd, 0x1, insn_start + 2);
+                 rel->r_info = ELF64_R_INFO (0, R_390_NONE);
+                 rel->r_addend = 0;
                  continue;
                }
            }
index b1cf37c54d622b3fc1dccb9a2dd46e231a745bf4..d04e1e5009158d0e29c62c137a1e36939b7394b5 100644 (file)
@@ -5,9 +5,16 @@ Disassembly of section .text:
 
 .* <foo>:
 .*:    c4 18 00 00 08 56 [      ]*lgrl %r1,11b4 <_GLOBAL_OFFSET_TABLE_\+0x14>
+[       ]*.*: R_390_GOTENT     bar\+0x2
 .*:    e3 10 c0 14 00 04 [      ]*lg   %r1,20\(%r12\)
+[       ]*.*: R_390_GOT20      bar
 .*:    c0 10 00 00 08 52 [      ]*larl %r1,11b8 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    58 10 c0 14 [    ]*l    %r1,20\(%r12\)
+[       ]*.*: R_390_GOT12      bar
 .*:    c0 10 00 00 08 4d [      ]*larl %r1,11b8 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c4 18 00 00 08 46 [      ]*lgrl %r1,11b0 <_GLOBAL_OFFSET_TABLE_\+0x10>
+[       ]*.*: R_390_GOTENT     _GLOBAL_OFFSET_TABLE_\+0x2
 .*:    c4 18 00 00 08 41 [      ]*lgrl %r1,11ac <_GLOBAL_OFFSET_TABLE_\+0xc>
+[       ]*.*: R_390_GOTENT     misaligned_sym\+0x2
index 2e0d2cda87b490ffca06bba43b40b5bcf4743ba7..dd2c474b755ab4fc76115dfa2476c03299e9b7fe 100644 (file)
@@ -5,9 +5,16 @@ Disassembly of section .text:
 
 .* <foo>:
 .*:    c4 18 00 00 08 1e [      ]*lgrl %r1,4010b0 <_GLOBAL_OFFSET_TABLE_\+0x14>
+[       ]*.*: R_390_GOTENT     bar\+0x2
 .*:    e3 10 c0 14 00 04 [      ]*lg   %r1,20\(%r12\)
+[       ]*.*: R_390_GOT20      bar
 .*:    c0 10 00 00 08 1a [      ]*larl %r1,4010b4 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    58 10 c0 14 [    ]*l    %r1,20\(%r12\)
+[       ]*.*: R_390_GOT12      bar
 .*:    c0 10 00 00 08 15 [      ]*larl %r1,4010b4 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c4 18 00 00 08 0e [      ]*lgrl %r1,4010ac <_GLOBAL_OFFSET_TABLE_\+0x10>
+[       ]*.*: R_390_GOTENT     _GLOBAL_OFFSET_TABLE_\+0x2
 .*:    c4 18 00 00 08 09 [      ]*lgrl %r1,4010a8 <_GLOBAL_OFFSET_TABLE_\+0xc>
+[       ]*.*: R_390_GOTENT     misaligned_sym\+0x2
index 751b7a8de6d69f3d958bc67de834593b7495bb40..57537aeecd885bc83cef657912144b3634136020 100644 (file)
@@ -4,9 +4,16 @@ Disassembly of section .text:
 
 .* <foo>:
 .*:    c0 10 00 00 08 2c [      ]*larl %r1,1001108 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c0 10 00 00 08 29 [      ]*larl %r1,1001108 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c4 1d 00 00 08 22 [      ]*lrl  %r1,1001100 <_GLOBAL_OFFSET_TABLE_\+0x28>
+[       ]*.*: R_390_GOTENT     bar\+0x2
 .*:    58 10 c0 28 [    ]*l    %r1,40\(%r12\)
+[       ]*.*: R_390_GOT12      bar
 .*:    e3 10 c0 28 00 58 [      ]*ly   %r1,40\(%r12\)
+[       ]*.*: R_390_GOT20      bar
 .*:    c4 18 00 00 08 16 [      ]*lgrl %r1,10010f8 <_GLOBAL_OFFSET_TABLE_\+0x20>
+[       ]*.*: R_390_GOTENT     _GLOBAL_OFFSET_TABLE_\+0x2
 .*:    c4 18 00 00 08 0f [      ]*lgrl %r1,10010f0 <_GLOBAL_OFFSET_TABLE_\+0x18>
+[       ]*.*: R_390_GOTENT     misaligned_sym\+0x2
index 8debd975d07dea8881ed57b0332200309f446cb6..eece724d217cd76d1530d7172417b638557afdc5 100644 (file)
@@ -4,9 +4,16 @@ Disassembly of section .text:
 
 .* <foo>:
 .*:    c0 10 00 00 08 9c [      ]*larl %r1,12e8 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c0 10 00 00 08 99 [      ]*larl %r1,12e8 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c4 1d 00 00 08 92 [      ]*lrl  %r1,12e0 <_GLOBAL_OFFSET_TABLE_\+0x28>
+[       ]*.*: R_390_GOTENT     bar\+0x2
 .*:    58 10 c0 28 [    ]*l    %r1,40\(%r12\)
+[       ]*.*: R_390_GOT12      bar
 .*:    e3 10 c0 28 00 58 [      ]*ly   %r1,40\(%r12\)
+[       ]*.*: R_390_GOT20      bar
 .*:    c4 18 00 00 08 86 [      ]*lgrl %r1,12d8 <_GLOBAL_OFFSET_TABLE_\+0x20>
+[       ]*.*: R_390_GOTENT     _GLOBAL_OFFSET_TABLE_\+0x2
 .*:    c4 18 00 00 08 7f [      ]*lgrl %r1,12d0 <_GLOBAL_OFFSET_TABLE_\+0x18>
+[       ]*.*: R_390_GOTENT     misaligned_sym\+0x2
index 64151d10a7c8aadf246cb560280dca584453cbd6..7cb11940f8e3f05aea8391bb945f06cd3cfb9e8d 100644 (file)
@@ -4,9 +4,16 @@ Disassembly of section .text:
 
 .* <foo>:
 .*:    c0 10 00 00 0f 0c [      ]*larl %r1,2000 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c0 10 00 00 0f 09 [      ]*larl %r1,2000 <bar>
+[       ]*.*: R_390_PC32DBL    bar\+0x2
 .*:    c4 1d 00 00 0f 02 [      ]*lrl  %r1,1ff8 <_GLOBAL_OFFSET_TABLE_\+0x28>
+[       ]*.*: R_390_GOTENT     bar\+0x2
 .*:    58 10 c0 28 [    ]*l    %r1,40\(%r12\)
+[       ]*.*: R_390_GOT12      bar
 .*:    e3 10 c0 28 00 58 [      ]*ly   %r1,40\(%r12\)
+[       ]*.*: R_390_GOT20      bar
 .*:    c4 18 00 00 0e f6 [      ]*lgrl %r1,1ff0 <_GLOBAL_OFFSET_TABLE_\+0x20>
+[       ]*.*: R_390_GOTENT     _GLOBAL_OFFSET_TABLE_\+0x2
 .*:    c4 18 00 00 0e ef [      ]*lgrl %r1,1fe8 <_GLOBAL_OFFSET_TABLE_\+0x18>
+[       ]*.*: R_390_GOTENT     misaligned_sym\+0x2
index 452811dcb2ba5bb4f06bfa127ddf031ea9495d33..27a1b346fe7cfe3feea495799be8fe5be7f42ae1 100644 (file)
@@ -50,12 +50,12 @@ set s390tests {
       {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
      "tlsbin"}
     {"GOT: symbol address load from got to larl"
-     "-shared -melf_s390 --hash-style=sysv --version-script=gotreloc-1.ver" ""
+     "-shared -melf_s390 --hash-style=sysv --version-script=gotreloc-1.ver --emit-relocs" ""
      "-m31" {gotreloc-1.s}
      {{objdump -dzrj.text gotreloc_31-1.dd}}
      "gotreloc_31-1"}
     {"GOT: no-pie symbol address load from got to larl"
-     "-shared -melf_s390 --no-pie --hash-style=sysv --version-script=gotreloc-1.ver" ""
+     "-shared -melf_s390 --no-pie --hash-style=sysv --version-script=gotreloc-1.ver --emit-relocs" ""
      "-m31" {gotreloc-1.s}
      {{objdump -dzrj.text gotreloc_31-no-pie-1.dd}}
      "gotreloc_31-1"}
@@ -88,17 +88,17 @@ set s390xtests {
       {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}}
      "tlsbin_64"}
     {"GOT: norelro symbol address load from got to larl"
-     "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" ""
+     "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver --emit-relocs" ""
      "-m64" {gotreloc-1.s}
      {{objdump -dzrj.text gotreloc_64-norelro-1.dd}}
      "gotreloc_64-1"}
     {"GOT: relro symbol address load from got to larl"
-     "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" ""
+     "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver --emit-relocs" ""
      "-m64" {gotreloc-1.s}
      {{objdump -dzrj.text gotreloc_64-relro-1.dd}}
      "gotreloc_64-1"}
     {"GOT: no-pie symbol address load from got to larl"
-     "-shared -melf64_s390 --no-pie --hash-style=sysv --version-script=gotreloc-1.ver" ""
+     "-shared -melf64_s390 --no-pie --hash-style=sysv --version-script=gotreloc-1.ver --emit-relocs" ""
      "-m64" {gotreloc-1.s}
      {{objdump -dzrj.text gotreloc_64-no-pie-1.dd}}
      "gotreloc_64-1"}
@@ -108,10 +108,10 @@ set s390xtests {
      {{objdump "-dzrj.text --stop-address=16" pltoffset-1.dd}}
      "pltoffset-1"}
     {"WEAKUNDEF1: overflow test (PC32DBL)"
-     "-m elf64_s390 -dT 8GB.ld --no-error-rwx-segments" "" "-m64" {weakundef-1.s}
+     "-m elf64_s390 -dT 8GB.ld --emit-relocs --no-error-rwx-segments" "" "-m64" {weakundef-1.s}
      {{objdump "-dzrj.text" weakundef-1.dd}} "weakundef-1"}
     {"WEAKUNDEF2: overflow test (PLT32DBL)"
-     "-m elf64_s390 -dT 8GB.ld --no-error-rwx-segments -no-pie" "" "-m64" {weakundef-2.s}
+     "-m elf64_s390 -dT 8GB.ld --emit-relocs --no-error-rwx-segments -no-pie" "" "-m64" {weakundef-2.s}
      {{objdump "-dzrj.text" weakundef-2.dd}} "weakundef-2"}
     {"Helper shared library (PLT test)"
      "-shared -m elf64_s390" "" "-m64" {pltlib.s}
index 04d53c91d58e8866d257d70459beba4537745672..3dd25c7d284e519d48756a4d9fa29af4ac39ee2d 100644 (file)
@@ -4,12 +4,21 @@ Disassembly of section .text:
 
 .* <foo>:
 .*:    c0 10 00 00 00 1c [      ]*larl %r1,200000038 <d>
+[       ]*.*: R_390_PC32DBL    \.data\+0x2
 .*:    c0 10 00 00 00 1d [      ]*larl %r1,200000040 <wd>
+[       ]*.*: R_390_PC32DBL    wd\+0x2
 .*:    e3 10 00 00 00 71 [      ]*lay  %r1,0
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 f4 00 00 00 01 [      ]*jg   .*
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 f4 00 00 00 01 [      ]*jg   .*
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 f4 00 00 00 01 [      ]*jg   .*
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 f4 00 00 00 01 [      ]*jg   .*
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 f4 00 00 00 01 [      ]*jg   .*
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 04 00 00 00 00 [      ]*jgnop        .*
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    07 07 [  ]*nopr %r7
index e7f0e2239b6aa12ecf44cacd244d242372ed0789..e586ff2e28c98d172648f5427576c4ef6c9c3b99 100644 (file)
@@ -4,11 +4,17 @@ Disassembly of section .text:
 
 0+200000000 <foo>:
 .*:    c0 10 00 00 00 12 [      ]*larl %r1,200000024 <d>
+[       ]*.*: R_390_PLT32DBL   d\+0x2
 .*:    c0 10 00 00 00 10 [      ]*larl %r1,200000026 <wd>
+[       ]*.*: R_390_PLT32DBL   wd\+0x2
 .*:    e3 10 00 00 00 71 [      ]*lay  %r1,0
+[       ]*.*: R_390_NONE       \*ABS\*
 .*:    c0 e5 00 00 00 09 [      ]*brasl        %r14,200000024 <d>
+[       ]*.*: R_390_PLT32DBL   d\+0x2
 .*:    c0 e5 00 00 00 07 [      ]*brasl        %r14,200000026 <wd>
+[       ]*.*: R_390_PLT32DBL   wd\+0x2
 .*:    c0 f4 00 00 00 01 [      ]*jg   .*
+[       ]*.*: R_390_NONE       \*ABS\*
 
 0+200000024 <d>:
 .*:    07 fe [  ]*br   %r14