Bind defined symbol locally in PIE (was: [Bug ld/33141] unresolved relocations in -static-pie binaries on s390x (and probably others))
Jens Remus
jremus@linux.ibm.com
Thu Jul 24 11:04:09 GMT 2025
Hello H.J., et al.,
I am porting the x86-64 change from your x86 commit 4e0c91e45402 ("Bind
defined symbol locally in PIE") to s390 for PR 33141.
The change in elf_x86_64_relocate_section is clear to me. The change
to elf_x86_64_check_relocs (now scan_relocs) is not.
Other architectures that supposedly ported your fix (see list of commits
in forwarded PR update below) did only change relocate_section.
If you happen to recall the reason for your change to check_relocs
(now scan_relocs) I would be very grateful if you could share your
thoughts with me. Same if enybody else could enlighten me.
The PR also questions whether the fix/optimization could not better
be implemented in a generic way, for instance to change SYMBOLIC_BIND.
I don't feel like I am there yet to tackle that. Anybody else (H.J.,
Alan, Jan, ...)?
Thanks and regards,
Jens
-------- Forwarded Message --------
Subject: [Bug ld/33141] unresolved relocations in -static-pie binaries on s390x (and probably others)
Date: Thu, 24 Jul 2025 09:14:49 +0000
From: jremus at linux dot ibm.com <sourceware-bugzilla@sourceware.org>
To: bug-binutils@gnu.org
https://sourceware.org/bugzilla/show_bug.cgi?id=33141
--- Comment #1 from Jens Remus <jremus at linux dot ibm.com> ---
I reviewed the bug, the referenced Alpine issue, the referenced fixes, and did
some research. My understanding is as follows:
Binding defined local symbols in (static) PIE dynamically is not a bug per se.
It results in dynamic relocations for those local symbols, which Glibc and musl
(at lest for PIE) can apparently resolve. It would be a valid optimization
though to bind defined local symbols in (static) PIE locally, which results in
`R_*_RELATIVE` relocations, as ELF does not allow for defined local symbol
interposition in executables at all (neither PDE nor PIE):
> The executable is always the first element of the search list,
> so a defined symbol of any binding in the executable cannot be
> preempted (interposed).
Source: Fangrui Song, ELF interposition and -Bsymbolic,
https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic
This would result in a more optimal executable, as the defined local symbols
are then bound at link-time, so that the loader does not have to the perform
the symbol lookup. Additionally this would resolve the issue that musl cannot
lacks the capability to resolve dynamic relocations in static PIE.
Using the provided references to existing commits I found the following
architectures to have "fixed" the issue:
- AArch64: ac33b731d214 ("[AArch64] Bind defined symbol locally in PIE")
https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=ac33b731d214
- ARM: 1dcb9720d62c ("[ARM] Bind defined symbol locally in PIE")
https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=1dcb9720d62c
- RISC-V: 39c7793ba8be ("RISC-V: Bind defined symbol locally in PIE")
https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=39c7793ba8be
- x86: 4e0c91e45402 ("Bind defined symbol locally in PIE")
https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=4e0c91e45402
Reviewing the x86 commit 4e0c91e45402 ("Bind defined symbol locally in PIE") I
understand the purpose of the following change in elf_x86_64_relocate_section.
It prevents a dynamic relocation from being emitted for executables just
because option `-Bsymbolic` is not specified, which AFAIK cannot be specified
for an executable. The other architecture fixes also have this, but in a
slightly diffrerent minimal version, that only replaces the `!SYMBOLIC_BIND
(info, h)` with `!(bfd_link_pie (info) || SYMBOLIC_BIND (info, h))`.
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
@@ -4830,8 +4831,8 @@ direct:
else if (h != NULL
&& h->dynindx != -1
&& (IS_X86_64_PCREL_TYPE (r_type)
- || ! bfd_link_pic (info)
- || ! SYMBOLIC_BIND (info, h)
+ || !(bfd_link_executable (info)
+ || SYMBOLIC_BIND (info, h))
|| ! h->def_regular))
{
if ((r_type != R_X86_64_PC64 && r_type != R_X86_64_64)
But I have issues to understand the purpose of the following change in
elf_x86_64_check_relocs (now scan_relocs). For test purposes I reverted that
change on master as well as on 4e0c91e45402 and ran the x86 linker tests
(x86-64 cross build on s390x though). None of the tests failed, that could have
provided some further insight. None of the other architecture fixes have this.
Did they come to the conclusion this change is superfluous?
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
@@ -2073,7 +2073,8 @@ do_size:
&& (sec->flags & SEC_ALLOC) != 0
&& (! IS_X86_64_PCREL_TYPE (r_type)
|| (h != NULL
- && (! SYMBOLIC_BIND (info, h)
+ && (! (bfd_link_pie (info)
+ || SYMBOLIC_BIND (info, h))
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
As for resolving this PR I have a patch in my pipeline that ports the obvious
x86 change to s390, including the tests, and can confirm this relaxes the
dynamic relocations for local symbols to `R_390_RELATIVE`. Maybe H.J. Lu can
provide more insights on his second change in his patch?
I won't attempt a generic fix, for instance changing SYMBOLIC_BIND as suggested
to include a test for `!bfd_link_executable (info)`. Please open a separate PR
for that.
--
Jens Remus
Linux on Z Development (D3303)
+49-7031-16-1128 Office
jremus@de.ibm.com
IBM
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
More information about the Binutils
mailing list