* Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
@ 2020-03-16 4:58 Fangrui Song
2020-03-16 5:02 ` Fangrui Song
0 siblings, 1 reply; 10+ messages in thread
From: Fangrui Song @ 2020-03-16 4:58 UTC (permalink / raw)
To: binutils; +Cc: Florian Weimer, libc-alpha
cd /tmp/p
git clone git://sourceware.org/git/glibc.git; cd glibc
mkdir Release; ../configure --prefix=/tmp/opt
make -j
When linking elf/librtld.map.o
% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o -Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0 -Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0 -Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-(' /tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
Without -Wl,defsym:
dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
__libc_scratch_buffer_set_array_size fetches libc_pic.a(scratch_buffer_set_array_size.os)
libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
free fetches libc_pic.a(malloc.os)
libc_pic.a(malloc.os) has an undefined __libc_message
__libc_message fetches libc_pic.a(libc_fatal.os)
libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
>>> defined at dl-fxstatat64.c
>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
>>> defined at libc_fatal.c
>>> libc_fatal.os:(.text+0x240) in archive /tmp/p/glibc/Release/libc_pic.a
glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress libc_pic.a(malloc.os):
% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail_local
826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail
905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
My question is: does the suppression via --defsym work reliably?
# a.o
call foo
# b.a(b.o)
.globl foo, free
foo:
free:
# GNU ld --defsym is order dependent.
ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
# gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to match GNU ld.
gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
# lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
# https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is required to bypass a configure check
ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 4:58 Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o) Fangrui Song
@ 2020-03-16 5:02 ` Fangrui Song
2020-03-16 11:27 ` H.J. Lu
0 siblings, 1 reply; 10+ messages in thread
From: Fangrui Song @ 2020-03-16 5:02 UTC (permalink / raw)
To: binutils; +Cc: Florian Weimer, libc-alpha
On 2020-03-15, Fangrui Song wrote:
>cd /tmp/p
>git clone git://sourceware.org/git/glibc.git; cd glibc
>mkdir Release; ../configure --prefix=/tmp/opt
>make -j
>
>When linking elf/librtld.map.o
>
>% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o -Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0 -Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0 -Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-(' /tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
>
>Without -Wl,defsym:
>
>dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
>__libc_scratch_buffer_set_array_size fetches libc_pic.a(scratch_buffer_set_array_size.os)
>libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
>free fetches libc_pic.a(malloc.os)
>libc_pic.a(malloc.os) has an undefined __libc_message
>__libc_message fetches libc_pic.a(libc_fatal.os)
>
>libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
>>>>defined at dl-fxstatat64.c
>>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
>>>>defined at libc_fatal.c
>>>> libc_fatal.os:(.text+0x240) in archive /tmp/p/glibc/Release/libc_pic.a
>
>glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress libc_pic.a(malloc.os):
>
>% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
> 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail_local
> 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
> 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail
> 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
> 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
> 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
>
>My question is: does the suppression via --defsym work reliably?
>
># a.o
>call foo
>
># b.a(b.o)
>.globl foo, free
>foo:
>free:
>
>
># GNU ld --defsym is order dependent.
>ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>
># gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to match GNU ld.
>gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>
># lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
># https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is required to bypass a configure check
>ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent
Sorry, clarify the behavior of lld.
# lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 5:02 ` Fangrui Song
@ 2020-03-16 11:27 ` H.J. Lu
2020-03-16 15:47 ` Fangrui Song
0 siblings, 1 reply; 10+ messages in thread
From: H.J. Lu @ 2020-03-16 11:27 UTC (permalink / raw)
To: Fangrui Song; +Cc: Binutils, GNU C Library
On Sun, Mar 15, 2020 at 10:02 PM Fangrui Song via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> On 2020-03-15, Fangrui Song wrote:
> >cd /tmp/p
> >git clone git://sourceware.org/git/glibc.git; cd glibc
> >mkdir Release; ../configure --prefix=/tmp/opt
> >make -j
> >
> >When linking elf/librtld.map.o
> >
> >% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o -Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0 -Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0 -Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-(' /tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
> >
> >Without -Wl,defsym:
> >
> >dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
> >__libc_scratch_buffer_set_array_size fetches libc_pic.a(scratch_buffer_set_array_size.os)
> >libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
> >free fetches libc_pic.a(malloc.os)
> >libc_pic.a(malloc.os) has an undefined __libc_message
> >__libc_message fetches libc_pic.a(libc_fatal.os)
> >
> >libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
> >>>>defined at dl-fxstatat64.c
> >>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
> >>>>defined at libc_fatal.c
> >>>> libc_fatal.os:(.text+0x240) in archive /tmp/p/glibc/Release/libc_pic.a
> >
> >glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress libc_pic.a(malloc.os):
> >
> >% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
> > 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail_local
> > 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
> > 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail
> > 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
> > 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
> > 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
> >
> >My question is: does the suppression via --defsym work reliably?
> >
> ># a.o
> >call foo
> >
> ># b.a(b.o)
> >.globl foo, free
> >foo:
> >free:
> >
> >
> ># GNU ld --defsym is order dependent.
> >ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
> >ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
> >
> ># gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to match GNU ld.
> >gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
> >gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
> >
> ># lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
> ># https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is required to bypass a configure check
> >ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
> >ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>
> Sorry, clarify the behavior of lld.
>
> # lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
> ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
> ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
Glibc build requires a linker compatible with ld. Can you provide an lld
option to make lld compatible with ld for cases like this?
--
H.J.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 11:27 ` H.J. Lu
@ 2020-03-16 15:47 ` Fangrui Song
2020-03-16 16:01 ` H.J. Lu
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Fangrui Song @ 2020-03-16 15:47 UTC (permalink / raw)
To: H.J. Lu; +Cc: Binutils, GNU C Library, Florian Weimer
On 2020-03-16, H.J. Lu wrote:
>On Sun, Mar 15, 2020 at 10:02 PM Fangrui Song via Libc-alpha
><libc-alpha@sourceware.org> wrote:
>>
>> On 2020-03-15, Fangrui Song wrote:
>> >cd /tmp/p
>> >git clone git://sourceware.org/git/glibc.git; cd glibc
>> >mkdir Release; ../configure --prefix=/tmp/opt
>> >make -j
>> >
>> >When linking elf/librtld.map.o
>> >
>> >% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o -Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0 -Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0 -Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-(' /tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
>> >
>> >Without -Wl,defsym:
>> >
>> >dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
>> >__libc_scratch_buffer_set_array_size fetches libc_pic.a(scratch_buffer_set_array_size.os)
>> >libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
>> >free fetches libc_pic.a(malloc.os)
>> >libc_pic.a(malloc.os) has an undefined __libc_message
>> >__libc_message fetches libc_pic.a(libc_fatal.os)
>> >
>> >libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
>> >>>>defined at dl-fxstatat64.c
>> >>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
>> >>>>defined at libc_fatal.c
>> >>>> libc_fatal.os:(.text+0x240) in archive /tmp/p/glibc/Release/libc_pic.a
>> >
>> >glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress libc_pic.a(malloc.os):
>> >
>> >% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
>> > 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail_local
>> > 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
>> > 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail
>> > 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
>> > 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
>> > 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
>> >
>> >My question is: does the suppression via --defsym work reliably?
>> >
>> ># a.o
>> >call foo
>> >
>> ># b.a(b.o)
>> >.globl foo, free
>> >foo:
>> >free:
>> >
>> >
>> ># GNU ld --defsym is order dependent.
>> >ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>> >ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>> >
>> ># gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to match GNU ld.
>> >gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>> >gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>> >
>> ># lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
>> ># https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is required to bypass a configure check
>> >ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>> >ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>>
>> Sorry, clarify the behavior of lld.
>>
>> # lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
>> ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>> ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
>
>Glibc build requires a linker compatible with ld. Can you provide an lld
>option to make lld compatible with ld for cases like this?
As a contributor of lld, I would be cooperative and be happy to adapt lld if the proposed semantic is reasonable.
I am concerned that the --defsym's order dependence with archive files is not so obvious, given -u's behavior:
# -u inserts an undefined which fetches b.a(b.o)
ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
# This can't be order dependent because b.a (not in a group) should have been dropped when we saw -u
ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
Some observations:
# GNU ld --defsym interacts with an archive
ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
# a.x contains one line `foo = 0;`
# -T a.x is similar to --defsym
ld.bfd a.o b.a -T a.x -o a # b.a(b.o) is fetched. free is present
ld.bfd -T a.x a.o b.a -o a # b.a(b.o) is not fetched. free is absent
# -u is usually order independent
# The second can't be order dependent because b.a should have been dropped when we see -u
ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
# gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to make it work
gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
# gold --export-dynamic-symbol (not in GNU ld) implies -u
gold --export-dynamic-symbol foo b.a # b.a(b.o) is fetched. free is present
gold b.a --export-dynamic-symbol foo # b.a(b.o) is fetched. free is present
# lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
If we aim for robustness and make the librtld.map.o trick supported (I will add a note that gold happens to work),
I will hope both the following can suppress b.a(b.o):
ld.bfd a.o b.a --defsym foo=0
ld.bfd --defsym foo=0 a.o b.a
(a) Given --defsym's similarity to a symbol assignment specified by a -T, we will hope -T does not behave too differently.
(b) Note that in a linker script, at least input files should be order dependent w.r.t. input files on the command line.
(a)+(b) => symbol assignments specified by -T need to be declared early but input files specified -T are ordered w.r.t. input files on the command line.
For linker portability, projects using this trick (currently glibc is the only one) should place --defsym first to work with
existing releases of GNU ld.
The added librtld.map.o code is related to https://sourceware.org/bugzilla/show_bug.cgi?id=25486
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 15:47 ` Fangrui Song
@ 2020-03-16 16:01 ` H.J. Lu
2020-03-16 18:31 ` Fangrui Song
2020-03-16 19:05 ` Michael Matz
2 siblings, 0 replies; 10+ messages in thread
From: H.J. Lu @ 2020-03-16 16:01 UTC (permalink / raw)
To: Fangrui Song; +Cc: Binutils, GNU C Library, Florian Weimer
On Mon, Mar 16, 2020 at 8:47 AM Fangrui Song <maskray@google.com> wrote:
>
> On 2020-03-16, H.J. Lu wrote:
> >On Sun, Mar 15, 2020 at 10:02 PM Fangrui Song via Libc-alpha
> ><libc-alpha@sourceware.org> wrote:
> >>
> >> On 2020-03-15, Fangrui Song wrote:
> >> >cd /tmp/p
> >> >git clone git://sourceware.org/git/glibc.git; cd glibc
> >> >mkdir Release; ../configure --prefix=/tmp/opt
> >> >make -j
> >> >
> >> >When linking elf/librtld.map.o
> >> >
> >> >% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o -Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0 -Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0 -Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-(' /tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
> >> >
> >> >Without -Wl,defsym:
> >> >
> >> >dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
> >> >__libc_scratch_buffer_set_array_size fetches libc_pic.a(scratch_buffer_set_array_size.os)
> >> >libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
> >> >free fetches libc_pic.a(malloc.os)
> >> >libc_pic.a(malloc.os) has an undefined __libc_message
> >> >__libc_message fetches libc_pic.a(libc_fatal.os)
> >> >
> >> >libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
> >> >>>>defined at dl-fxstatat64.c
> >> >>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
> >> >>>>defined at libc_fatal.c
> >> >>>> libc_fatal.os:(.text+0x240) in archive /tmp/p/glibc/Release/libc_pic.a
> >> >
> >> >glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress libc_pic.a(malloc.os):
> >> >
> >> >% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
> >> > 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail_local
> >> > 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
> >> > 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS __stack_chk_fail
> >> > 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
> >> > 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
> >> > 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
> >> >
> >> >My question is: does the suppression via --defsym work reliably?
> >> >
> >> ># a.o
> >> >call foo
> >> >
> >> ># b.a(b.o)
> >> >.globl foo, free
> >> >foo:
> >> >free:
> >> >
> >> >
> >> ># GNU ld --defsym is order dependent.
> >> >ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
> >> >ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
> >> >
> >> ># gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to match GNU ld.
> >> >gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
> >> >gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
Gold is irrelevant here since it isn't supported to build glibc:
https://sourceware.org/bugzilla/show_bug.cgi?id=24148
There are also other gold bugs which may impact glibc build. Please remove
gold from this discussion.
--
H.J.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 15:47 ` Fangrui Song
2020-03-16 16:01 ` H.J. Lu
@ 2020-03-16 18:31 ` Fangrui Song
2020-03-16 19:05 ` Michael Matz
2 siblings, 0 replies; 10+ messages in thread
From: Fangrui Song @ 2020-03-16 18:31 UTC (permalink / raw)
To: H.J. Lu, Florian Weimer; +Cc: Binutils, GNU C Library
>>>On 2020-03-16, H.J. Lu wrote:
>>>Glibc build requires a linker compatible with ld. Can you provide an lld
>>>option to make lld compatible with ld for cases like this?
>>
>>As a contributor of lld, I would be cooperative and be happy to adapt lld if the proposed semantic is reasonable.
>>
>>I am concerned that the --defsym's order dependence with archive files is not so obvious, given -u's behavior:
>>
>># -u inserts an undefined which fetches b.a(b.o)
>>ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
>># This can't be order dependent because b.a (not in a group) should have been dropped when we saw -u
>>ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
>>
>>
>>Some observations:
>>
>>
>># GNU ld --defsym interacts with an archive
>>ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>>ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>>
>># a.x contains one line `foo = 0;`
>># -T a.x is similar to --defsym
>>ld.bfd a.o b.a -T a.x -o a # b.a(b.o) is fetched. free is present
>>ld.bfd -T a.x a.o b.a -o a # b.a(b.o) is not fetched. free is absent
>>
>># -u is usually order independent
>># The second can't be order dependent because b.a should have been dropped when we see -u
>>ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
>>ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
>>
>>
>># gold --defsym is order independent. For the more complex glibc elf/librtld.map.o case, it happens to make it work
>>gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>>gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>>
>># gold --export-dynamic-symbol (not in GNU ld) implies -u
>>gold --export-dynamic-symbol foo b.a # b.a(b.o) is fetched. free is present
>>gold b.a --export-dynamic-symbol foo # b.a(b.o) is fetched. free is present
>>
>>
>># lld --defsym is order independent. --defsym is processed the last. For elf/librtld.map.o it will report a multiple definition error.
>>ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>>ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
>>
>>
>>If we aim for robustness and make the librtld.map.o trick supported (I will add a note that gold happens to work),
>>I will hope both the following can suppress b.a(b.o):
>>
>> ld.bfd a.o b.a --defsym foo=0
>> ld.bfd --defsym foo=0 a.o b.a
>>
>>(a) Given --defsym's similarity to a symbol assignment specified by a -T, we will hope -T does not behave too differently.
>>(b) Note that in a linker script, at least input files should be order dependent w.r.t. input files on the command line.
>>
>>(a)+(b) => symbol assignments specified by -T need to be declared early but input files specified -T are ordered w.r.t. input files on the command line.
>>
>>
>>For linker portability, projects using this trick (currently glibc is the only one) should place --defsym first to work with
>>existing releases of GNU ld.
>>
>>The added librtld.map.o code is related to https://sourceware.org/bugzilla/show_bug.cgi?id=25486
>
>Gold is irrelevant here since it isn't supported to build glibc:
>
>https://sourceware.org/bugzilla/show_bug.cgi?id=24148
>
>There are also other gold bugs which may impact glibc build. Please remove
>gold from this discussion.
Thanks for the link. I am aways eager to learn more about linkers..
My motivation is indeed for my selfish dream to make glibc compilable with clang and linkable with lld.
As a contributor of lld and various LLVM tools, I think I am best positioned to make the situation better:)
At least for lld, it seems we need very few portability patches to work.
(At least the default configuration. There are numerous other configurations I don't know how to test now. I know really little about glibc.)
To make it very clear, I won't add workarounds for quality of implementation issues of clang+lld.
I mostly consider lld HEAD (lld<8 is not very reliable.)
To make my intention more plausible, this is in the spirit of https://gcc.gnu.org/wiki/cauldron2019 (GCC/LLVM Collaboration BoF).
Given more thoughts, I would hope we don't rely on the --defsym trick for malloc.os symbols
(already in use before commit 3a0ecccb599a6b1ad4b149dc569c0080e92d057b).
lld processes input files and -T/-u/--defsym in the following order:
1. parseFile(files[i]) // shared, relocatable, archive, linker scripts. Most archive members fetch is done in this step
2. handle -u // This can trigger more fetch of archive members
3. declare symbols specified by -T and --defsym // too late to suppress fetch of archive members
(I have a feeling that gold's overall strategy is similar, though, when handling --start-group, it
sorta gets into an undesired "mixed" status (my simple a.o b.a example and librtld.map.o exhibit
different behaviors))
I could let lld match GNU ld by adding a separate --defsym step, but the logic would not be
consistent with -T processing.
1. declare symbols specified by --defsym
2. parseFile(files[i])
3. handle -u
4. declare symbols specified by -T
Note that --defsym can accept arbitrary expressions. Their st_shndx/st_value isn't finalized.
Postponing their effectness as late as possible can theoretically make implementations (ld/ldlang.c
ld/ldexp.c) simpler.
Without the --defsym trick, the following scheme may work:
(1) remove malloc.os from libc_pic.a
(2) ld -r -( dl-allobjs.os libc_pic.a -) -Map librtld.map
(3) add malloc.os back to libc_pic.a
(4) process librtld.map and get the libc dependencies
...
(1) and (3) could be avoided if GNU ld supported --start-lib --end-lib (gold,lld):
https://sourceware.org/bugzilla/show_bug.cgi?id=24600
As to why we should make ld a.o b.a --defsym foo=0 and ld --defsym foo=0 a.o b.a behave the same,
order dependency is not robust. We should avoid subtle failures if possible.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 15:47 ` Fangrui Song
2020-03-16 16:01 ` H.J. Lu
2020-03-16 18:31 ` Fangrui Song
@ 2020-03-16 19:05 ` Michael Matz
2020-03-21 16:39 ` Fangrui Song
2020-04-11 17:04 ` Florian Weimer
2 siblings, 2 replies; 10+ messages in thread
From: Michael Matz @ 2020-03-16 19:05 UTC (permalink / raw)
To: Fangrui Song; +Cc: H.J. Lu, Florian Weimer, GNU C Library, Binutils
Hallo,
On Mon, 16 Mar 2020, Fangrui Song via Binutils wrote:
> On 2020-03-16, H.J. Lu wrote:
> >On Sun, Mar 15, 2020 at 10:02 PM Fangrui Song via Libc-alpha
> ><libc-alpha@sourceware.org> wrote:
> >>
> >> On 2020-03-15, Fangrui Song wrote:
> >> >cd /tmp/p
> >> >git clone git://sourceware.org/git/glibc.git; cd glibc
> >> >mkdir Release; ../configure --prefix=/tmp/opt
> >> >make -j
> >> >
> >> >When linking elf/librtld.map.o
> >> >
> >> >% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o
> >> >-Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0
> >> >-Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0
> >> >-Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-('
> >> >/tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a
> >> >-lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
> >> >
> >> >Without -Wl,defsym:
> >> >
> >> >dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
> >> >__libc_scratch_buffer_set_array_size fetches
> >> >libc_pic.a(scratch_buffer_set_array_size.os)
> >> >libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
> >> >free fetches libc_pic.a(malloc.os)
> >> >libc_pic.a(malloc.os) has an undefined __libc_message
> >> >__libc_message fetches libc_pic.a(libc_fatal.os)
> >> >
> >> >libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
> >> >>>>defined at dl-fxstatat64.c
> >> >>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
> >> >>>>defined at libc_fatal.c
> >> >>>> libc_fatal.os:(.text+0x240) in archive
> >> >>>> /tmp/p/glibc/Release/libc_pic.a
> >> >
> >> >glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress
> >> >libc_pic.a(malloc.os):
> >> >
> >> >% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
> >> > 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS
> >> > __stack_chk_fail_local
> >> > 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
> >> > 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS
> >> > __stack_chk_fail
> >> > 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
> >> > 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
> >> > 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
> >> >
> >> >My question is: does the suppression via --defsym work reliably?
> >> >
> >> ># a.o
> >> >call foo
> >> >
> >> ># b.a(b.o)
> >> >.globl foo, free
> >> >foo:
> >> >free:
> >> >
> >> >
> >> ># GNU ld --defsym is order dependent.
> >> >ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
> >> >ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
> >> >
> >> ># gold --defsym is order independent. For the more complex glibc
> >> >elf/librtld.map.o case, it happens to match GNU ld.
> >> >gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
> >> >gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
> >> >
> >> ># lld --defsym is order independent. --defsym is processed the last. For
> >> ># elf/librtld.map.o it will report a multiple definition error.
> >> ># https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is
> >> ># required to bypass a configure check
> >> >ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
> >> >ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent
> >>
> >> Sorry, clarify the behavior of lld.
> >>
> >> # lld --defsym is order independent. --defsym is processed the last. For
> >> elf/librtld.map.o it will report a multiple definition error.
> >> ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
> >> ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
> >
> >Glibc build requires a linker compatible with ld. Can you provide an lld
> >option to make lld compatible with ld for cases like this?
>
> As a contributor of lld, I would be cooperative and be happy to adapt lld if
> the proposed semantic is reasonable.
>
> I am concerned that the --defsym's order dependence with archive files is not
> so obvious, given -u's behavior:
>
> # -u inserts an undefined which fetches b.a(b.o)
> ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
> # This can't be order dependent because b.a (not in a group) should have been
> dropped when we saw -u
> ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
>
> Some observations:
>
>
> # GNU ld --defsym interacts with an archive
> ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
> ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
I consider this the correct linker behaviour. In that sense I would
consider the inconsistency with -u and -T to be the problems of those, not
a problem of --defsym (but not necessarily problems we can fix anymore, as
people might rely on that). (i.e. I think the second -u command above
should result in an 'undefined foo' output/error, not in b.a(b.o) being
fetched).
I consider the above to be correct because this is how traditional link
editors behave with respect to archives: ordering of file arguments does
matter (obviously between .o and .a, but also between multiple .a and even
between .o (think static initializers)). And if you interpret '--defsym
bla' as "object file defining symbol bla" and '-u foo' as "object file
containing reference to foo" the behaviour for --defsym naturally follows
(and makes the behaviour of -u be the inconsistence).
For this reasoning it's immaterial that --defsym accepts expressions: the
evaluation of them can be delayed until cmdline arguments are processed.
But the point of definition or reference should be their place in the
cmdline.
How that interacts with -T: well, in an ideal world I don't see why those
shouldn't also be processed in order and at their place within the command
line (i.e. file arguments before it are available and processed, file
arguments after it aren't yet), again with the caveat that RHS expressions
might be evaluated late, but name references or definitions happen
immediately). But as said, we might not be able to change ld such that
this is the case for compat reasons.
> If we aim for robustness and make the librtld.map.o trick supported (I will
> add a note that gold happens to work),
> I will hope both the following can suppress b.a(b.o):
>
> ld.bfd a.o b.a --defsym foo=0
> ld.bfd --defsym foo=0 a.o b.a
And I would hope that the above two would _not_ be made to behave the
same.
Ciao,
Michael.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 19:05 ` Michael Matz
@ 2020-03-21 16:39 ` Fangrui Song
2020-04-11 17:04 ` Florian Weimer
1 sibling, 0 replies; 10+ messages in thread
From: Fangrui Song @ 2020-03-21 16:39 UTC (permalink / raw)
To: Michael Matz; +Cc: H.J. Lu, Florian Weimer, GNU C Library, Binutils
On 2020-03-16, Michael Matz wrote:
>Hallo,
>
>On Mon, 16 Mar 2020, Fangrui Song via Binutils wrote:
>
>> On 2020-03-16, H.J. Lu wrote:
>> >On Sun, Mar 15, 2020 at 10:02 PM Fangrui Song via Libc-alpha
>> ><libc-alpha@sourceware.org> wrote:
>> >>
>> >> On 2020-03-15, Fangrui Song wrote:
>> >> >cd /tmp/p
>> >> >git clone git://sourceware.org/git/glibc.git; cd glibc
>> >> >mkdir Release; ../configure --prefix=/tmp/opt
>> >> >make -j
>> >> >
>> >> >When linking elf/librtld.map.o
>> >> >
>> >> >% gcc -nostdlib -nostartfiles -r -o /tmp/p/glibc/Release/elf/librtld.map.o
>> >> >-Wl,--defsym=calloc=0 -Wl,--defsym=free=0 -Wl,--defsym=malloc=0
>> >> >-Wl,--defsym=realloc=0 -Wl,--defsym=__stack_chk_fail=0
>> >> >-Wl,--defsym=__stack_chk_fail_local=0 '-Wl,-('
>> >> >/tmp/p/glibc/Release/elf/dl-allobjs.os /tmp/p/glibc/Release/libc_pic.a
>> >> >-lgcc '-Wl,-)' -Wl,-Map,/tmp/p/glibc/Release/elf/librtld.mapT
>> >> >
>> >> >Without -Wl,defsym:
>> >> >
>> >> >dl-allobjs.os has an undefined __libc_scratch_buffer_set_array_size
>> >> >__libc_scratch_buffer_set_array_size fetches
>> >> >libc_pic.a(scratch_buffer_set_array_size.os)
>> >> >libc_pic.a(scratch_buffer_set_array_size.os) has an undefined free
>> >> >free fetches libc_pic.a(malloc.os)
>> >> >libc_pic.a(malloc.os) has an undefined __libc_message
>> >> >__libc_message fetches libc_pic.a(libc_fatal.os)
>> >> >
>> >> >libc_fatal.os will cause a multiple definition error (__GI___libc_fatal)
>> >> >>>>defined at dl-fxstatat64.c
>> >> >>>> /tmp/p/glibc/Release/elf/dl-allobjs.os:(__GI___libc_fatal)
>> >> >>>>defined at libc_fatal.c
>> >> >>>> libc_fatal.os:(.text+0x240) in archive
>> >> >>>> /tmp/p/glibc/Release/libc_pic.a
>> >> >
>> >> >glibc/elf/Makefile uses -Wl,--defsym= (rtld-stubbed-symbols) to suppress
>> >> >libc_pic.a(malloc.os):
>> >> >
>> >> >% readelf -s elf/librtld.map.o | grep ABS | grep -v LOCAL
>> >> > 712: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS
>> >> > __stack_chk_fail_local
>> >> > 826: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS malloc
>> >> > 876: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS
>> >> > __stack_chk_fail
>> >> > 905: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS calloc
>> >> > 975: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS realloc
>> >> > 1174: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS free
>> >> >
>> >> >My question is: does the suppression via --defsym work reliably?
>> >> >
>> >> ># a.o
>> >> >call foo
>> >> >
>> >> ># b.a(b.o)
>> >> >.globl foo, free
>> >> >foo:
>> >> >free:
>> >> >
>> >> >
>> >> ># GNU ld --defsym is order dependent.
>> >> >ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>> >> >ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>> >> >
>> >> ># gold --defsym is order independent. For the more complex glibc
>> >> >elf/librtld.map.o case, it happens to match GNU ld.
>> >> >gold a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>> >> >gold --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>> >> >
>> >> ># lld --defsym is order independent. --defsym is processed the last. For
>> >> ># elf/librtld.map.o it will report a multiple definition error.
>> >> ># https://sourceware.org/pipermail/libc-alpha/2020-March/111899.html is
>> >> ># required to bypass a configure check
>> >> >ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is not fetched. free is absent
>> >> >ld.lld --defsym=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>> >>
>> >> Sorry, clarify the behavior of lld.
>> >>
>> >> # lld --defsym is order independent. --defsym is processed the last. For
>> >> elf/librtld.map.o it will report a multiple definition error.
>> >> ld.lld a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>> >> ld.lld --defsym=0 a.o b.a # b.a(b.o) is fetched. free is present
>> >
>> >Glibc build requires a linker compatible with ld. Can you provide an lld
>> >option to make lld compatible with ld for cases like this?
>>
>> As a contributor of lld, I would be cooperative and be happy to adapt lld if
>> the proposed semantic is reasonable.
>>
>> I am concerned that the --defsym's order dependence with archive files is not
>> so obvious, given -u's behavior:
>>
>> # -u inserts an undefined which fetches b.a(b.o)
>> ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
>> # This can't be order dependent because b.a (not in a group) should have been
>> dropped when we saw -u
>> ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
>>
>> Some observations:
>>
>>
>> # GNU ld --defsym interacts with an archive
>> ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>> ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>
>I consider this the correct linker behaviour. In that sense I would
>consider the inconsistency with -u and -T to be the problems of those, not
>a problem of --defsym (but not necessarily problems we can fix anymore, as
>people might rely on that). (i.e. I think the second -u command above
>should result in an 'undefined foo' output/error, not in b.a(b.o) being
>fetched).
>
>I consider the above to be correct because this is how traditional link
>editors behave with respect to archives: ordering of file arguments does
>matter (obviously between .o and .a, but also between multiple .a and even
>between .o (think static initializers)). And if you interpret '--defsym
>bla' as "object file defining symbol bla" and '-u foo' as "object file
>containing reference to foo" the behaviour for --defsym naturally follows
>(and makes the behaviour of -u be the inconsistence).
Symbol assignments in -T can override symbols in object files.
PROVIDE(...) is still effectful if -T comes before the object file.
The two facts imply that symbol assignments in -T can be considered
sorta order independent with regard to symbols in other files.
The model is that ad-hoc symbol resolution (symbol assignments in -T,
--defsym, -u, --export-dynamic-symbol) happens after archive file resolution.
>For this reasoning it's immaterial that --defsym accepts expressions: the
>evaluation of them can be delayed until cmdline arguments are processed.
>But the point of definition or reference should be their place in the
>cmdline.
>
>How that interacts with -T: well, in an ideal world I don't see why those
>shouldn't also be processed in order and at their place within the command
>line (i.e. file arguments before it are available and processed, file
>arguments after it aren't yet), again with the caveat that RHS expressions
>might be evaluated late, but name references or definitions happen
>immediately). But as said, we might not be able to change ld such that
>this is the case for compat reasons.
It is actually possible for GNU ld's symbol resolution rules to behave
more like gold and lld. The amount of work can be large, but it can
improve consistency and simplify the internals.
>> If we aim for robustness and make the librtld.map.o trick supported (I will
>> add a note that gold happens to work),
>> I will hope both the following can suppress b.a(b.o):
>>
>> ld.bfd a.o b.a --defsym foo=0
>> ld.bfd --defsym foo=0 a.o b.a
>
>And I would hope that the above two would _not_ be made to behave the
>same.
>
>
>Ciao,
>Michael.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-03-16 19:05 ` Michael Matz
2020-03-21 16:39 ` Fangrui Song
@ 2020-04-11 17:04 ` Florian Weimer
2020-04-11 18:16 ` Fangrui Song
1 sibling, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2020-04-11 17:04 UTC (permalink / raw)
To: Michael Matz; +Cc: Fangrui Song, GNU C Library, Binutils
* Michael Matz:
> On Mon, 16 Mar 2020, Fangrui Song via Binutils wrote:
>> I am concerned that the --defsym's order dependence with archive files is not
>> so obvious, given -u's behavior:
>>
>> # -u inserts an undefined which fetches b.a(b.o)
>> ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
>> # This can't be order dependent because b.a (not in a group) should have been
>> dropped when we saw -u
>> ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
>>
>> Some observations:
>>
>>
>> # GNU ld --defsym interacts with an archive
>> ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>> ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>
> I consider this the correct linker behaviour. In that sense I would
> consider the inconsistency with -u and -T to be the problems of those, not
> a problem of --defsym (but not necessarily problems we can fix anymore, as
> people might rely on that). (i.e. I think the second -u command above
> should result in an 'undefined foo' output/error, not in b.a(b.o) being
> fetched).
I agree, the ld.bfd behavior seems the most reasonable one to me.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o)
2020-04-11 17:04 ` Florian Weimer
@ 2020-04-11 18:16 ` Fangrui Song
0 siblings, 0 replies; 10+ messages in thread
From: Fangrui Song @ 2020-04-11 18:16 UTC (permalink / raw)
To: Florian Weimer; +Cc: Michael Matz, GNU C Library, Binutils, Fangrui Song
On 2020-04-11, Florian Weimer wrote:
>* Michael Matz:
>
>> On Mon, 16 Mar 2020, Fangrui Song via Binutils wrote:
>>> I am concerned that the --defsym's order dependence with archive files is not
>>> so obvious, given -u's behavior:
>>>
>>> # -u inserts an undefined which fetches b.a(b.o)
>>> ld.bfd -u foo b.a # b.a(b.o) is fetched. free is present
>>> # This can't be order dependent because b.a (not in a group) should have been
>>> dropped when we saw -u
>>> ld.bfd b.a -u foo # b.a(b.o) is fetched. free is present
>>>
>>> Some observations:
>>>
>>>
>>> # GNU ld --defsym interacts with an archive
>>> ld.bfd a.o b.a --defsym foo=0 # b.a(b.o) is fetched. free is present
>>> ld.bfd --defsym foo=0 a.o b.a # b.a(b.o) is not fetched. free is absent
>>
>> I consider this the correct linker behaviour. In that sense I would
>> consider the inconsistency with -u and -T to be the problems of those, not
>> a problem of --defsym (but not necessarily problems we can fix anymore, as
>> people might rely on that). (i.e. I think the second -u command above
>> should result in an 'undefined foo' output/error, not in b.a(b.o) being
>> fetched).
>
>I agree, the ld.bfd behavior seems the most reasonable one to me.
ld accepts two types of command line arguments: input files / options.
Examples of order dependency between two input files:
* an earlier archive member can override a subsequent archive member
* a shared object can suppress the fetch of a subsequent archive member
* a fetched archive member (turns to an object file) overrides a shared object
Examples of order dependency between an input file and an option:
* --as-needed --no-as-needed
* --whole-archive --no-whole-archive
* --start-lib --end-lib
* -Bdynamic -Bstatic -static (I am saddened by https://sourceware.org/pipermail/binutils/2020-March/000110.html)
* --start-group --end-group
I acknowledge all the above. However, a large set of options have no
order dependency issues.
* --allow-shlib-undefined
* --dynamic-list
* --version-script
* --apply-dynamic-relocs
* --omagic
* ...
* -u
* --export-dynamic-symbol
* --exclude-libs
I am glad the options are designed this way, otherwise in people's build
systems they could notice many more hard-to-diagnose problems.
As my very first message said, if GNU ld had --start-lib for a long time
(feature request: https://sourceware.org/bugzilla/show_bug.cgi?id=24600), this shadowing
malloc.o definition issue can be fixed very elegantly.
Now, we don't have --start-lib for GNU ld, but we can probably use GNU
ar thin archives as an alternative. The Linux kernel makes use of a
similar trick.
------- Random out of topic comments
In FreeBSD ports, 32k pieces of software just work, 130+ packages are
marked as LLD_UNSAFE, but many should be safe (need developers' testing)
as of lld 9. It is very likely none of the packages makes use of the
--defsym feature.
Most configurations of x86/x86-64/aarch64/ppc64le/ppc64le ports of the
Linux kernel link fine with LLD.
Making glibc compilable/linkable with clang/LLD is not at all my work
requirement. It is simply I want to earn myself some contributions + I
don't want glibc to be tied to very specific toolchain. I started with
LLD because it is the relatively easy task. Clang compilability is more
troublesome. If I feel sufficient enmity, I will surely stop.
I tried stripping down LLD yesterday, just wanted to know how much code
is sufficient as the core https://github.com/MaskRay/picolld WoW, 18000+
LOC is capable to keep x86/ARM/AArch64/PPC ports and most functionality.
The GNU ld core probably really needs a refinement.
I have been thinking how to detect discrepancy between lld's and
traditional linkers' resolution rules. (The FreeBSD ports stats tell us
the "order dependency" issues are very few.) https://reviews.llvm.org/D77512
I am saddened that for some bug reports/enhancement proposals, the
initial reaction of some people in the community is usually "this is not
a bug." "this is an LLD bug" "GCC does this, so clang should do this as well."
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94391 is an awesome recent
showcase. It was then followed by an unfounded "NO LLD is not
implemented the ABI as PIE COPYRELOC is required by ABI these days".
The status was updated back and forth between "invalid", "wontfix" and
"worksforme" until a maintainer realized GNU ld had indeed one bug
(R_X86_64_[REX_]GOTPCRELX cannot be relaxed for SHN_ABS) and one
enhancement (PC relative relocations to a non-preemptible symbol should
be rejected). No one is probably willing to admit that LLD is good, though.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2020-04-11 18:16 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-16 4:58 Suppress the fetch of an archive member via --defsym (glibc/elf/librtld.map.o) Fangrui Song
2020-03-16 5:02 ` Fangrui Song
2020-03-16 11:27 ` H.J. Lu
2020-03-16 15:47 ` Fangrui Song
2020-03-16 16:01 ` H.J. Lu
2020-03-16 18:31 ` Fangrui Song
2020-03-16 19:05 ` Michael Matz
2020-03-21 16:39 ` Fangrui Song
2020-04-11 17:04 ` Florian Weimer
2020-04-11 18:16 ` Fangrui Song
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).