https://sourceware.org/bugzilla/show_bug.cgi?id=27441
Michael Matz <matz at suse dot de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |matz at suse dot de --- Comment #2 from Michael Matz <matz at suse dot de> --- The real situation is a bit different from comment #1, and I think it shows a problem in ld.bfd when using LTO. See also https://bugzilla.opensuse.org/show_bug.cgi?id=1182252 >From there: ------------------------------------ the important core, all on current factory with Staging:B, i.e. binutils 2.36.0.20210204-404 and glibc 2.33 : % cat bad3.c #include <stdlib.h> #include <unistd.h> #include <fcntl.h> int getfile(const char *path) { return open(path, O_RDONLY); } void callqsort(void *p, size_t n, size_t s, int (*c)(const void *, const void*)) { qsort(p, n, s, c); } It's important that the file (or the collection of all input files) calls open (or any function defined in libpthread and libc) _and_ a function defined only in libc (here qsort). Then, base case, no LTO: % gcc -fPIC -Wl,--as-needed -fno-lto -shared -o foo.so bad3.c -lpthread % readelf -dW foo.so | grep pthread 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0] So, all is well. Note in particular that -lpthread comes after the object files (here source files), as it should be, and is picked up as dependency because it provides a definition of open(). Now with LTO: % gcc -fPIC -Wl,--as-needed -flto -shared -o foo.so bad3.c -lpthread % readelf -dW foo.so | grep pthread <nothing> With -Wl,-y,open we can trace the open references: % gcc -fPIC -Wl,--as-needed -fno-lto -shared -o foo.so bad3.c -lpthread -Wl,-y,open /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/cczQCQq2.o: reference to open /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /usr/lib64/gcc/x86_64-suse-linux/10/../../../../lib64/libpthread.so: definition of open So, as expected. With LTO: % gcc -fPIC -Wl,--as-needed -flto -shared -o foo.so bad3.c -lpthread -Wl,-y,open /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccnS9KVr.o (symbol from plugin): reference to open /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /usr/lib64/gcc/x86_64-suse-linux/10/../../../../lib64/libpthread.so: definition of open /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /lib64/libc.so.6: definition of open /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/foo.so.IdEo2Q.ltrans0.ltrans.o: reference to open So, here open comes as reference from plugin (I guess that's sensible), then the definition in libpthread.so is found, and then ld seems to continue looking and also finds one in libc.so. And then a further reference from the ltrans object. I guess, but haven't verified that this last reference is the one that matters for final code, and that it's actually resolved to the libc variant, although the definition in libpthread was first. -------------------------------- I'm guessing that to remove the dependency on specific symbols provided by libpthread/libc, one could simulate that situation as well: make two libraries, one providing two strong defs of "func1" and "func2", and another providing only a weak def of "func2". Then the above testcase would need to call func1 and func2. -- You are receiving this mail because: You are on the CC list for the bug.