https://sourceware.org/bugzilla/show_bug.cgi?id=29655

--- Comment #28 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jens Remus <[email protected]>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=15b1f65448f3802f51923fdde7f62272e708aea1

commit 15b1f65448f3802f51923fdde7f62272e708aea1
Author: Jens Remus <[email protected]>
Date:   Fri Mar 27 17:42:08 2026 +0100

    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 <[email protected]>
    Signed-off-by: Jens Remus <[email protected]>

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to