Bug 28154 - [test] sysdeps/x86/tst-ifunc-isa-* lazy binding failure with ld.lld
Summary: [test] sysdeps/x86/tst-ifunc-isa-* lazy binding failure with ld.lld
Alias: None
Product: glibc
Classification: Unclassified
Component: dynamic-link (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2021-07-28 21:15 UTC by Fangrui Song
Modified: 2021-09-01 05:43 UTC (History)
2 users (show)

See Also:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2021-07-28 21:15:18 UTC
Extracted from https://sourceware.org/pipermail/libc-alpha/2021-July/129450.html

To build LLD 13.0.0:

# https://github.com/llvm/llvm-project/ origin/release/13.x
cmake -H. -Bout/release -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='clang;lld'
ninja -C out/release lld

I use
sudo ln -sf $PWD/out/release/bin/lld /usr/local/bin/ld
to ensure the glibc build system definitely picks ld => lld
(messing around with LDFLAGS=-fuse-ld=lld may work as well)

`make check` says sysdeps/x86/tst-ifunc-isa-* fail.
The tests work with LD_BIND_NOW=1.

I debugged a bit. ld.lld and GNU ld place IRELATIVE differently. IIUC some ports of GNU ld use .rela.dyn and behave similar to ld.lld.

The tests happen to work with GNU ld because the IRELATIVE for foo_ifunc
is placed after JUMP_SLOT in .repa.plt.  The test needs to call
__x86_get_cpuid_feature_leaf which is defined in a different TU. IMHO
such ifunc does not guaranteed to work.
Comment 1 H.J. Lu 2021-07-29 22:21:50 UTC
See PR ld/13302.  lld should implement the same behavior.
Comment 2 Fangrui Song 2021-07-29 22:54:24 UTC
(In reply to H.J. Lu from comment #1)
> See PR ld/13302.  lld should implement the same behavior.

I think the GNU ld PowerPC (ld.lld) behavior (IRELATIVE in .rela.dyn) makes more sense. IRELATIVE relocations are eagerly resolved, so .rela.dyn is better than .rela.plt . .rela.plt should only have JUMP_SLOT.

To make PR ld/13302 work, ld.so can pause at IRELATIVE in .rela.dyn and start applying .rela.plt

(I use the section names for simplicity. Impl should use dynamic tags DT_RELA/DT_JMPREL.)
Comment 3 H.J. Lu 2021-07-29 23:07:08 UTC
(In reply to Fangrui Song from comment #2)
> To make PR ld/13302 work, ld.so can pause at IRELATIVE in .rela.dyn and
> start applying .rela.plt

This requires both linker and ld.so changes.  The PR ld/13302 linker change
doesn't require ld.so change.
Comment 4 cvs-commit@gcc.gnu.org 2021-09-01 05:43:16 UTC
The master branch has been updated by Fangrui Song <maskray@sourceware.org>:


commit 224edada607ebc6aaa1aadaae423128fae7880df
Author: Fangrui Song <maskray@google.com>
Date:   Mon Aug 30 13:59:33 2021 -0700

    configure: Allow LD to be LLD 13.0.0 or above [BZ #26558]
    When using LLD (LLVM linker) as the linker, configure prints a confusing
        *** These critical programs are missing or too old: GNU ld
    LLD>=13.0.0 can build glibc --enable-static-pie. (8.0.0 needs one
    workaround for -Wl,-defsym=_begin=0. 9.0.0 works with
    XFAIL two tests sysdeps/x86/tst-ifunc-isa-* which have the BZ #28154
    issue (LLD follows the PowerPC port of GNU ld for ifunc by placing
    IRELATIVE relocations in .rela.dyn, triggering a glibc ifunc fragility).
    The set of dynamic symbols is the same with GNU ld and LLD,
    modulo unused SHN_ABS version node symbols.
    For comparison, gold does not support --enable-static-pie
    yet (--no-dynamic-linker is unsupported BZ #22221), yet
    has 6 failures more than LLD. gold linked libc.so has
    larger .dynsym differences with GNU ld and LLD
    (non-default version symbols are changed to default versions
    by a version script BZ #28196).