Message ID | 20210726035802.275992-1-maskray@google.com |
---|---|
State | New |
Headers | show |
On Sun, Jul 25, 2021 at 8:58 PM Fangrui Song via Libc-alpha <libc-alpha@sourceware.org> wrote: > > The patches allow LLD 13.0.0 to build glibc. LLD's compatibility with > GNU ld is generally better than gold's compatibility with GNU ld. > > The first two commits improve gold and clang compatibility as well. > (There is still a long way for clang to build glibc.) > > About `make check` results: > > I can't configure glibc --enable-static-pie with gold, so I use > --disable-static-pie with gold. > > * gold (--disable-static-pie) has 160 FAIL. > * ld.bfd has 152 FAIL. > * ld.lld has 159 FAIL. > > ## I have investigated a few failures. > > The tst-ifunc-isa-*.c failures are not ld.lld's fault. > The lld linked tst-ifunc-isa-* work with LD_BIND_NOW=1. > 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. > > For gmon/tst-gmon-gprof*, ld.lld linked tst-gmon-gprof has a f3 line, > which appears more correct to me. But the test considers it a failure. > > % cat gmon/tst-gmon-gprof.out > --- expected > +++ actual > @@ -1,2 +1,3 @@ > f1 2000 > f2 1000 > +f3 1 > FAIL > > > For malloc/tst-compathooks-on, > > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking > > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: > > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); > > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. > __free_hook is then attached a default version GLIBC_2.2.5. > I think malloc/malloc-debug.c uses a fragile versioned symbol here. > If the inline asm uses @@ the failure should go away. > > > In summary, I think the failed tests touch some dark corners of the toolchain. > These things do not really matter for real world applications. > Please open a separate bug for each issue you are trying to fix and reference the bug in your patch. Thanks.
On 2021-07-28, H.J. Lu wrote: >On Sun, Jul 25, 2021 at 8:58 PM Fangrui Song via Libc-alpha ><libc-alpha@sourceware.org> wrote: >> >> The patches allow LLD 13.0.0 to build glibc. LLD's compatibility with >> GNU ld is generally better than gold's compatibility with GNU ld. >> >> The first two commits improve gold and clang compatibility as well. >> (There is still a long way for clang to build glibc.) >> >> About `make check` results: >> >> I can't configure glibc --enable-static-pie with gold, so I use >> --disable-static-pie with gold. >> >> * gold (--disable-static-pie) has 160 FAIL. >> * ld.bfd has 152 FAIL. >> * ld.lld has 159 FAIL. >> >> ## I have investigated a few failures. >> >> The tst-ifunc-isa-*.c failures are not ld.lld's fault. >> The lld linked tst-ifunc-isa-* work with LD_BIND_NOW=1. >> 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. >> >> For gmon/tst-gmon-gprof*, ld.lld linked tst-gmon-gprof has a f3 line, >> which appears more correct to me. But the test considers it a failure. >> >> % cat gmon/tst-gmon-gprof.out >> --- expected >> +++ actual >> @@ -1,2 +1,3 @@ >> f1 2000 >> f2 1000 >> +f3 1 >> FAIL >> >> >> For malloc/tst-compathooks-on, >> >> malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking >> >> the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: >> >> __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); >> >> This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. >> __free_hook is then attached a default version GLIBC_2.2.5. >> I think malloc/malloc-debug.c uses a fragile versioned symbol here. >> If the inline asm uses @@ the failure should go away. >> >> >> In summary, I think the failed tests touch some dark corners of the toolchain. >> These things do not really matter for real world applications. >> > >Please open a separate bug for each issue you are trying to fix and reference >the bug in your patch. > >Thanks. I filed: https://sourceware.org/bugzilla/show_bug.cgi?id=28151 elf: Some tst-audit* tests need ld --audit and --depaudit which do not work with gold or ld.lld https://sourceware.org/bugzilla/show_bug.cgi?id=28152 elf: clang integrated assembler and ld.lld do not support .tls_common https://sourceware.org/bugzilla/show_bug.cgi?id=28153 [test] gmon/tst-gmon-gprof* may have a f3 line when built with ld.lld https://sourceware.org/bugzilla/show_bug.cgi?id=28154 [test] sysdeps/x86/tst-ifunc-isa-* lazy binding failure with ld.lld If there is a need to amend patches, I'll attach the BZ numbers.
On Wed, Jul 28, 2021 at 2:52 PM Fangrui Song <maskray@google.com> wrote: > > On 2021-07-28, H.J. Lu wrote: > >On Sun, Jul 25, 2021 at 8:58 PM Fangrui Song via Libc-alpha > ><libc-alpha@sourceware.org> wrote: > >> > >> The patches allow LLD 13.0.0 to build glibc. LLD's compatibility with > >> GNU ld is generally better than gold's compatibility with GNU ld. > >> > >> The first two commits improve gold and clang compatibility as well. > >> (There is still a long way for clang to build glibc.) > >> > >> About `make check` results: > >> > >> I can't configure glibc --enable-static-pie with gold, so I use > >> --disable-static-pie with gold. > >> > >> * gold (--disable-static-pie) has 160 FAIL. > >> * ld.bfd has 152 FAIL. There should be no unexpected failures on x86 with ld.bfd. If it isn't the case for you, you should open a binutils bug. > >> * ld.lld has 159 FAIL. > >> > >> ## I have investigated a few failures. > >> > >> The tst-ifunc-isa-*.c failures are not ld.lld's fault. > >> The lld linked tst-ifunc-isa-* work with LD_BIND_NOW=1. > >> 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. > >> > >> For gmon/tst-gmon-gprof*, ld.lld linked tst-gmon-gprof has a f3 line, > >> which appears more correct to me. But the test considers it a failure. > >> > >> % cat gmon/tst-gmon-gprof.out > >> --- expected > >> +++ actual > >> @@ -1,2 +1,3 @@ > >> f1 2000 > >> f2 1000 > >> +f3 1 > >> FAIL > >> > >> > >> For malloc/tst-compathooks-on, > >> > >> malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking > >> > >> the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: > >> > >> __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); > >> > >> This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. > >> __free_hook is then attached a default version GLIBC_2.2.5. > >> I think malloc/malloc-debug.c uses a fragile versioned symbol here. > >> If the inline asm uses @@ the failure should go away. > >> > >> > >> In summary, I think the failed tests touch some dark corners of the toolchain. Please open a separate bug for each distinct failed test with lld. Thanks. > >> These things do not really matter for real world applications. > >> > > > >Please open a separate bug for each issue you are trying to fix and reference > >the bug in your patch. > > > >Thanks. > > I filed: > > https://sourceware.org/bugzilla/show_bug.cgi?id=28151 elf: Some tst-audit* tests need ld --audit and --depaudit which do not work with gold or ld.lld > https://sourceware.org/bugzilla/show_bug.cgi?id=28152 elf: clang integrated assembler and ld.lld do not support .tls_common > https://sourceware.org/bugzilla/show_bug.cgi?id=28153 [test] gmon/tst-gmon-gprof* may have a f3 line when built with ld.lld > https://sourceware.org/bugzilla/show_bug.cgi?id=28154 [test] sysdeps/x86/tst-ifunc-isa-* lazy binding failure with ld.lld > > If there is a need to amend patches, I'll attach the BZ numbers.
* Fangrui Song via Libc-alpha: > For malloc/tst-compathooks-on, > > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking > > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: > > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); > > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. > __free_hook is then attached a default version GLIBC_2.2.5. > I think malloc/malloc-debug.c uses a fragile versioned symbol here. > If the inline asm uses @@ the failure should go away. But we want to produce a compat symbol here. With the current version scripts, BFD ld will not export a symbol unless it is listed in the version script. That is, if I remove __free_hook from libc_malloc_debug in malloc/Versions, I get an ABI check failure: --- ../sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist 2021-07-27 16:14:51.516781791 +0200 +++ …/malloc/libc_malloc_debug.symlist 2021-07-30 09:55:09.818875449 +0200 @@ -3 +2,0 @@ GLIBC_2.16 aligned_alloc F -GLIBC_2.2.5 __free_hook D 0x8 If this works with a linker, it appears to ignore “local: *;” in version nodes for versioned symbols. That looks like a linker bug. Thanks, Florian
On Fri, Jul 30, 2021 at 12:57 AM Florian Weimer <fweimer@redhat.com> wrote: > > * Fangrui Song via Libc-alpha: > > > For malloc/tst-compathooks-on, > > > > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking > > > > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: > > > > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); > > > > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. > > __free_hook is then attached a default version GLIBC_2.2.5. > > I think malloc/malloc-debug.c uses a fragile versioned symbol here. > > If the inline asm uses @@ the failure should go away. > > But we want to produce a compat symbol here. With the current version > scripts, BFD ld will not export a symbol unless it is listed in the > version script. That is, if I remove __free_hook from libc_malloc_debug > in malloc/Versions, I get an ABI check failure: > > --- ../sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist 2021-07-27 16:14:51.516781791 +0200 > +++ …/malloc/libc_malloc_debug.symlist 2021-07-30 09:55:09.818875449 +0200 > @@ -3 +2,0 @@ GLIBC_2.16 aligned_alloc F > -GLIBC_2.2.5 __free_hook D 0x8 > > If this works with a linker, it appears to ignore “local: *;” in version > nodes for versioned symbols. That looks like a linker bug. > > Thanks, > Florian > I have a comment on https://sourceware.org/bugzilla/show_bug.cgi?id=23328#c6 How does removing __free_hook from malloc/Versions break the ABI check test? % cat a.s .symver __free_hook, __free_hook@GLIBC_2.2.5 .globl __free_hook __free_hook: nop % cat a.ver GLIBC_2.2.5 {}; /* should not list the non-default version __free_hook */ local { local: *; }; % cc -c a.s % ld.bfd -shared --version-script=a.ver a.o -o a.so % readelf -W --dyn- a.so | grep free_hook 3: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 7 __free_hook@GLIBC_2.2.5 One non-default version symbol, as expected.
* Fāng-ruì Sòng: > On Fri, Jul 30, 2021 at 12:57 AM Florian Weimer <fweimer@redhat.com> wrote: >> >> * Fangrui Song via Libc-alpha: >> >> > For malloc/tst-compathooks-on, >> > >> > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking >> > >> > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: >> > >> > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); >> > >> > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. >> > __free_hook is then attached a default version GLIBC_2.2.5. >> > I think malloc/malloc-debug.c uses a fragile versioned symbol here. >> > If the inline asm uses @@ the failure should go away. >> >> But we want to produce a compat symbol here. With the current version >> scripts, BFD ld will not export a symbol unless it is listed in the >> version script. That is, if I remove __free_hook from libc_malloc_debug >> in malloc/Versions, I get an ABI check failure: >> >> --- ../sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist 2021-07-27 16:14:51.516781791 +0200 >> +++ …/malloc/libc_malloc_debug.symlist 2021-07-30 09:55:09.818875449 +0200 >> @@ -3 +2,0 @@ GLIBC_2.16 aligned_alloc F >> -GLIBC_2.2.5 __free_hook D 0x8 >> >> If this works with a linker, it appears to ignore “local: *;” in version >> nodes for versioned symbols. That looks like a linker bug. >> >> Thanks, >> Florian >> > > I have a comment on https://sourceware.org/bugzilla/show_bug.cgi?id=23328#c6 > > How does removing __free_hook from malloc/Versions break the ABI check test? > > % cat a.s > .symver __free_hook, __free_hook@GLIBC_2.2.5 > .globl __free_hook > __free_hook: > nop > % cat a.ver > GLIBC_2.2.5 {}; /* should not list the non-default version __free_hook */ > local { local: *; }; We currently generate this: GLIBC_2.2.5 { global: __malloc_hook; __memalign_hook; __realloc_hook; calloc; free; mallinfo; malloc; malloc_get_state; malloc_set_state; malloc_stats; malloc_trim; malloc_usable_size; mallopt; mcheck; mcheck_check_all; mcheck_pedantic; memalign; mprobe; mtrace; muntrace; posix_memalign; pvalloc; realloc; valloc; local: *; }; See libc_malloc_debug.map in the build tree. Thanks, Florian
On 7/26/21 9:27 AM, Fangrui Song via Libc-alpha wrote: > For malloc/tst-compathooks-on, > > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking > > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: > > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); > > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. > __free_hook is then attached a default version GLIBC_2.2.5. > I think malloc/malloc-debug.c uses a fragile versioned symbol here. > If the inline asm uses @@ the failure should go away. The entire point of link time deprecation is to not emit a @@ symbol. If lld emits __free_hook@@GLIBC_2.2.5 in this case then this needs to be resolved. How does one do symbol deprecation in lld? > In summary, I think the failed tests touch some dark corners of the toolchain. > These things do not really matter for real world applications. Not having a default symbol version is a documented mechanism[1] to deprecate symbols, so this is not some obscure use case. Symbol deprecation matters for real world applications. Siddhesh [1] See section 3.3 in https://www.akkadia.org/drepper/dsohowto.pdf: "Every versioned DSO has at most one version of every API which can be used at link-time. An API (not ABI) can also vanish completely: this is a way to deprecate APIs without affecting binary compatibility."
On 8/2/21 9:32 AM, Siddhesh Poyarekar wrote: > The entire point of link time deprecation is to not emit a @@ symbol. If > lld emits __free_hook@@GLIBC_2.2.5 in this case then this needs to be > resolved. How does one do symbol deprecation in lld? Sorry I just realized that you may have implied that having a .globl in the object file ought to be sufficient to indicate that the symbol needs to be exported. The glibc linker script however overrides this with {local: *} and if the linker doesn't honour that then ISTM that this ought to be a bug in the linker. ld.bfd always gives preference to the linker script over symbol definitions in source and it seems like a simpler and more consistent rule. Siddhesh
On 2021-07-30, Fāng-ruì Sòng wrote: >On Fri, Jul 30, 2021 at 12:57 AM Florian Weimer <fweimer@redhat.com> wrote: >> >> * Fangrui Song via Libc-alpha: >> >> > For malloc/tst-compathooks-on, >> > >> > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking >> > >> > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: >> > >> > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); >> > >> > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. >> > __free_hook is then attached a default version GLIBC_2.2.5. >> > I think malloc/malloc-debug.c uses a fragile versioned symbol here. >> > If the inline asm uses @@ the failure should go away. >> >> But we want to produce a compat symbol here. With the current version >> scripts, BFD ld will not export a symbol unless it is listed in the >> version script. That is, if I remove __free_hook from libc_malloc_debug >> in malloc/Versions, I get an ABI check failure: >> >> --- ../sysdeps/unix/sysv/linux/x86_64/64/libc_malloc_debug.abilist 2021-07-27 16:14:51.516781791 +0200 >> +++ …/malloc/libc_malloc_debug.symlist 2021-07-30 09:55:09.818875449 +0200 >> @@ -3 +2,0 @@ GLIBC_2.16 aligned_alloc F >> -GLIBC_2.2.5 __free_hook D 0x8 >> >> If this works with a linker, it appears to ignore “local: *;” in version >> nodes for versioned symbols. That looks like a linker bug. >> >> Thanks, >> Florian >> > >I have a comment on https://sourceware.org/bugzilla/show_bug.cgi?id=23328#c6 > >How does removing __free_hook from malloc/Versions break the ABI check test? > >% cat a.s >.symver __free_hook, __free_hook@GLIBC_2.2.5 >.globl __free_hook >__free_hook: > nop >% cat a.ver >GLIBC_2.2.5 {}; /* should not list the non-default version __free_hook */ >local { local: *; }; >% cc -c a.s >% ld.bfd -shared --version-script=a.ver a.o -o a.so >% readelf -W --dyn- a.so | grep free_hook > 3: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 7 >__free_hook@GLIBC_2.2.5 > >One non-default version symbol, as expected. I'll implement the behavior in https://reviews.llvm.org/D107234 and https://reviews.llvm.org/D107235 ld.lld linked libc.so has exactly the same set of non-SHN_ABS dynamic symbols as ld.bfd linked libc.so. (ld.bfd places version nodes into SHN_ABS symbols but they are unused by ld.so)
On Sun, Aug 1, 2021 at 9:03 PM Siddhesh Poyarekar <siddhesh@gotplt.org> wrote: > > On 7/26/21 9:27 AM, Fangrui Song via Libc-alpha wrote: > > For malloc/tst-compathooks-on, > > > > malloc/tst-compathooks-on: Symbol `__free_hook' has different size in shared object, consider re-linking > > > > the root cause is that lld's symbol versioning is different from GNU ld in an unusal case: > > > > __asm__ (".symver " "__free_hook" "," "__free_hook" "@" "GLIBC_2.2.5"); > > > > This leaves two symbols __free_hook and __free_hook@GLIBC_2.2.5. > > __free_hook is then attached a default version GLIBC_2.2.5. > > I think malloc/malloc-debug.c uses a fragile versioned symbol here. > > If the inline asm uses @@ the failure should go away. > > The entire point of link time deprecation is to not emit a @@ symbol. > If lld emits __free_hook@@GLIBC_2.2.5 in this case then this needs to be > resolved. How does one do symbol deprecation in lld? > > > In summary, I think the failed tests touch some dark corners of the toolchain. > > These things do not really matter for real world applications. > > Not having a default symbol version is a documented mechanism[1] to > deprecate symbols, so this is not some obscure use case. Symbol > deprecation matters for real world applications. > > Siddhesh See https://sourceware.org/bugzilla/show_bug.cgi?id=28197 ("compat_symbol should migrate to .symver *, *, remove") This is an assembler design flaw. Keeping the original symbol makes all linker implementations difficult. Ian Lance Taylor's complaint is probably this: https://www.airs.com/blog/archives/220 Anyway, I installed a workaround for LLD 13.0.0. This is no longer an issue. > [1] See section 3.3 in https://www.akkadia.org/drepper/dsohowto.pdf: > > "Every versioned DSO has at most one version > of every API which can be used at link-time. An API > (not ABI) can also vanish completely: this is a way to > deprecate APIs without affecting binary compatibility."
On 8/8/21 8:24 AM, Fāng-ruì Sòng wrote: > See > https://sourceware.org/bugzilla/show_bug.cgi?id=28197 ("compat_symbol > should migrate to .symver *, *, remove") Thanks for digging deeper into this. Off the top of my head I don't remember any compat_symbol() use where we may be using the implementation function name so ", remove" may in fact be acceptable. Siddhesh
On Sun, Aug 1, 2021 at 9:23 PM Siddhesh Poyarekar <siddhesh@gotplt.org> wrote: > > On 8/2/21 9:32 AM, Siddhesh Poyarekar wrote: > > The entire point of link time deprecation is to not emit a @@ symbol. If > > lld emits __free_hook@@GLIBC_2.2.5 in this case then this needs to be > > resolved. How does one do symbol deprecation in lld? > > Sorry I just realized that you may have implied that having a .globl in > the object file ought to be sufficient to indicate that the symbol needs > to be exported. The glibc linker script however overrides this with > {local: *} and if the linker doesn't honour that then ISTM that this > ought to be a bug in the linker. ld.bfd always gives preference to the > linker script over symbol definitions in source and it seems like a > simpler and more consistent rule. > > Siddhesh Your conjecture was correct:) LLD<13.0.0 did not implement: a "local:" pattern can localize a non-default version symbol. I apologize for the previous confusion I may caused. (I was not aware that this is possible, but this behavior does make sense to me. I implemented it and cherry picked https://reviews.llvm.org/D107234 to 13.0.0)
--- expected +++ actual @@ -1,2 +1,3 @@ f1 2000 f2 1000 +f3 1