Bug 815 - [C-api -> C++ lib] undefined symbol _Unwind*
Summary: [C-api -> C++ lib] undefined symbol _Unwind*
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.15
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-02 08:46 UTC by Pawel Sikora
Modified: 2005-04-15 11:19 UTC (History)
4 users (show)

See Also:
Host: i686-pld-linux
Target: i686-pld-linux
Build: i686-pld-linux
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pawel Sikora 2005-04-02 08:46:50 UTC
# cat foo.h  
struct foo { bool check() const; };  
  
# cat foo.cpp  
#include "foo.h"  
bool foo::check() const { return true; }  
  
# cat foo-c.cpp  
#include "foo.h"  
extern "C" int foo_check(const foo* obj) { return obj->check(); } 
 
# build 
g++ -O2 foo.cpp -o libfoo.so -shared 
g++ -O2 foo-c.cpp -o libfoo-c.so -shared -L. -lfoo 
# link test 
gcc libfoo.so 
LD_LIBRARY_PATH=./ gcc libfoo-c.so 
 
# with binutils-2.15.94* it works fine 
 
2x: 
 
/usr/lib/gcc/i686-pld-linux/4.0.0/../../../crt1.o(.text+0x18): 
In function `_start': init.c: undefined reference to `main' 
collect2: ld returned 1 exit status 
 
# LD_LIBRARY_PATH=. ldd libfoo*.so 
libfoo-c.so: 
        linux-gate.so.1 =>  (0xffffe000) 
        libfoo.so => ./libfoo.so (0x40002000) 
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40004000) 
        libm.so.6 => /lib/libm.so.6 (0x400d4000) 
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400f8000) 
        libc.so.6 => /lib/libc.so.6 (0x40103000) 
        /lib/ld-linux.so.2 (0x80000000) 
libfoo.so: 
        linux-gate.so.1 =>  (0xffffe000) 
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40002000) 
        libm.so.6 => /lib/libm.so.6 (0x400d2000) 
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400f6000) 
        libc.so.6 => /lib/libc.so.6 (0x40101000) 
        /lib/ld-linux.so.2 (0x80000000) 
 
# with binutils snapshot it doesn't work 
(ftp://sources.redhat.com/pub/binutils/snapshots2.15.96) 
 
2x: 
 
/usr/lib/gcc/i686-pld-linux/4.0.0/../../../crt1.o: 
In function `_start': 
init.c:(.text+0x18): undefined reference to `main' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_DeleteException@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_Resume@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_RaiseException@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_GetRegionStart@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_GetDataRelBase@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_SetGR@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_GetLanguageSpecificData@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_Resume_or_Rethrow@GCC_3.3' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_GetIP@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_GetTextRelBase@GCC_3.0' 
/usr/bin/../lib/libstdc++.so.6: 
undefined reference to `_Unwind_SetIP@GCC_3.0' 
collect2: ld returned 1 exit status 
 
# LD_LIBRARY_PATH=. ldd libfoo*.so 
libfoo-c.so: 
        linux-gate.so.1 =>  (0xffffe000) 
        libfoo.so => ./libfoo.so (0x40002000) 
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40004000) 
        libm.so.6 => /lib/libm.so.6 (0x400d4000) 
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400f8000) 
        libc.so.6 => /lib/libc.so.6 (0x40103000) 
        /lib/ld-linux.so.2 (0x80000000) 
libfoo.so: 
        linux-gate.so.1 =>  (0xffffe000) 
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40002000) 
        libm.so.6 => /lib/libm.so.6 (0x400d2000) 
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x400f6000) 
        libc.so.6 => /lib/libc.so.6 (0x40101000) 
        /lib/ld-linux.so.2 (0x80000000) 
 
Do I need add the -lstdc++ to link similiar C-apis now?
Comment 1 Pawel Sikora 2005-04-04 16:20:19 UTC
another testcase: 
 
binutils-2.15.96) 
# gcc emptymain.c -L/usr/X11R6/lib/ -lXext 
/lib/libdl.so.2: undefined reference to `_rtld_global@GLIBC_PRIVATE' 
/lib/libdl.so.2: undefined reference to `_rtld_global_ro@GLIBC_PRIVATE' 
/lib/libdl.so.2: undefined reference to `_dl_rtld_di_serinfo@GLIBC_PRIVATE' 
collect2: ld returned 1 exit status 
 
binutils-2.15.94.0.2.2) 
# gcc emptymain.c -L/usr/X11R6/lib/ -lXext 
 
Comment 2 Jürg Billeter 2005-04-13 09:15:04 UTC
Problem appears when using --as-needed as e.g. gcc inserts automatically around
-lgcc_s. It seems to have been introduced by
http://sourceware.org/ml/binutils-cvs/2005-02/msg00008.html and happens with FSF
binutils 2.15.96 and HJ Lu binutils 2.16.90.0.1
Comment 3 Greg Schafer 2005-04-13 11:04:00 UTC
This seems to be the cause of build failure when compiling xorg-6.8.2:

gcc -m32 -o glxinfo -O2 -march=i686 -fno-strict-aliasing -ansi -pedantic
-Wall -Wpointer-arith -Wundef     -L../../exports/lib   glxinfo.o -lGLU -lGL
-lXext -lX11  -lpthread -lm   -Wl,-rpath-link,../../exports/lib
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_DeleteException@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to `_Unwind_Resume@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_RaiseException@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_GetRegionStart@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_GetDataRelBase@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to `_Unwind_SetGR@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_GetLanguageSpecificData@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_Resume_or_Rethrow@GCC_3.3'
/usr/bin/../lib/libstdc++.so.6: undefined reference to `_Unwind_GetIP@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to
`_Unwind_GetTextRelBase@GCC_3.0'
/usr/bin/../lib/libstdc++.so.6: undefined reference to `_Unwind_SetIP@GCC_3.0'
collect2: ld returned 1 exit status
make[4]: *** [glxinfo] Error 1

This is with HJL binutils-2.16.90.0.1 on i686-pc-linux-gnu.
Thanks.
Comment 4 Alan Modra 2005-04-13 13:34:08 UTC
Please try latest mainline binutils.  My 2005-04-11 ld/emultempl/elf32.em patch
may well have fixed this problem.
Comment 5 Jürg Billeter 2005-04-13 16:39:07 UTC
Part of the problem seems to have been solved in latest binutils mainline, i.e.
the first test case works fine now.

But linking glxinfo of Xorg 6.8.2 still fails although with other error messages:

gcc -m32 -o glxinfo -O2 -fno-strength-reduce -fno-strict-aliasing -ansi
-pedantic -Wall -Wpointer-arith -Wundef     -L../../exports/lib   glxinfo.o
-lGLU -lGL -lXext -lX11  -lpthread -lm
/usr/bin/ld: warning: libXxf86vm.so.1, needed by ../../exports/lib/libGL.so, not
found (try using -rpath or -rpath-link)
../../exports/lib/libGL.so: undefined reference to `XF86VidModeQueryVersion'
../../exports/lib/libGL.so: undefined reference to `XF86VidModeGetModeLine'
collect2: ld returned 1 exit status
make[4]: *** [glxinfo] Error 1
make[4]: Leaving directory `/usr/src/X11R6.8.2-src/programs/glxinfo'
make[3]: *** [all] Error 2
make[3]: Leaving directory `/usr/src/X11R6.8.2-src/programs'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/usr/src/X11R6.8.2-src'
make[1]: *** [World] Error 2
make[1]: Leaving directory `/usr/src/X11R6.8.2-src'
make: *** [World] Error 2
Comment 6 Pawel Sikora 2005-04-13 22:24:36 UTC
(In reply to comment #4) 
> Please try latest mainline binutils.  My 2005-04-11 ld/emultempl/elf32.em 
patch 
> may well have fixed this problem. 
 
 
I've built the binutils-2.16.90.0.1 with patch from ML: 
 
"Date: Tue, 12 Apr 2005 00:00:15 +0930 
From: Alan Modra <amodra at bigpond dot net dot au> 
To: binutils at sources dot redhat dot com 
Subject: AS_NEEDED failure" 
 
and ld links glxinfo fine but linker fails on wmfplugin from kdelibs: 
 
/bin/sh ../libtool --silent --tag=CXX --mode=link i686-pld-linux-g++ 
-Wnon-virtual-dtor -Wno-long-long -Wundef -ansi -D_XOPEN_SOURCE=500 
-D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W 
-Wpointer-arith -Wwrite-strings -DNDEBUG -DNO_DEBUG -O2 -O2 -march=i686 
-mtune=pentium4 -fomit-frame-pointer -fvisibility-inlines-hidden -pipe 
-Wl,--as-needed -Wformat-security -Wmissing-format-attribute -fno-exceptions 
-fno-check-new -fno-common -fno-exceptions -fno-check-new -fno-common 
-fvisibility=hidden -fvisibility-inlines-hidden  -DQT_CLEAN_NAMESPACE 
-DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION 
-z combreloc -o wmfthumbnail.la -rpath /usr/lib/kde3 -module -L/usr/lib 
-L/usr/X11R6/lib    -avoid-version -module -no-undefined -Wl,--no-undefined 
-Wl,--allow-shlib-undefined   wmfthumbnail_la.all_cpp.lo  ../kio/libkio.la 
-L/usr/lib -lwmf -lwmflite -lfreetype -lz -L/usr/X11R6/lib -lSM -lICE -lX11 
-lexpat -ljpeg -lpng -lz -lm 
 
/usr/bin/ld: BFD 2.16.90.0.1 20050408 assertion fail linker.c:621 
/usr/bin/ld: BFD 2.16.90.0.1 20050408 assertion fail linker.c:621 
/usr/bin/ld: BFD 2.16.90.0.1 20050408 assertion fail linker.c:621 
 
Comment 7 Alan Modra 2005-04-14 03:34:08 UTC
comment #5 just seems to be a simple case of ld not finding a library, probably
because the right options were not passed to ld.

comment #6 is more worrying.  Can you provided a reduced testcase? 
Alternatively, can you debug this a little by running ld under gdb and printing
*h for the failing symbols?  Another thing worth trying in order to isolate the
bug would be to remove "if (inf.twiddled)" at elflink.c:4192, ie. always run
bfd_link_repair_undef_list.
Comment 8 Jürg Billeter 2005-04-14 09:18:28 UTC
You're right, -Wl,-rpath-link,../../exports/lib is missing from the gcc command
line but when buildling Xorg 6.8.2 with binutils 2.15.94.0.2.2 (and everything
else the same) that part of the command line is not missing. Don't know the
problem source right now.
Comment 9 Pawel Sikora 2005-04-14 15:59:57 UTC
(In reply to comment #7) 
 
print *h 
 
$4 = {root = {next = 0x838f620, string = 0x8369840 
              "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
      type = bfd_link_hash_undefined, 
          u = {undef = {next = 0x8402f90, abfd = 0x8361968, weak = 0x0}, 
                 def = {next = 0x8402f90, section = 0x8361968, value = 0}, 
                   i = {next = 0x8402f90, link = 0x8361968, warning = 0x0}, 
                   c = {next = 0x8402f90, p = 0x8361968, size = 0}}} 
 
print *h->u.undef.next 
 
$11 = {root = {next = 0x838f620, string = 0x8369840 
               "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
       type = bfd_link_hash_undefined, 
           u = {undef = {next = 0x8402f90, abfd = 0x8361968, weak = 0x0}, 
                  def = {next = 0x8402f90, section = 0x8361968, value = 0}, 
           i = {next = 0x8402f90, link = 0x8361968, warning = 0x0}, 
            c = {next = 0x8402f90, p = 0x8361968, size = 0}}} 
 
print *h 
 
$5 = {root = {next = 0x82e489c, string = 0x841479c 
              "pthread_mutex_lock@GLIBC_2.0", hash = 317394191}, 
      type = bfd_link_hash_undefined, 
         u = {undef = {next = 0x842e1a4, abfd = 0x8361968, weak = 0x0}, 
                def = {next = 0x842e1a4, section = 0x8361968, value = 0}, 
                  i = {next = 0x842e1a4, link = 0x8361968, warning = 0x0}, 
                  c = {next = 0x842e1a4, p = 0x8361968, size = 0}}} 
 
$6 = {root = {next = 0x849806c, string = 0x8414df8 
              "pthread_mutex_unlock@GLIBC_2.0", hash = 779585870}, 
      type = bfd_link_hash_undefined, 
         u = {undef = {next = 0x84b2710, abfd = 0x8361968, weak = 0x0}, 
                def = {next = 0x84b2710, section = 0x8361968, value = 0}, 
                  i = {next = 0x84b2710, link = 0x8361968, warning = 0x0}, 
                  c = {next = 0x84b2710, p = 0x8361968, size = 0}}} 
 
# glibc/nptl 
# readelf -sW /lib/libc-2.3.90.so |grep pthread_mutex_ 
1497: 000dc08d 41 FUNC GLOBAL DEFAULT   11 pthread_mutex_unlock@@GLIBC_2.0 
1778: 000dc00a 41 FUNC GLOBAL DEFAULT   11 pthread_mutex_destroy@@GLIBC_2.0 
1800: 000dc064 41 FUNC GLOBAL DEFAULT   11 pthread_mutex_lock@@GLIBC_2.0 
1942: 000dc033 49 FUNC GLOBAL DEFAULT   11 pthread_mutex_init@@GLIBC_2.0 
Comment 10 Pawel Sikora 2005-04-14 16:05:06 UTC
print *h->u.undef.abfd 
 
$15 = {id = 246, filename = 0x80cf5a0 "/usr/X11R6/lib/libX11.so", 
       xvec = 0x400adf60, iostream = 0x84ee0a0, iovec = 0x400aa6f0, 
       cacheable = 1, target_defaulted = 0, lru_prev = 0x84ee4f8, 
       lru_next = 0x8573268, where = 50692, opened_once = 0, mtime_set = 0, 
       mtime = 0, ifd = 0, format = bfd_object, direction = read_direction, 
       flags = 336, origin = 0, output_has_begun = 0, 
       section_htab = { table = 0x85e2bf8, size = 4051, newfunc = 0x4003b410 
       <bfd_section_hash_newfunc>, memory = 0x80d3160}, sections = 0x0, 
       section_tail = 0x83619cc, section_count = 0, start_address = 70640, 
       symcount = 0, outsymbols = 0x0, dynsymcount = 0, 
       arch_info = 0x400affe0, no_export = 0, arelt_data = 0x0, 
       my_archive = 0x0, next = 0x0, archive_head = 0x0, has_armap = 0, 
       link_next = 0x0, archive_pass = 0, tdata = {aout_data = 0x85de428, 
       aout_ar_data = 0x85de428, oasys_obj_data = 0x85de428, 
       oasys_ar_data = 0x85de428, coff_obj_data = 0x85de428, 
       pe_obj_data = 0x85de428, xcoff_obj_data = 0x85de428, 
       ecoff_obj_data = 0x85de428, ieee_data = 0x85de428, 
       ieee_ar_data = 0x85de428, srec_data = 0x85de428, 
       ihex_data = 0x85de428, tekhex_data = 0x85de428, 
       elf_obj_data = 0x85de428, nlm_obj_data = 0x85de428, 
       bout_data = 0x85de428, mmo_data = 0x85de428, 
       sun_core_data = 0x85de428, sco5_core_data = 0x85de428, 
       trad_core_data = 0x85de428, som_data = 0x85de428, 
       hpux_core_data = 0x85de428, hppabsd_core_data = 0x85de428, 
       sgi_core_data = 0x85de428, lynx_core_data = 0x85de428, 
       osf_core_data = 0x85de428, cisco_core_data = 0x85de428, 
       versados_data = 0x85de428, netbsd_core_data = 0x85de428, 
       mach_o_data = 0x85de428, mach_o_fat_data = 0x85de428, 
       pef_data = 0x85de428, pef_xlib_data = 0x85de428, 
       sym_data = 0x85de428, any = 0x85de428}, usrdata = 0x80b3cd8, 
       memory = 0x80cf5c0} 
 
Comment 11 Alan Modra 2005-04-15 02:35:42 UTC
Ah!  Seeing pthread_mutex_init@GLIBC_2.0's u.undef.next link back to itself was
the clue I needed.  u.undef.next is used as a list pointer, and also as a marker
to say that a symbol has been referenced.  As a marker, u.undef.next is set to
point to the symbol itself, so obviously can't be on the list and thus won't be
fixed by bfd_link_repair_undef_list.

Hmm, but just fixing u.undef.next might be papering over another problem, as it
isn't exactly clear how u.undef.next is being set like this.  I suspect the
following scenario:
a) pthread_mutex_init is defined in one shared lib and referenced by another,
which would leave u.undef.next pointing back to the sym
b) an as-needed lib is loaded which also defines pthread_mutex_init.  There is a
hack in _bfd_elf_merge_symbol around line 1177 of elflink.c to stop multiple
symbol definition errors when two shared libs define a sym.  Unfortunately, this
will result in the symbol being marked as defined in the as-needed lib.
c) The as-needed lib doesn't satisfy any undefined syms in regular object files,
so elf_smash_syms is called to remove syms defined in the library.  This
interacts with the above mentioned hack, and results in the symbol being undefined.

To confirm this, would you please give the result from
readelf -sD lib.so | grep pthread_mutex_init
for each shared lib involved in the link.  It might pay to add -Wl,--verbose to
options passed to libtool so that you see the real list of libs involved in the
link.
Comment 12 Alan Modra 2005-04-15 02:52:32 UTC
No, (b) is wrong.  elf.c:1177 won't result in the sym being marked as defined in
the as-needed shared lib.  I need to dig some more (or have those readelf -sD
results!)
Comment 13 Pawel Sikora 2005-04-15 07:20:40 UTC
(In reply to comment #11) 
 
full link command: 
 
/usr/bin/ld --eh-frame-hdr -m elf_i386 -shared -o .libs/wmfthumbnail.so 
-z combreloc 
-L/usr/lib/gcc/i686-pld-linux/4.0.0 
-L/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdefx/.libs 
-L/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/dcop/.libs 
-L/usr/lib/gcc/i686-pld-linux/4.0.0/../../.. 
-L/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdecore/.libs 
-L/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kwallet/client/.libs 
-L/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdesu/.libs 
-L/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdeui/.libs 
-L/usr/lib -L/usr/X11R6/lib -L/usr/lib/gcc/i686-pld-linux/4.0.0 
-L/usr/lib/gcc/i686-pld-linux/4.0.0 
-L/usr/lib/gcc/i686-pld-linux/4.0.0/../../.. 
--as-needed --no-undefined --allow-shlib-undefined 
/usr/lib/gcc/i686-pld-linux/4.0.0/../../../crti.o 
/usr/lib/gcc/i686-pld-linux/4.0.0/crtbeginS.o 
.libs/wmfthumbnail_la.all_cpp.o 
../kio/.libs/libkio.so 
/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdeui/.libs/libkdeui.so 
/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdesu/.libs/libkdesu.so 
/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kwallet/client/.libs/libkwalletclient.so 
/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdecore/.libs/libkdecore.so 
/home/users/pluto/rpm/BUILD/kdelibs-3.4.0/dcop/.libs/libDCOP.so 
-lresolv -lutil /usr/lib/libart_lgpl_2.so 
/usr/lib/libidn.so /home/users/pluto/rpm/BUILD/kdelibs-3.4.0/kdefx/.libs/libkdefx.so 
/usr/lib/libqt-mt.so -lGL -lXmu -lXrandr -lXcursor -lXinerama -lXft 
/usr/lib/libfontconfig.so -ldl -lXext -lpthread -lXrender /usr/lib/libfam.so 
/usr/lib/libwmf.so /usr/lib/libwmflite.so /usr/lib/libfreetype.so -lSM -lICE 
-lX11 /usr/lib/libexpat.so /usr/lib/libjpeg.so -lpng -lz /usr/lib/libstdc++.so 
-lm -lc -lgcc_s /usr/lib/gcc/i686-pld-linux/4.0.0/crtendS.o 
/usr/lib/gcc/i686-pld-linux/4.0.0/../../../crtn.o -soname wmfthumbnail.so 
 
grep results: 
 
/lib/libc-2.3.90.so 
 1942 838: 000dc033    49    FUNC GLOBAL DEFAULT  11 pthread_mutex_init 
 
/lib/libpthread-2.3.90.so 
  297 226: 00006c44    67    FUNC GLOBAL DEFAULT  12 pthread_mutex_init 
   92 341: 00006c44    67    FUNC GLOBAL DEFAULT  12 __pthread_mutex_init 
 
/usr/lib/libqt-mt.so 
 6936 14053: 00000000  67    FUNC   WEAK DEFAULT UND pthread_mutex_init 
 
/usr/X11R6/lib/libGL.so 
  692 526: 00000000    67    FUNC GLOBAL DEFAULT UND pthread_mutex_init 
 
/usr/X11R6/lib/libX11.so 
  432 526: 00000000    49    FUNC GLOBAL DEFAULT UND pthread_mutex_init 
 
reduced testcase is: 
 
/usr/bin/ld --eh-frame-hdr -m elf_i386 -shared -o wmfthumbnail.so \ 
--no-undefined --allow-shlib-undefined --as-needed \ 
./wmfthumbnail_la.all_cpp.o \ 
/usr/lib/libqt-mt.so /lib/libpthread.so.0 /usr/X11R6/lib/libX11.so \ 
-soname wmfthumbnail.so 
 
without --as-needed option it reports only valid undefined references. 
Comment 14 Alan Modra 2005-04-15 11:16:43 UTC
I've traced what is happening, and everything now makes sense.

This fix checked in to mainline and 2.16 should cure your problem.

	PR ld/815
	* elflink.c (elf_smash_syms): Clear undef.next if it's not being
	used as a list pointer.
Comment 15 Alan Modra 2005-04-15 11:19:00 UTC
libqt-mt.so.3.3.4 defines pthread_mutex_init@GLIBC_2.0

$22 = {root = {root = {next = 0x85d2380, 
      string = 0x85a9ea0 "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
    type = bfd_link_hash_undefweak, u = {undef = {next = 0x0, 
        abfd = 0x85890e8, weak = 0x85890e8}, def = {next = 0x0, 
        section = 0x85890e8, value = 140021992}, i = {next = 0x0, 
        link = 0x85890e8, warning = 0x85890e8 "\002"}, c = {next = 0x0, 
        p = 0x85890e8, size = 140021992}}}, indx = -1, dynindx = -1, got = {
    refcount = 0, offset = 0, glist = 0x0, plist = 0x0}, plt = {refcount = 0, 
    offset = 0, glist = 0x0, plist = 0x0}, size = 0, type = 0, other = 0, 
  ref_regular = 0, def_regular = 0, ref_dynamic = 0, def_dynamic = 0, 
  ref_regular_nonweak = 0, dynamic_adjusted = 0, needs_copy = 0, 
  needs_plt = 0, non_elf = 0, hidden = 0, forced_local = 0, mark = 0, 
  non_got_ref = 0, dynamic_def = 0, dynamic_weak = 0, 
  pointer_equality_needed = 0, dynstr_index = 0, u = {weakdef = 0x0, 
    elf_hash_value = 0}, verinfo = {verdef = 0x0, vertree = 0x0}, 
  vtable = 0x0}

libqt-mt.so.3.3.4 is needed, so above is kept.

libpthread.so.0 defines pthread_mutex_init@@GLIBC_2.0

$25 = {root = {root = {next = 0x865fa24, 
      string = 0x876b230 "pthread_mutex_init@@GLIBC_2.0", hash = 329801547}, 
    type = bfd_link_hash_defined, u = {undef = {next = 0x0, abfd = 0x85be3a4, 
        weak = 0x2700}, def = {next = 0x0, section = 0x85be3a4, 
        value = 9984}, i = {next = 0x0, link = 0x85be3a4, 
        warning = 0x2700 <Address 0x2700 out of bounds>}, c = {next = 0x0, 
        p = 0x85be3a4, size = 9984}}}, indx = -1, dynindx = -1, got = {
    refcount = 0, offset = 0, glist = 0x0, plist = 0x0}, plt = {refcount = 0, 
    offset = 0, glist = 0x0, plist = 0x0}, size = 0, type = 0, other = 0, 
  ref_regular = 0, def_regular = 0, ref_dynamic = 0, def_dynamic = 0, 
  ref_regular_nonweak = 0, dynamic_adjusted = 0, needs_copy = 0, 
  needs_plt = 0, non_elf = 0, hidden = 0, forced_local = 0, mark = 0, 
  non_got_ref = 0, dynamic_def = 0, dynamic_weak = 0, 
  pointer_equality_needed = 0, dynstr_index = 0, u = {weakdef = 0x0, 
    elf_hash_value = 0}, verinfo = {verdef = 0x85bcbf0, vertree = 0x85bcbf0}, 
  vtable = 0x0}

the linker creates an indirect symbol, pthread_mutex_init

(gdb) p *hi
$30 = {root = {root = {next = 0x8739a04, 
      string = 0x87720bc "pthread_mutex_init", hash = 268710567}, 
    type = bfd_link_hash_indirect, u = {undef = {next = 0x0, 
        abfd = 0x8772060, weak = 0x0}, def = {next = 0x0, 
        section = 0x8772060, value = 0}, i = {next = 0x0, link = 0x8772060, 
        warning = 0x0}, c = {next = 0x0, p = 0x8772060, size = 0}}}, 
  indx = -1, dynindx = -1, got = {refcount = 0, offset = 0, glist = 0x0, 
    plist = 0x0}, plt = {refcount = 0, offset = 0, glist = 0x0, plist = 0x0}, 
  size = 0, type = 0, other = 0, ref_regular = 0, def_regular = 0, 
  ref_dynamic = 0, def_dynamic = 0, ref_regular_nonweak = 0, 
  dynamic_adjusted = 0, needs_copy = 0, needs_plt = 0, non_elf = 0, 
  hidden = 0, forced_local = 0, mark = 0, non_got_ref = 0, dynamic_def = 0, 
  dynamic_weak = 0, pointer_equality_needed = 0, dynstr_index = 0, u = {
    weakdef = 0x0, elf_hash_value = 0}, verinfo = {verdef = 0x0, 
    vertree = 0x0}, vtable = 0x0}
(gdb) p *hi->root.u.i.link
$31 = {root = {next = 0x865fa24, 
    string = 0x876b230 "pthread_mutex_init@@GLIBC_2.0", hash = 329801547}, 
  type = bfd_link_hash_defined, u = {undef = {next = 0x0, abfd = 0x85be3a4, 
      weak = 0x2700}, def = {next = 0x0, section = 0x85be3a4, value = 9984}, 
    i = {next = 0x0, link = 0x85be3a4, 
      warning = 0x2700 <Address 0x2700 out of bounds>}, c = {next = 0x0, 
      p = 0x85be3a4, size = 9984}}}

and also an indirection from the nondefault version,
pthread_mutex_init@GLIBC_2.0 which was undefweak from libqt-mt.so.3.3.4

(gdb) p *h
$33 = {root = {next = 0x85d2380, 
    string = 0x85a9ea0 "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
  type = bfd_link_hash_indirect, u = {undef = {next = 0x0, abfd = 0x8772060, 
      weak = 0x85890e8}, def = {next = 0x0, section = 0x8772060, 
      value = 140021992}, i = {next = 0x0, link = 0x8772060, 
      warning = 0x85890e8 "\002"}, c = {next = 0x0, p = 0x8772060, 
      size = 140021992}}}
(gdb) p *h->u.i.link
$34 = {root = {next = 0x865fa24, 
    string = 0x876b230 "pthread_mutex_init@@GLIBC_2.0", hash = 329801547}, 
  type = bfd_link_hash_defined, u = {undef = {next = 0x0, abfd = 0x85be3a4, 
      weak = 0x2700}, def = {next = 0x0, section = 0x85be3a4, value = 9984}, 
    i = {next = 0x0, link = 0x85be3a4, 
      warning = 0x2700 <Address 0x2700 out of bounds>}, c = {next = 0x0, 
      p = 0x85be3a4, size = 9984}}}

and this code:

	    /* If the indirect symbol has been referenced, we need to
	       push the reference down to the symbol we are
	       referencing.  */
	    if (h->type != bfd_link_hash_new)
	      {
		row = UNDEF_ROW;
		cycle = TRUE;
	      }

then results in u.undef.next pointing back at the syms

$36 = {root = {next = 0x85d2380, 
    string = 0x85a9ea0 "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
  type = bfd_link_hash_indirect, u = {undef = {next = 0x865f858, 
      abfd = 0x8772060, weak = 0x85890e8}, def = {next = 0x865f858, 
      section = 0x8772060, value = 140021992}, i = {next = 0x865f858, 
      link = 0x8772060, warning = 0x85890e8 "\002"}, c = {next = 0x865f858, 
      p = 0x8772060, size = 140021992}}}

$37 = {root = {next = 0x865fa24, 
    string = 0x876b230 "pthread_mutex_init@@GLIBC_2.0", hash = 329801547}, 
  type = bfd_link_hash_defined, u = {undef = {next = 0x8772060, 
      abfd = 0x85be3a4, weak = 0x2700}, def = {next = 0x8772060, 
      section = 0x85be3a4, value = 9984}, i = {next = 0x8772060, 
      link = 0x85be3a4, warning = 0x2700 <Address 0x2700 out of bounds>}, 
    c = {next = 0x8772060, p = 0x85be3a4, size = 9984}}}

but libpthread.so.0 isn't needed, so the syms get set back to newly
created.  (shown below are what we have after my fix to elf_smash_syms
ie. root.u.undef.next cleared.)

1: *h = {root = {root = {next = 0x865fa24, 
      string = 0x876b230 "pthread_mutex_init@@GLIBC_2.0", hash = 329801547}, 
    type = bfd_link_hash_new, u = {undef = {next = 0x0, abfd = 0x8589310, 
        weak = 0x0}, def = {next = 0x0, section = 0x8589310, value = 0}, i = {
        next = 0x0, link = 0x8589310, warning = 0x0}, c = {next = 0x0, 
        p = 0x8589310, size = 0}}}, indx = -1, dynindx = -1, got = {
    refcount = 0, offset = 0, glist = 0x0, plist = 0x0}, plt = {refcount = 0, 
    offset = 0, glist = 0x0, plist = 0x0}, size = 0, type = 0, other = 0, 
  ref_regular = 0, def_regular = 0, ref_dynamic = 0, def_dynamic = 0, 
  ref_regular_nonweak = 0, dynamic_adjusted = 0, needs_copy = 0, 
  needs_plt = 0, non_elf = 0, hidden = 0, forced_local = 0, mark = 0, 
  non_got_ref = 0, dynamic_def = 0, dynamic_weak = 0, 
  pointer_equality_needed = 0, dynstr_index = 0, u = {weakdef = 0x0, 
    elf_hash_value = 0}, verinfo = {verdef = 0x0, vertree = 0x0}, 
  vtable = 0x0}

1: *h = {root = {root = {next = 0x85d2380, 
      string = 0x85a9ea0 "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
    type = bfd_link_hash_new, u = {undef = {next = 0x0, abfd = 0x8589310, 
        weak = 0x0}, def = {next = 0x0, section = 0x8589310, value = 0}, i = {
        next = 0x0, link = 0x8589310, warning = 0x0}, c = {next = 0x0, 
        p = 0x8589310, size = 0}}}, indx = -1, dynindx = -1, got = {
    refcount = 0, offset = 0, glist = 0x0, plist = 0x0}, plt = {refcount = 0, 
    offset = 0, glist = 0x0, plist = 0x0}, size = 0, type = 0, other = 0, 
  ref_regular = 0, def_regular = 0, ref_dynamic = 0, def_dynamic = 0, 
  ref_regular_nonweak = 0, dynamic_adjusted = 0, needs_copy = 0, 
  needs_plt = 0, non_elf = 0, hidden = 0, forced_local = 0, mark = 0, 
  non_got_ref = 0, dynamic_def = 0, dynamic_weak = 0, 
  pointer_equality_needed = 0, dynstr_index = 0, u = {weakdef = 0x0, 
    elf_hash_value = 0}, verinfo = {verdef = 0x0, vertree = 0x0}, 
  vtable = 0x0}

then libX11.so.6.2 makes a reference to pthread_mutex_init@GLIBC_2.0
which results in

$40 = {root = {root = {next = 0x85d2380, 
      string = 0x85a9ea0 "pthread_mutex_init@GLIBC_2.0", hash = 421875337}, 
    type = bfd_link_hash_undefined, u = {undef = {next = 0x0, 
        abfd = 0x8589548, weak = 0x0}, def = {next = 0x0, 
        section = 0x8589548, value = 0}, i = {next = 0x0, link = 0x8589548, 
        warning = 0x0}, c = {next = 0x0, p = 0x8589548, size = 0}}}, 
  indx = -1, dynindx = -1, got = {refcount = 0, offset = 0, glist = 0x0, 
    plist = 0x0}, plt = {refcount = 0, offset = 0, glist = 0x0, plist = 0x0}, 
  size = 0, type = 0, other = 0, ref_regular = 0, def_regular = 0, 
  ref_dynamic = 0, def_dynamic = 0, ref_regular_nonweak = 0, 
  dynamic_adjusted = 0, needs_copy = 0, needs_plt = 0, non_elf = 0, 
  hidden = 0, forced_local = 0, mark = 0, non_got_ref = 0, dynamic_def = 0, 
  dynamic_weak = 0, pointer_equality_needed = 0, dynstr_index = 0, u = {
    weakdef = 0x0, elf_hash_value = 0}, verinfo = {verdef = 0x0, 
    vertree = 0x0}, vtable = 0x0}

and putting the above sym on the undefs list.  So that explains how
undef.next can be set when adding symbols from an as-needed lib.