ld: testsuite: Skip pr33577 tests with GNU extensions on Solaris [PR33577]
Several of the ld-elfvers pr33577 tests FAIL on Solaris, for either or
both of two reasons:
* Tests using ld --hash-style=gnu cannot work on Solaris:
.gnu.hash/SHT_GNU_HASH sections are a GNU extension not supported by
Solaris ld.so.1.
* Similarly, binding different implementations of the same symbol to
different symbol versions is a GNU extension that wasn't in the
original Solaris specification of symbol versioning. ld.so.1 doesn't
support it and never will.
This can be seen in the elfdump output for the .dynsym section:
Symbol Table Section: .dynsym
index value size type bind oth ver shndx name
[8] 0x630 0xd FUNC GLOB D 1H .text foo
[10] 0x620 0x6 FUNC GLOB D 2 .text foo
foo is bound to both version 1 (the Base version) and version 2 (VERS_1
from pr33577.map).
Same for .symtab:
Symbol Table Section: .symtab
index value size type bind oth ver shndx name
[28] 0x620 0x6 FUNC GLOB D 0 .text foo
[35] 0x630 0xd FUNC GLOB D 0 .text foo@
As I said, ld.so.1 doesn't support <symbol>@<version> (in this case the
Base version) at all.
Therefore the tests that employ those extensions are guarded with
supports_gnu_osabi.
Tested on sparc{,v9}-sun-solaris2.11, sparc{,64}-unknown-linux-gnu,
{i386,amd64}-pc-solaris2.11, and {x86_64,i686}-pc-linux-gnu.
2026-01-23 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
ld:
PR ld/33577
* testsuite/ld-elfvers/vers.exp (base_symbol_test): Only run
pr33577a with libpr33577-versioned.so test on ELFOSABI_GNU
systems.
Likewise for run base_symbol_tests with --hash-style=gnu.
s390: Only use canonical PLT for non-PIC code taking address in PDE
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>
s390: Skip non-PIC shared library visibility linker tests
Some of the "visibility" linker tests that use a non-PIC shared library
with load offset (first load segment has a non-zero virtual address)
XPASS on s390 64-bit (s390x):
PASS: visibility (hidden) (non PIC, load offset)
XFAIL: visibility (hidden_normal) (non PIC, load offset)
PASS: visibility (hidden_undef) (non PIC, load offset)
PASS: visibility (hidden_undef_def) (non PIC, load offset)
XPASS: visibility (hidden_weak) (non PIC, load offset)
XPASS: visibility (protected) (non PIC, load offset)
PASS: visibility (protected_undef) (non PIC, load offset)
XPASS: visibility (protected_undef_def) (non PIC, load offset)
XPASS: visibility (protected_weak) (non PIC, load offset)
XFAIL: visibility (normal) (non PIC, load offset)
This is due to Alan Modra's commit 125c64931b97 from 2006, which moved
overriddenvar, shlib_overriddencall2, and shared_data from sh1.c to
sh2.c, if the shared library is build non-PIC. This prevents GCC from
treating them as local symbols, preventing the executable from
overriding them, causing the tests to fail because interposition did
not work.
This actually only became visible due to H.J. Lu's commit fd7728c8a4aa
("ld: Update function prototypes for compilers defaulting to -std=gnu23")
from 2025, that fixed the visibility test's function prototypes.
Previously all of the "visibility" tests would appear as UNSUPPORTED, as
the prerequisite compile of main.c would fail due to the function
prototypes not matching with their definitions.
In general creating shared libraries from non-PIC compiled code is not
supported on s390 64-bit (s390x). This is because shared libraries are
inherently position independent. The Glibc dynamic loader common code
passes the virtual address from the first load segment as hint to
mmap(). As a result a shared library with "load offset" may be loaded
at the virtual address used at link-time, but this is not guaranteed.
The following visibility tests using a non-PIC shared library with
load offset XPASS, if the non-PIC shared library is loaded at its link-
time "load offset". This causes the tests to PASS by chance.
XPASS: visibility (hidden_weak) (non PIC, load offset)
XPASS: visibility (protected) (non PIC, load offset)
XPASS: visibility (protected_undef_def) (non PIC, load offset)
XPASS: visibility (protected_weak) (non PIC, load offset)
The following visibility tests using a non-PIC shared library with
load offset still XFAIL:
XFAIL: visibility (hidden_normal) (non PIC, load offset)
XFAIL: visibility (normal) (non PIC, load offset)
This is because visibility_var is local in sh1.c, preventing the
executable from overriding it, causing the tests to fail because
interposition does not work.
Note that all of the visibility tests using a non-PIC shared library
without load offset XFAIL, as they are loaded at a random address, which
is incompatible with non-PIC code.
Skip all non-PIC shared library "visibility" linker tests on s390 64-bit
(s390x) as unsupported. In contrast to PowerPC and MIPS do not skip
all of the "visibility" linker tests.
ld/testsuite/
* ld-vsb/vsb.exp: Skip non-PIC shared library "visibility" tests
on s390 64-bit (s390x).
Signed-off-by: Jens Remus <jremus@linux.ibm.com>