This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Possible weak linker bug in ld
- From: "Svein E. Seldal" <Svein dot Seldal at solidas dot com>
- To: binutils at sources dot redhat dot com
- Date: Wed, 15 Oct 2003 14:39:58 +0200
- Subject: Possible weak linker bug in ld
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
Attachment:
ldweak_bug.tgz
Description: application/compressed