Bug 56431 - -lpthread should be added to -lgo
Summary: -lpthread should be added to -lgo
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: go (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Ian Lance Taylor
URL:
Keywords:
Depends on: 56353
Blocks:
  Show dependency treegraph
 
Reported: 2013-02-22 23:44 UTC by H.J. Lu
Modified: 2019-01-16 22:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2013-02-22 23:44:40 UTC
+++ This bug was initially created as a clone of Bug #56353 +++

libjava.jni/invocation/PR16923.c behaves differently, depending
on linking with gold or ld. _Jv_RegisterClasses is weak reference
and libgcj.so isn't on the linker command line. Since libgcj.so isn't
on the linker command line, gold resolves _Jv_RegisterClasses to 0 and
ld silently resolves it to _Jv_RegisterClasses in libgcj.so:

[hjl@gnu-13 testsuite]$ readelf -sWr /tmp/PR16923.gold | grep _Jv_RegisterClasses 
     8: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    37: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
[hjl@gnu-13 testsuite]$ readelf -sWr /tmp/PR16923.bfd | grep _Jv_RegisterClasses 
0000000000600cd0  0000000900000007 R_X86_64_JUMP_SLOT     00000000004005e0 _Jv_RegisterClasses + 0
     9: 00000000004005e0     0 FUNC    WEAK   DEFAULT  UND _Jv_RegisterClasses
    59: 00000000004005e0     0 FUNC    WEAK   DEFAULT  UND _Jv_RegisterClasses
[hjl@gnu-13 testsuite]$]

-lgo has the same issue.  With the bfd linker, I got

[hjl@gnu-mic-2 go]$ ld --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /lib/../lib/crt1.o /lib/../lib/crti.o /export/build/gnu/gcc-asan/build-x86_64-linux/gcc/testsuite/go/../../32/crtbegin.o -L/export/build/gnu/gcc-asan/build-x86_64-linux/x86_64-unknown-linux-gnu/32/libgo -L/export/build/gnu/gcc-asan/build-x86_64-linux/x86_64-unknown-linux-gnu/32/libgo/.libs -L/export/build/gnu/gcc-asan/build-x86_64-linux/gcc/testsuite/go/../../32 -L/lib/../lib -L/usr/lib/../lib -L/export/build/gnu/gcc-asan/build-x86_64-linux/gcc/testsuite/go/../.. array-1.o -lgobegin -lgo -lm --wrap=pthread_create -lgcc_s -lgcc -lc -lgcc_s -lgcc /export/build/gnu/gcc-asan/build-x86_64-linux/gcc/testsuite/go/../../32/crtend.o /lib/../lib/crtn.o
ld: /export/build/gnu/gcc-asan/build-x86_64-linux/gcc/testsuite/go/../../32/libgcc.a(generic-morestack.o): undefined reference to symbol 'pthread_sigmask@@GLIBC_2.0'
ld: note: 'pthread_sigmask@@GLIBC_2.0' is defined in DSO /lib/libpthread.so.0 so try adding it to the linker command line
/lib/libpthread.so.0: could not read symbols: Invalid operation
[hjl@gnu-mic-2 go]$ 

gold links, but it generates

    51: 00000000     0 NOTYPE  WEAK   DEFAULT  UND pthread_sigmask

It means that go executables generated by bfd ld and gold may behave
differently.  Go driver should add -lpthread to -lgo if libgo.so is
linked against libpthread.so.
Comment 1 Ian Lance Taylor 2013-02-27 14:54:22 UTC
The reference to pthread_sigmask in generic-morestack.c is weak, and the code handles the weak reference correctly.  It looks like gold is doing the right thing by emitting a weak reference.

I don't understand why GNU ld is complaining about an undefined weak reference.  As far as I can see, this is a GNU ld bug; it should be testing h->ref_regular_nonweak in the code that issues this "is defined in DSO" warning.
Comment 2 H.J. Lu 2013-02-27 16:59:17 UTC
The new GNU ld is complaining about an undefined weak reference because
it sees libpthread.so from DT_NEEDED in libgo.so. The old GNU ld just
silently adds libpthread.so from DT_NEEDED in libgo.so.  When creating
executables, GNU ld checks DT_NEEDED in DSOes on command line.  Since
libpthread.so is included from libgo.so for creating executables, it expects
libpthread.so will be used and pthread_sigmask is defined at run-time
Comment 3 Ian Lance Taylor 2013-02-27 18:49:43 UTC
Object OBJ has a weak reference to SYM.

OBJ is linked against shared library S1.  S1 does not define SYM.

S1 happens to be linked against shared library S2.  S2 does define SYM.

That will work fine: at runtime OBJ will see that SYM is defined, because S1 brings in S2.

Suppose that, later on, S1 is not linked against S2.  That will also work fine: at runtime OBJ will see that SYM is not defined.

Right now GNU ld is issuing a warning because it sees that the weak reference from OBJ will be defined at runtime by S2, brought in at runtime because S1 is linked against S2.  GNU ld is suggesting that OBJ should be linked against S2 directly.  But nothing will go wrong if S1 is changed such that it does not link against S2.

Therefore, GNU ld's warning is inappropriate.  There is no reason to link OBJ against S2 in this case.
Comment 4 H.J. Lu 2013-02-27 19:36:07 UTC
(In reply to comment #3)
> Object OBJ has a weak reference to SYM.
> 
> OBJ is linked against shared library S1.  S1 does not define SYM.
> 
> S1 happens to be linked against shared library S2.  S2 does define SYM.
> 
> That will work fine: at runtime OBJ will see that SYM is defined, because S1
> brings in S2.
> 

This isn't what happens.  Since gold doesn't check S2 at link-time, it
resolves SYM to 0:

[hjl@gnu-6 pr15149]$ cat foo.c 
#include <stdio.h>

extern int xxx () __attribute__((weak));

int
foo ()
{
  if (&xxx)
    return xxx ();
  return 1;
}

int
main ()
{
  printf ("xxx: %d\n", foo ());
  return 0;
}
[hjl@gnu-6 pr15149]$ cat xxx.c
int
xxx ()
{
  return 0;
}
[hjl@gnu-6 pr15149]$ cat yyy.c
/* Dummy */
[hjl@gnu-6 pr15149]$ make y
gcc -Wl,--no-copy-dt-needed-entries    -c -o foo.o foo.c
gcc -Wl,--no-copy-dt-needed-entries -shared -fPIC -o libxxx.so xxx.c
gcc -Wl,--no-copy-dt-needed-entries -shared -fPIC -o libyyy.so yyy.c libxxx.so -Wl,-rpath,.
gcc -Wl,--no-copy-dt-needed-entries -fuse-ld=gold -B./ -Wl,--no-as-needed -o y foo.o libyyy.so -Wl,-rpath,.
[hjl@gnu-6 pr15149]$ ./y
xxx: 1
[hjl@gnu-6 pr15149]$ 

38: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND xxx

If gold sees SYM defined in S2, it will create a R_X86_64_JUMP_SLO relocation, set xxx value to the PLT entry and resolve xxx to the PLT entry.

000000401ad0  000700000007 R_X86_64_JUMP_SLO 0000000000400570 xxx + 0

7: 0000000000400570     0 FUNC    WEAK   DEFAULT  UND xxx

That is the difference between seeing SYM in S2 or not.
Comment 5 Ian Lance Taylor 2013-02-27 21:07:59 UTC
I see.  Interesting.  I wonder if that is a bug in gold.  I wonder what other ELF linkers do.
Comment 6 H.J. Lu 2013-02-27 21:20:53 UTC
(In reply to comment #5)
> I see.  Interesting.  I wonder if that is a bug in gold.  I wonder what other

I think this is related to the gold bug:

http://sourceware.org/bugzilla/show_bug.cgi?id=15153

> ELF linkers do.

On Linux, ld and gold set the standard.
Comment 7 Rainer Orth 2018-12-10 12:48:45 UTC
I'm seeing the same link error on Linux/x86_64 on mainline when configured with
--disable-shared:

/vol/gcc/bin/gld-2.31: /var/gcc/regression/trunk/4.17.3-gcc-gas-gld/build/./gcc/libgcc.a(generic-morestack.o): in function `__morestack_block_signals':
/vol/gcc/src/hg/trunk/local/libgcc/generic-morestack.c:661: undefined reference to `pthread_sigmask'

linking e.g. test2json.
Comment 8 Ian Lance Taylor 2019-01-16 22:32:38 UTC
The workaround for this is probably to change gcc/go/gospec.c to remove the need_thread variable.  That would have the effect of changing the only use of need_thread to only test library > 0, which would mean that gccgo would add -lpthread every time it adds -lgo.  (I don't plan to try implementing and testing this myself.)