Bug 26530

Summary: Inconsistency in between bfd and gold about -Wl,--as-needed
Product: binutils Reporter: Martin Liska <mliska>
Component: ldAssignee: Alan Modra <amodra>
Status: RESOLVED FIXED    
Severity: normal CC: hjl.tools, matz
Priority: P2    
Version: 2.34   
Target Milestone: 2.36   
Host: Target:
Build: Last reconfirmed: 2020-08-25 00:00:00
Attachments: A testcase

Description Martin Liska 2020-08-25 07:26:48 UTC
Let's consider the following example:

$ cat foo.c
const char *lrealpath(const char *a)
{
  return a;
}

$ cat main.c
const char *lrealpath(const char *a);

int main(int argc, char **argv)
{
  lrealpath (argv[0]);
}

$ gcc foo.c -fPIC -flto -c
$ ar r libtest.a foo.o
$ gcc -o libfoo.so foo.o -shared

$ gcc main.o -Wl,--as-needed libfoo.so libtest.a --save-temps -fuse-ld=bfd -L. && cat libtest.res
2
main.o 2
200 6e870bd31e7efa23 PREVAILING_DEF main
206 6e870bd31e7efa23 RESOLVED_IR lrealpath
libtest.a@0x92 1
199 76b392265247fa61 PREVAILING_DEF_IRONLY_EXP lrealpath

while gold does:

$ gcc main.o -Wl,--as-needed libfoo.so libtest.a --save-temps -fuse-ld=gold -L. && cat libtest.res
1
main.o 2
200 6e870bd31e7efa23 PREVAILING_DEF main
206 6e870bd31e7efa23 RESOLVED_DYN lrealpath

So BFD takes symbols from LTO IR while GOLD takes them from the shared library.
Comment 1 Michael Matz 2020-08-25 12:22:03 UTC
FWIW, I think the gold behaviour is the correct one.  The order of libraries
on the cmdline is significant, and libfoo.so does fulfill the symbol request, so the object from libtest.a shouldn't be considered.  No matter if LTO is or isn't
involved.  (In fact also bfd ld doesn't use the archive without LTO mode)
Comment 2 H.J. Lu 2020-08-25 13:08:01 UTC
Created attachment 12794 [details]
A testcase

$ make
gcc -B./ -O2 -g -flto -c -o pr26530c.o pr26530c.c
gcc -B./ -O2 -g -fPIC -c -o pr26530a.o pr26530a.c
gcc -B./ -shared -o libpr26530.so pr26530a.o
gcc -B./ -O2 -g -c -o pr26530b.o pr26530b.c
ar rc -o libpr26530.a pr26530b.o
gcc -B./ -Wl,--as-needed -o x pr26530c.o libpr26530.so libpr26530.a -Wl,-R,.
./x
make: *** [Makefile:14: all] Aborted (core dumped)
Comment 3 H.J. Lu 2020-08-25 17:29:52 UTC
A patch is posted at

https://sourceware.org/pipermail/binutils/2020-August/112996.html
Comment 4 Sourceware Commits 2020-09-04 07:25:05 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1e3b96fd6cf0c7d018083994ad951ccf92aba582

commit 1e3b96fd6cf0c7d018083994ad951ccf92aba582
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Sep 4 13:54:21 2020 +0930

    Allow plugin syms to mark as-needed shared libs needed
    
    We must tell LTO about symbols in all shared libraries loaded.  That
    means we can't load extra shared libraries after LTO recompilation, at
    least, not those that affect the set of symbols that LTO cares about,
    the IR symbols.
    
    This change will likely result in complaints about --as-needed
    libraries being loaded unnecessarily, but being correct is more
    important than being optimal.  One of the PR15146 tests regresses, and
    while that could be hidden by disabling the missing dso message by
    making it conditional on h->root.non_ir_ref_regular, that would just
    be sweeping a problem under the rug.
    
    bfd/
            PR 15146
            PR 26314
            PR 26530
            * elflink.c (elf_link_add_object_symbols): Do set def_regular
            and ref_regular for IR symbols.  Don't clear dynsym, allowing
            IR symbols to load --as-needed shared libraries, but prevent
            IR symbols from becoming dynamic.
    ld/
            * testsuite/ld-plugin/lto.exp: Don't run pr15146 tests.
            * testsuite/ld-plugin/pr15146.d: Delete.
            * testsuite/ld-plugin/pr15146a.c: Delete.
            * testsuite/ld-plugin/pr15146b.c: Delete.
            * testsuite/ld-plugin/pr15146c.c: Delete.
            * testsuite/ld-plugin/pr15146d.c: Delete.
Comment 5 Alan Modra 2020-09-04 07:38:29 UTC
Fixed.
Comment 6 Sourceware Commits 2020-11-01 23:14:43 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b1a92c635c1ec10fd703302ce1fc4ab3a8515a04

commit b1a92c635c1ec10fd703302ce1fc4ab3a8515a04
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Oct 30 14:56:35 2020 +1030

    PR26806, Suspected linker bug with LTO
    
    This patch reverts most of git commit 1e3b96fd6cf, so IR symbols are
    again not marked def_regular or ref_regular.  That should be enough to
    stop IR symbols from becoming dynamic.  To mark as-needed shared
    libraries referenced by IR symbols, use the referencing BFD rather
    than the ref flags.
    
    bfd/
            PR 15146
            PR 26314
            PR 26530
            PR 26806
            * elflink.c (elf_link_add_object_symbols): Don't set def/ref flags
            for plugin syms.  Do allow plugin syms to mark as-needed libs.
    ld/
            PR 26806
            * testsuite/ld-plugin/lto-19.h,
            * testsuite/ld-plugin/lto-19a.c,
            * testsuite/ld-plugin/lto-19b.c,
            * testsuite/ld-plugin/lto-19c.c: New test.
            * testsuite/ld-plugin/pr26806.c,
            * testsuite/ld-plugin/pr26806.d: New test.
            * testsuite/ld-plugin/lto.exp: Run them.