]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
s390: Bind defined symbol locally in PIE
authorJens Remus <jremus@linux.ibm.com>
Fri, 7 Nov 2025 16:09:55 +0000 (17:09 +0100)
committerJens Remus <jremus@linux.ibm.com>
Fri, 7 Nov 2025 16:09:55 +0000 (17:09 +0100)
Symbols defined in PIE should be bound locally, the same as -shared
-Bsymbolic.

Port x86 commit 4e0c91e45402 ("Bind defined symbol locally in PIE")
change of relocate_section as well as linker tests to s390.  Similar as
done for other architectures with the following commits:
- AArch64: ac33b731d214 ("[AArch64] Bind defined symbol locally in PIE")
- ARM: 1dcb9720d62c ("[ARM] Bind defined symbol locally in PIE")
- RISC-V: 39c7793ba8be ("RISC-V: Bind defined symbol locally in PIE")
- x86: 4e0c91e45402 ("Bind defined symbol locally in PIE")
With this change symbols defined in an executable (i.e. PDE or PIE) are
bound locally, as they cannot be interposed.  In the same way as symbols
defined in a shared library linked with -Bsymbolic are bound locally.

This also ensures that all defined symbols are bound locally in
static PIE.

Do not port the x86 change of check_relocs (now scan_relocs).  None of
the linker tests where the change in condition triggers (e.g. bootstrap,
cdtest) produce different readelf -Wa output.  The change appears to
affect accounting of space required for dynamic relocations.  Instead of
accounting them in check_relocs and later filtering them away in
allocate_dynrelocs, they would not get accounted in the first place:
The change in the expression would only have an effect if the following
conditions are all met in addition to PIE:  ALLOC, PC-relative
relocation, global symbol, not defined weak, and defined regular.  In
this specific case the accounting of the PC relative relocation in
h->dyn_relocs would be skipped for PIE.  But allocate_dynrelocs later
eliminates any PC-relative dynamic relocations if PIC (= PIE or shared
library) and SYMBOL_CALLS_LOCAL.

bfd/
PR ld/33141
* elf64-s390.c (elf_s390_relocate_section): Bind defined symbol
locally in PIE.

ld/testsuite/
PR ld/33141
* ld-s390/s390.exp: Add pr33141 tests.
* ld-s390/pr33141.rd: New file.
* ld-s390/pr33141a.s: Likewise.
* ld-s390/pr33141b.s: Likewise.

Signed-off-by: Jens Remus <jremus@linux.ibm.com>
bfd/elf64-s390.c
ld/testsuite/ld-s390/pr33141.rd [new file with mode: 0644]
ld/testsuite/ld-s390/pr33141a.s [new file with mode: 0644]
ld/testsuite/ld-s390/pr33141b.s [new file with mode: 0644]
ld/testsuite/ld-s390/s390.exp

index 96ba8b3cd77ef1bde8cc96c0602b0d4f86a2c8b5..2508769f9bfd0887ee3bb541641e2e31d4379173 100644 (file)
@@ -2973,8 +2973,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                           || r_type == R_390_PC32
                           || r_type == R_390_PC32DBL
                           || r_type == R_390_PC64
-                          || !bfd_link_pic (info)
-                          || !SYMBOLIC_BIND (info, h)
+                          || !(bfd_link_executable (info) || SYMBOLIC_BIND (info, h))
                           || !h->def_regular))
                {
                  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
diff --git a/ld/testsuite/ld-s390/pr33141.rd b/ld/testsuite/ld-s390/pr33141.rd
new file mode 100644 (file)
index 0000000..7c7d277
--- /dev/null
@@ -0,0 +1,5 @@
+#readelf: -r --wide
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_390_RELATIVE +[0-9a-f]+
diff --git a/ld/testsuite/ld-s390/pr33141a.s b/ld/testsuite/ld-s390/pr33141a.s
new file mode 100644 (file)
index 0000000..43241f5
--- /dev/null
@@ -0,0 +1,10 @@
+       .text
+       .global _start
+_start:
+       .dc.a foo
+       .data
+       .globl foo
+foo:
+       .byte 0
+
+       .section        .note.GNU-stack
diff --git a/ld/testsuite/ld-s390/pr33141b.s b/ld/testsuite/ld-s390/pr33141b.s
new file mode 100644 (file)
index 0000000..897c149
--- /dev/null
@@ -0,0 +1,3 @@
+       .data
+       .dc.a foo
+       .section        .note.GNU-stack
index eaf74c4c2347d6051305b829b8606e53321f029b..014754f94862d00c1cc739ed43ed0d1cfe2a860a 100644 (file)
@@ -158,6 +158,20 @@ set s390xtests {
      "-m elf64_s390" "" "-m64" {pr32969a.s pr32969c.s pr32969b.s}
      {{objdump "-dzrj.text" pr32969_64-2.dd}}
      "pr32969_64-2"}
+    {"Build pr33141a.o"
+     "" "" "-m64" { pr33141a.s }}
+    {"Build pr33141b.so"
+     "-m elf64_s390 -shared" "" "-m64" { pr33141b.s }
+     {}
+     "pr33141b.so"}
+    {"Build pr33141"
+     "-m elf64_s390 -pie -z notext tmpdir/pr33141a.o tmpdir/pr33141b.so" "" "-m64" {}
+     {{readelf {-rW} pr33141.rd}}
+     "pr33141"}
+    {"Build pr33141.so"
+     "-m elf64_s390 -shared -Bsymbolic -z notext" "" "-m64" { pr33141a.s }
+     {{readelf {-rW} pr33141.rd}}
+     "pr33141.so"}
 }
 
 if { [istarget "s390-*-*"] || [istarget "s390x-*-*"] } {