https://sourceware.org/bugzilla/show_bug.cgi?id=32006

            Bug ID: 32006
           Summary: ld pulls symbols from wrong library
           Product: binutils
           Version: 2.41
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: felix-glibc at fefe dot de
  Target Milestone: ---

I'm not quite sure what is going on here.
Basically, I'm linking a program like this:

  $ diet -v gcc -o t test.c -pthread -Wl,-Map,mapfile

diet is a wrapper from dietlibc and it will transform the command line to this:

  $ gcc -nostdlib -static -L/opt/diet/lib-x86_64 /opt/diet/lib-x86_64/start.o
-o t test.c -D_REENTRANT -lpthread -Wl,-Map,mapfile -isystem /opt/diet/include
-D__dietlibc__ /opt/diet/lib-x86_64/libc.a -lgcc /opt/diet/lib-x86_64/crtend.o

Now, there is a symbol called __stdio_init_file that is exported by fdglue2.o
in libc.a and it is also exported from pthread_fdglue2.o in libpthread.a.

My understanding is that ld should always satisfy references from the first
library on the command line that has an export under that name (leaving
trickery like weak symbols aside for now).

Here's the load list from the mapfile:

LOAD /opt/diet/lib-x86_64/start.o
LOAD /tmp/ccnyXICz.o
LOAD /opt/diet/lib-x86_64/libpthread.a
LOAD /opt/diet/lib-x86_64/libc.a
LOAD /usr/lib64/gcc/x86_64-pc-linux-gnu/14.1.0/libgcc.a
LOAD /opt/diet/lib-x86_64/crtend.o

libpthread.a is named first, then libc.a.

Here's what nm says about libpthread.a:

pthread_fdglue2.o:
0000000000000000 T __stdio_init_file
                 U __stdio_init_file_nothreads

Here's what nm says about libc.a:

fdglue2.o:
                 U _GLOBAL_OFFSET_TABLE_
                 U __errno_location
                 U __libc_close
                 U __stdio_atexit
                 U __stdio_flushall
0000000000000000 W __stdio_init_file
0000000000000000 T __stdio_init_file_nothreads
                 U __stdio_root
                 U atexit
                 U free
                 U fstat
                 U malloc

Making __stdio_init_file weak is my current attempt to fix the situation but it
is not helping. So both libraries export __stdio_init_file and libpthread.a is
named first, yet ld takes the one from libc instead:

/opt/diet/lib-x86_64/libc.a(fdglue2.o)                                         
                                                                     
/opt/diet/lib-x86_64/libc.a(fopen.o) (__stdio_init_file)

What the hell is going on? Is this a bug in binutils ld?

For good measure I tried -fuse-ld=gold (same behavior) and -fuse-ld=lld (pulls
in pthread_fdglue2.o) and -fuse-ld=mold (also pulls in pthread_fdglue2.o).

Have I been relying on undefined behaviour for over a decade?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to