[PATCH v4] s390: Only use canonical PLT for non-PIC code taking address in PDE

Jens Remus jremus@linux.ibm.com
Fri Mar 27 16:46:45 GMT 2026


On 3/23/2026 4:43 PM, Jens Remus wrote:
> Fix incorrect use of canonical PLT in position-dependent executables
> (PDE) that violated pointer equality.  The linker must distinguish
> between non-PIC code linked as PDE (which requires canonical PLT for
> pointer equality) and PIC code linked as PDE (which must not use
> canonical PLT).  This is determined by examining relocations, not just
> the executable type (PIE vs. PDE).
> 
> Canonical PLT entries are needed only when non-PIC code takes function
> addresses.  Non-PIC code uses absolute addresses and assumes all
> addresses are known at link time.  When such code both calls and takes
> the address of a shared library function, the linker creates a canonical
> PLT entry (setting the symbol's value to the PLT stub address) to ensure
> all references use the same address, maintaining pointer equality.
> 
> However, PIC code uses GOT-indirect addressing for function pointers.
> When PIC code takes a function's address, it loads from the GOT, which
> the dynamic linker resolves to the actual function address in the shared
> library.  Using canonical PLT in this case is wrong, as it forces all
> GOT entries to point to the PLT stub, breaking pointer equality when the
> shared library compares function addresses internally.
> 
> Require pointer equality in PDE for symbols with non-PLT PC-relative
> relocations, that are likely in address taken context, and direct
> relocations, that are likely in function reference context.  Do so
> for IFUNC symbols defined in a non-shared object.  Clear value of PLT
> undefined symbols if pointer equality is not needed and do not hash them
> in '.gnu.hash' section.
> 
> As workaround for GCC 12-14 treat PC32DBL relocation for address taking
> instruction "larl rX,<sym>@PLT" as if it was without @PLT suffix and
> require pointer equality.  This ensures correct behavior even when the
> compiler incorrectly marks address-taking instructions with @PLT.
> GCC 12-14, since GCC commit 0990d93dd8a4 ("IBM Z: Use @PLT symbols for
> local functions in 64-bit mode") [1], unconditionally suffix non-local
> symbols with @PLT, regardless of whether they are used in function call
> instructions (i.e. brasl) or address taking instructions (i.e. larl).
> The assembler therefore generates a PLT32DBL instead of a PC32DBL
> relocation for larl.  The linker therefore cannot distinguish between
> function call and address taking instructions solely from the relocation
> type.  The latter requiring pointer equality.
> This complements GCC commit a2e0a30c52fa ("IBM zSystems: Do not use
> @PLT with larl") [2], which makes GCC stop suffixing @PLT to address
> taking larl instructions, so that the correct behavior with regards to
> pointer equality is also achieved with affected GCC 12-14.
> Note that this workaround can be reverted once GCC 12-14 emitting
> address taking larl instructions with @PLT suffix have become
> irrelevant.
> 
> Note that without the workaround for GCC 12-14 suffixing @PLT to larl
> the following linker tests would fail:
> 
>   FAIL: shared
>   FAIL: visibility (hidden_normal)
>   FAIL: visibility (hidden_weak)
>   FAIL: visibility (protected)
>   FAIL: visibility (protected_undef_def)
>   FAIL: visibility (protected_weak)
>   FAIL: visibility (normal)
> 
> Based on x86-64, especially Jakub Jelinek's x86 commits 47a9f7b34f7a
> (clearing value of PLT undefined symbols if pointer equality not needed)
> and fdc90cb46b0f (omitting PLT undefined symbols from '.gnu.hash').
> 
> Note that on x86-64 PC32 (and PC64) relocations are excluded as
> indication for address taken context requiring function pointer
> equality.  This is because x86-64 used a PC32 relocation in function
> calls from non-PIC code, which has been resolved with commit
> bd7ab16b4537 ("x86-64: Generate branch with PLT32 relocation").
> 
> [1] GCC commit 0990d93dd8a4 ("IBM Z: Use @PLT symbols for local
>     functions in 64-bit mode"),
>     https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0990d93dd8a4
> [2] GCC commit a2e0a30c52fa ("IBM zSystems: Do not use @PLT with larl"),
>     https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=a2e0a30c52fa
> 
> bfd/
> 	PR ld/29655
> 	* elf64-s390.c (elf_s390_check_relocs): Require pointer equality
> 	for direct and non-PLT PC-relative relocations indicating
> 	address taking instructions and for PLT32DBL relocations, when
> 	used with address taking larl instruction.
> 	(elf_s390_finish_dynamic_symbol): Do not use canonical PLT for
> 	non-local undefined symbols if pointer equality is not needed.
> 	Abort if pointer equality needed flag not set although required.
> 	(elf_s390_copy_indirect_symbol): Copy pointer equality needed
> 	flag.
> 	(elf_s390_hash_symbol): New function.  Based on x86-64.
> 	(elf_backend_hash_symbol): Wire up elf_s390_hash_symbol.
> 
> ld/testsuite/
> 	PR ld/29655
> 	* ld-elf/shared.exp: Add new pr29655 test.
> 	* ld-elf/pr29655a.c: New file.  Based on Rui's sample in PR.
> 	* ld-elf/pr29655b.c: Likewise.
> 	* ld-elf/pr29655.rd: Expect zero fun_public symbol value.
> 	* ld-s390/plt_64-1.wf: Adjust expected test output to change in
> 	.gnu.hash due to omitted PLT undefined symbols that do not need
> 	pointer equality.
> 	* ld-s390/plt_64-1_eh.wf: Likewise.
> 
> Bug: https://sourceware.org/PR29655
> Co-authored-by: Andreas Krebbel <krebbel@linux.ibm.com>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> ---
> 
> Notes (jremus):
>     Changes in v4:
>     - Reword commit subject and message to clarify canonical PLT is only
>       required for non-PIC code taking a function address linked as PDE.
>     - Remove setup_xfail and clear_xfail. (Alan)
>     
>     Changes in v3:
>     - Turn pr29655 test into a run_cc_link_tests that checks the executable
>       using readelf --dyn-sym looking for a zero value undefined fun_public.
>       (Alan)
>     - clear-xfail arm*-*-* aarch64-*-* pr29655 test. (Linaro-TCWG-CI)
>     - clear-xfail alpha-*-* hppa-*-* ia64-*-* microblaze-*-* mips-*-*
>       mips64-*-*. (Alan)
>     
>     Changes in v2:
>     - Reword commit message to reflect that function pointer equality is
>       required for all direct and non-PLT PC-relative relocations and to
>       mention which tests fail without the GCC 12-14 workaround.
>     - Fix typo in comment on GCC 12-14 workaround. (Andreas)
>     - Have main() return 0 in test. (Andreas)
>     - Adding Nick, Alan, and Jan due to the added common test case.
>     
>     Note: Splitting the GCC 12-14 workaround into a separate patch either
>     requires it to be the first patch or causes one shared and multiple
>     visibility tests to fail. Addressing the latter using a setup_fail
>     condition as follows (that would get removed by the workaround-patch)
>     seemed rather odd to me:
>     
>       # On s390 64-bit (s390x) GCC 12-14 suffix symbols in address
>       # taken context with @PLT, which breaks function pointer equality.
>       if { [istarget s390x-*-linux*]
>            && [at_least_gcc_version 12 0]
>            && ![at_least_gcc_version 15 0] } {
>           setup_xfail "s390x-*-linux*"
>       }
> 
>  bfd/elf64-s390.c                    | 66 ++++++++++++++++++++++++++++-
>  ld/testsuite/ld-elf/pr29655.rd      |  5 +++
>  ld/testsuite/ld-elf/pr29655a.c      | 20 +++++++++
>  ld/testsuite/ld-elf/pr29655b.c      | 15 +++++++
>  ld/testsuite/ld-elf/shared.exp      | 25 +++++++++++
>  ld/testsuite/ld-s390/plt_64-1.wf    |  8 ++--
>  ld/testsuite/ld-s390/plt_64-1_eh.wf |  2 +-
>  7 files changed, 134 insertions(+), 7 deletions(-)
>  create mode 100644 ld/testsuite/ld-elf/pr29655.rd
>  create mode 100644 ld/testsuite/ld-elf/pr29655a.c
>  create mode 100644 ld/testsuite/ld-elf/pr29655b.c

Committed to mainline with Andreas' off-list approval.

Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/



More information about the Binutils mailing list