Possible weak linker bug in ld

Svein E. Seldal Svein.Seldal@solidas.com
Wed Oct 15 12:40:00 GMT 2003


Hello all,

I think I run across a bug in ld when linking files with weak symbols. 
Originally this bug was encountered in the avr target, but it seems that 
this bug is presistent even in the i386 (cygwin) target, so I will 
assume that this is a global (ELF?) bug.

Toolchain used: avr-gcc 3.3.1, avr-binutils 2.14   *or*   gcc 3.2 
20020927, binutils 2.13.90 20030308 i386 Cygwin official tools.

I've attached a small testcase which proves the bug. All the operations 
in this mail is makeable in that testcase.

The bug occurs if you have an assembly file, weak.S, that creates weak 
symbols:

	        .global _start
	_start: nop

	        .weak   _funca
	        .set    _funca, _start
	        jmp     _funca

	        .weak   _funcb
	        .set    _funcb, _start
	        jmp     _funcb

In this same project I have two files; test.c and testasm.S that defines 
funca and funcb as strong functions.

If I do a direct build (make direct.elf), where all files are linked in 
directly:

	$ make direct.elf
	<..snip..>
	gcc <...> -o direct.elf test.o testasm.o main.o weak.o

everything is OK. This is verified with nm:

	$ nm direct.elf |grep func
	00401090 T _funca
	004010a0 T _funcb

Now if the test.o and testasm.o (containing the strong symbols funca and 
funcb) are moved into a library:

	$ make libtest.a
	ar r libtest.a test.o testasm.o
	ranlib libtest.a

If I now do an indirect build by using this library, the strong symbols 
from libtest.a should override the local weak symbols  from weak.c:

	$ make fromlib.elf
	gcc <...> -o fromlib.elf main.o weak.o -L. -ltest

But this does not work, as indicated by nm:

	$ nm fromlib.elf |grep func
	004010d0 T _funca
	004010d0 T _funcb

This reveals that ld has used the weak symbols from weak.o despite that 
the library contains these symbols as strong functions.

Here comes the interesting bit:

If I edit weak.S and change the file into this (can be found in 
weak_works.S):

         .weak   _funca
         .set    _funca, _main		; <<--- Has ben changed
         jmp     _funca

         .weak   _funcb
         .set    _funcb, _main		; <<--- Has been changed
         jmp     _funcb

The internal references to _start is now substituted with _main. _main 
in this file's context is an external symbol, never mentioned anywhere else:

	$ nm weak.o |grep main
          U _main

If I now try to build the application, it suddenly works:

	$ make fromlib.elf
	$ nm fromlib.elf |grep func
	004010f0 T _funca
	004010e0 T _funcb

funca and funcb now uses the strong functions from the library.

Is this a bug or a feature? How should approach this bug?


Regards,
Svein
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ldweak_bug.tgz
Type: application/x-compressed
Size: 775 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20031015/86b4a123/attachment.bin>


More information about the Binutils mailing list