Original bug was a failed attempt to build llvm-11 with LDFLAGS="-flto -Wl,--as-needed": https://bugs.gentoo.org/749162. There std::call_once is implemented via weak pthread_once() symbol: https://gcc.gnu.org/PR55394. Presence of -Wl,--as-needed removes libpthread.so and breaks the program at runtime as pthread_once() has to have a real implementation. gcc plans to fix std::call_once by avoiding pthread_once() for unrelated reason (solving it will take a while). But the problem seems to be more general when local weak symbols are used to probe presence of a real implementation dynamically. What do you think of changing 'ld' to prefer strong symbols from shared libraries and keeping DT_NEEDED entries even if local object files define weak symbols? Toy example: $ cat a.c // gcc a.c -o a -Wl,--as-needed -pthread && ./a #include <stdio.h> #include <pthread.h> static pthread_once_t once = PTHREAD_ONCE_INIT; static __typeof(pthread_once) __gthrw_pthread_once __attribute__ ((__weakref__("pthread_once"), __copy__ (pthread_once))); static void ir(void) { printf("foo\n"); } int main(void) { if (__gthrw_pthread_once) __gthrw_pthread_once(&once, &ir); } $ gcc a.c -o a -Wl,--as-needed -pthread -fuse-ld=bfd && ./a $ gcc a.c -o a -Wl,--as-needed -pthread -fuse-ld=gold && ./a $ gcc a.c -o a -Wl,--as-needed -pthread -fuse-ld=lld && ./a $ gcc a.c -o a -Wl,--no-as-needed -pthread -fuse-ld=bfd && ./a foo Ideally all 4 tests should call pthread_once from libpthread.so.0 instead of calling local weak reference. Thanks!
It is done on purpose. libpthread.so.0 should be referenced by non-weak binding since weak reference means optional.
Aha, we'll try to find another workaround downstream then. Thank you!
This old thread might be relevant: https://sourceware.org/pipermail/binutils/2018-June/103245.html