Why GROUP(...) rather than INPUT(...) is used here?
rednoah
rednoax@163.com
Wed Nov 22 00:00:51 GMT 2023
Hi Nick:
I got it. Thanks very much for your detailed explanation.
regards
At 2023-11-20 23:23:06, "Nick Clifton" <nickc@redhat.com> wrote:
>Hi rednoah,
>
>> GROUP ( libgcc_s.so.1 -lgcc )
>>
>> The "-lgcc" linked here is actually libgcc.a. "libgcc_s.so.1" is an elf
>> shared object so there is only one archive file "libgcc.a" in GROUP(...).
>> GROUP(...) equals to "--start-group ... --end-group" and it is to enclose
>> two or more archive files to search undefined symbols repeatedly. There
>> seems no need to uss it when there is only one archive file in it. Maybe
>> INPUT(...) is a better choice here?
>
>Well... there is a theoretical difference. The thing is, the GROUP
>construct means that if there is code in libgcc.a that needs functions
>provided by libgcc_s.so.1 then it will be included even if there are
>no other code that needs libgcc_s.so.1.
>
>Here is a rather contrived example:
>
> $ cat main.c
>
> extern void atexit (int);
> int __dso_handle;
> int main (void)
> {
> atexit (0);
> return 0;
> }
>
> $ cat /usr/lib64/libc.so
>
> /* GNU ld script
> Use the shared library, but some functions are only in
> the static library, so try that secondarily. */
> OUTPUT_FORMAT(elf64-x86-64)
> GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
>
>I am running this test on my Fedora 38 box, so the libraries are
>slightly different from the ones you are using, but the test does
>show my first point which is that main.c does not call any
>functions in the shared C library (libc.so.6) but it does call
>a function in the static C library (libc_nonshared.a):
>
>So, if I compile and then link my program with the "libc.so" fake
>C library, everything works:
>
> $ gcc -c -fPIC main.c
> $ ld -e 0 main.o -L/usr/lib64 --as-needed -lc
>
>The GROUP command has caused the linker to deduce that the real
>shared C library is needed:
>
> $ ldd a.out
> linux-vdso.so.1 (0x00007fff6665e000)
> libc.so.6 => /lib64/libc.so.6 (0x000014fb0b800000)
> /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x000014fb0b9f9000)
>
>But if I create an alternative version of libc.so that uses INPUT
>directives instead of a GROUP directive:
>
> $ cat libfred.so
>
> /* GNU ld script
> Use the shared library, but some functions are only in
> the static library, so try that secondarily. */
> OUTPUT_FORMAT(elf64-x86-64)
> INPUT(/lib64/libc.so.6)
> GROUP(/usr/lib64/libc_nonshared.a)
> INPUT(/lib64/ld-linux-x86-64.so.2)
>
>and then try to use it...
>
> $ ld -e 0 main.o -L/usr/lib64 --as-needed -L. -lfred
> ld: /usr/lib64/libc_nonshared.a(atexit.oS): in function `atexit':
> (.text+0xe): undefined reference to `__cxa_atexit'
>
>...the link fails.
>
>Of course this can be fixed by moving the INPUT(/lib64/libc.so.6)
>to after the GROUP(/usr/lib64/libc_nonshared.a). But what if there
>is a function in libc.so.6 that needs code in libc_nonshared.a ?
>
>This is all mostly theoretical of course, since in real life
>these circumstances are very unlikely to occur. But why take the
>chance ? Using GROUP() works just as well as INPUT(), does not
>cost much more (since there is only one static library involved
>and it is not that big), and it means that the glibc maintainers
>do not have to worry about some future scenario where an unexpected
>dependency between the libraries does occur.
>
>Cheers
> Nick
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20231122/3ce1f387/attachment.htm>
More information about the Binutils
mailing list