[0/3] Allow LLD 13.0.0 and improve compatibility with gold and clang

Message ID 20210726035802.275992-1-maskray@google.com
State Superseded
Headers

Commit Message

Fangrui Song July 26, 2021, 3:57 a.m. UTC
  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
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.


Fangrui Song (3):
  elf: Replace .tls_common with .tbss definition
  elf: Skip tst-auditlogmod-* if the linker doesn't support --depaudit
  configure: Allow LD to be LLD 13.0.0 or above

 configure        | 111 +++++++++++++++++++++++++++++++++++++++++++++--
 configure.ac     |  24 +++++++---
 elf/Makefile     |   4 +-
 elf/tls-macros.h |   6 ++-
 4 files changed, 134 insertions(+), 11 deletions(-)
  

Comments

H.J. Lu July 28, 2021, 6:02 p.m. UTC | #1
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.
  
Fangrui Song July 28, 2021, 9:52 p.m. UTC | #2
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.
  
H.J. Lu July 29, 2021, 2:45 p.m. UTC | #3
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.
  
Florian Weimer July 30, 2021, 7:57 a.m. UTC | #4
* 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
  
Fangrui Song July 31, 2021, 6:34 a.m. UTC | #5
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.
  
Florian Weimer July 31, 2021, 6:41 a.m. UTC | #6
* 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
  
Siddhesh Poyarekar Aug. 2, 2021, 4:02 a.m. UTC | #7
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."
  
Siddhesh Poyarekar Aug. 2, 2021, 4:23 a.m. UTC | #8
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
  
Fangrui Song Aug. 2, 2021, 8:55 p.m. UTC | #9
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)
  
Fangrui Song Aug. 8, 2021, 2:54 a.m. UTC | #10
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."
  
Siddhesh Poyarekar Aug. 8, 2021, 4:45 p.m. UTC | #11
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
  
Fangrui Song Aug. 8, 2021, 4:50 p.m. UTC | #12
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)
  

Patch

--- expected
+++ actual
@@ -1,2 +1,3 @@ 
 f1 2000
 f2 1000
+f3 1