[PATCH v2 3/3] configure: Allow LD to be LLD 13.0.0 or above [BZ #26558]

H.J. Lu hjl.tools@gmail.com
Tue Aug 10 14:38:02 GMT 2021


On Mon, Aug 9, 2021 at 12:59 PM Fāng-ruì Sòng <maskray@google.com> wrote:
>
> On Mon, Aug 9, 2021 at 10:59 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Sat, Aug 7, 2021 at 9:17 PM Fāng-ruì Sòng <maskray@google.com> wrote:
> > >
> > >
> > >
> > > On 2021-08-07, H.J. Lu wrote:
> > > >On Fri, Aug 6, 2021 at 5:48 PM Fāng-ruì Sòng <maskray@google.com> wrote:
> > > >>
> > > >> On 2021-08-05, H.J. Lu wrote:
> > > >> >On Thu, Aug 5, 2021 at 9:43 AM Fāng-ruì Sòng <maskray@google.com> wrote:
> > > >> >>
> > > >> >> On Thu, Aug 5, 2021 at 9:34 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > >> >> >
> > > >> >> > On Thu, Aug 5, 2021 at 9:29 AM Fangrui Song via Libc-alpha
> > > >> >> > <libc-alpha@sourceware.org> wrote:
> > > >> >> > >
> > > >> >> > > When using LLD (LLVM linker) as the linker, configure prints a confusing
> > > >> >> > > message.
> > > >> >> > >
> > > >> >> > >     *** 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
> > > >> >> > > --disable-static-pie).
> > > >> >> > >
> > > >> >> > > With BZ #28153 (glibc bug exposed by testing with LLD) fixed,
> > > >> >> > > `make check` only has 2 more failures with LLD than with GNU ld:
> > > >> >> > > BZ #28154 (LLD follows the PowerPC port of GNU ld for ifunc by
> > > >> >> > > placing IRELATIVE relocations in .rela.dyn).
> > > >> >> >
> > > >> >> > This is an lld bug, similar to:
> > > >> >> >
> > > >> >> > https://sourceware.org/bugzilla/show_bug.cgi?id=13302
> > > >> >> >
> > > >> >> > Please fix it at least on x86.
> > > >> >>
> > > >> >> I am afraid that I disagree. The PowerPC port of GNU ld does the right
> > > >> >
> > > >> >This is just one opinion and it doesn't make it "the right thing".
> > > >> >
> > > >> >> thing and LLD follows suit.
> > > >> >> R_*_IRELATIVE relocations should be eagerly resolved, so they belong
> > > >> >> to .rela.dyn instead of .rela.plt.
> > > >> >
> > > >> >Ulrich and I designed/implemented IFUNC on x86 and for x86.  I consider
> > > >> >x86 implementation of IFUC as the gold standard.
> > > >>
> > > >> kib from FreeBSD said
> > > >>
> > > >> "FreeBSD rtld does the initial pass over the plt relocations and handles
> > > >> R_X86_64_JMP_SLOT only, If there are any R_X86_64_IRELATIVE relocks, we
> > > >> mark the object as having such relocations. Then, we do the ireloc
> > > >> processing, using the depth-first descend. We handle all IRELOCs for
> > > >> dependent objects before doing it for dependee. There, we iterate over
> > > >> all plt relocs to select IRELOCs."
> > > >>
> > > >> I pondered at this comment
> > > >>
> > > >> /*
> > > >>   * The handling of R_MACHINE_IRELATIVE relocations and jumpslots
> > > >>   * referencing STT_GNU_IFUNC symbols is postponed till the other
> > > >>   * relocations are done.  The indirect functions specified as
> > > >>   * ifunc are allowed to call other symbols, so we need to have
> > > >>   * objects relocated before asking for resolution from indirects.
> > > >>   *
> > > >>   * The R_MACHINE_IRELATIVE slots are resolved in greedy fashion,
> > > >>   * instead of the usual lazy handling of PLT slots.  It is
> > > >>   * consistent with how GNU does it.
> > > >>   */
> > > >>
> > > >> and re-read https://sourceware.org/glibc/wiki/GNU_IFUNC
> > > >>
> > > >> "This may work on x86_64 where the R_*_IRELATIVE relocations happen in
> > > >> DT_JMPREL after the DT_REL* relocations, but that is no guarantee that it will
> > > >> work on AArch64, PPC64, or other architectures that are slightly different.
> > > >> Such fundamental limitations may be lifted at a future point."
> > > >>
> > > >> I think adopting the FreeBSD approach can make IRELATIVE more robust, even for
> > > >> x86. IRELATIVE is still eager resolved, just postponed after other relocations.
> > > >> Fixing this property in glibc will improve rubustness/flexibility of ifunc
> > > >> resolvers and freeing linkers the responsibility to order IRELATIVE in a
> > > >> particular position.
> > > >>
> > > >> Pioneering on one feature gives the designer respect, yet the designer can only
> > > >> earn authority by demonstrating the consideration of all sort of implication.
> > > >>
> > > >
> > > >On Linux/x86, lld is incompatible with ld.so on this particular IFUNC feature.
> > > >We have 3 choices:
> > > >
> > > >1. Ignore it.  But it means that if lld is used to build glibc, we don't know if
> > > >this feature works or not.
> > >
> > > Let's ignore it :)
> > >
> > > It's just 2 tests, representing a corner case of IRELATIVE, which is
> > > unreliable on non-x86 (as documented) and x86 (see below) anyway.
> > >
> > > >2. Change glibc to make it compatible with lld.
> > > >3. Change lld to make it compatible with glibc.
> > > >
> > > >The FreeBSD scheme is not wrong.  But it is a workaround in glibc
> > > >for a linker bug unless it also fixes other IFUNC issues on Linux/x86.
> > >
> > > Let me try convincing you that glibc should be fixed:)
> > >
> > >    // a.c
> > >    #include <stdio.h>
> > >
> > >    int a_impl() { return 42; }
> > >    void *a_resolver() {
> > >      puts("a_resolver");
> > >      return (void *)a_impl;
> > >    }
> > >    int a() __attribute__((ifunc("a_resolver")));
> > >
> > >    // .rela.dyn.rel => R_X86_64_64 referencing STT_GNU_IFUNC in .rela.dyn
> > >    int (*fptr_a)() = a;
> > >
> > >    int main() { printf("%d\n", a()); }
> > >
> > > OK, let's compile with gcc and link with GNU ld:
> > >
> > > % cc -fpie -c a.c; cc -fuse-ld=bfd -pie a.o -o a; ./a
> > > [1]    170657 segmentation fault  ./a
> > >
> > > Oops. The segfault is very similar to the 2 ld.lld FAIL.
> >
> > There are restrictions on how IFUNC can be used.   If we want to
> > support this use case, we need to change ld.so or/and linker.
>
> Since you are familiar with dynamic linking, perhaps you can offer the
> ld.so fix  (postponing ifunc resolver invocation after other regular
> relocations) :)

Please open a glibc bug so that we can track it.   We should first
decide if we want to support this use case.

> Once a separate relocation loop for ifunc is created, it is trivial
> for non-x86 arch maintainers to make ifunc more reliable for their
> arches.
>
> Then users can build more trust on ifunc.
>
>
> Let me consider this sub-thread a non-blocker for LLD 13.0.0 support.
>
> > > Now, you may say, we can change GNU ld to emit R_X86_64_IRELATIVE instead of R_X86_64_64.
> > >
> > > Then let's try this:
> > >
> > >    // b.c
> > >    #include <stdio.h>
> > >
> > >    int b_impl() { return 42; }
> > >    void *b_resolver() {
> > >      puts("b resolver");
> > >      return (void *)b_impl;
> > >    }
> > >    int b() __attribute__((ifunc("b_resolver")));
> > >
> > >    int (*fptr_b)() = b;
> > >
> > > cc b.c -fpic -shared -o b.so
> > > Make it a DT_NEEDED of a and see the crash again. b is preemptible so IRELATIVE is not correct.
> >
> > I don't believe this is the use case we want to support.
>
> Do we have easy-to-explain words on what's supported and what's not?

This has been a recurring topic. We should have some guidance
on IFUNC.  IFUNC was designed for glibc.  It was later extended to
other use cases.  There are limitations, like

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

We need clear descriptions about how IFUNC should be used.

> > >
> > > If glibc adopts the FreeBSD model, then all these will be good, along with LLD's .rela.dyn IRELATIVE.
> > > An ifunc resolver can call functions defined in an arbitrary DT_NEEDED.
> >
> >
> >
> > --
> > H.J.



-- 
H.J.


More information about the Libc-alpha mailing list