public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Nick Clifton <nickc@redhat.com>
To: rednoah <rednoax@163.com>, binutils@sourceware.org
Subject: Re: Why GROUP(...) rather than INPUT(...) is used here?
Date: Mon, 20 Nov 2023 15:23:06 +0000	[thread overview]
Message-ID: <08886f47-a7c7-4a82-98b4-2d5588df25e2@redhat.com> (raw)
In-Reply-To: <18014862.5f25.18bdcad7f2b.Coremail.rednoax@163.com>

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






  reply	other threads:[~2023-11-20 15:23 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-17  9:47 rednoah
2023-11-20 15:23 ` Nick Clifton [this message]
2023-11-22  0:00   ` rednoah

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=08886f47-a7c7-4a82-98b4-2d5588df25e2@redhat.com \
    --to=nickc@redhat.com \
    --cc=binutils@sourceware.org \
    --cc=rednoax@163.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).