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>
|| 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);
--- /dev/null
+#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]+
--- /dev/null
+ .text
+ .global _start
+_start:
+ .dc.a foo
+ .data
+ .globl foo
+foo:
+ .byte 0
+
+ .section .note.GNU-stack
--- /dev/null
+ .data
+ .dc.a foo
+ .section .note.GNU-stack
"-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-*-*"] } {