Using a shared library to partly replace an archive library - ld changed behaviour
Graham Hudspith
gwh@allinea.com
Fri Apr 29 12:19:00 GMT 2005
H. J. Lu wrote:
>
>It is a combination of ld and ld.so. Weak symbols are treated as
>strong when DSO is involved. If you want a DSO to override a symbol
>in an archive, you have to make sure that the .o file which contains
>the symbol can ONLY be used to resolve that symbol. In your case,
>bar.o defines both foo and bar. Linker sees foo when it tries to
>resolve bar.
>
>
>
>
Thanks for the swift reply!
From what I can gather from your reply, it seems that any fix involving
just OUR shared library is not going to be possible. Changes to the
original package that builds the archive library are required.
So I shall have to raise a bug report on that package.
With that in mind, could you please give some hints as to why this
change in behaviour for ld happened? Or a search string for the binutils
mailing list archive?
Not being a linker developer, the reason this change in behaviour
happened is not obvious, so any pointers to the rationale would benefit
me greatly when composing the bug report!
Trying to come up with a "least changes required" strategy for the
maintainers of the package, and taking your advice into account, it
seems that modifying bar.c to be compiled TWICE, once for the "foo"
parts and again for the "bar" parts is a possible solution. It would
double the size of the archive library, but disk space is cheap. Is this
viable? Correct? Any other downsides?
I've modified our last example to do this (attached), and the diff for
bar.c is thus:
*** modified/bar.c 2005-04-27 22:24:44.000000000 +0100
--- mod-2/bar.c 2005-04-27 22:25:02.000000000 +0100
***************
*** 1,14 ****
--- 1,20 ----
#include <stdio.h>
+ #ifdef FOO
void foo ();
+ #endif
void bar ();
+ #ifdef BAR
#pragma weak foo = bar
+ #endif
void bar ();
+ #ifdef BAR
#define foo bar
+ #endif
void
foo ()
When "made", the following now results:
[gwh@snowball first-solution]$ make
gcc -B./ -O -g -c -o main.o main.c
gcc -B./ -O -g -fPIC -c foo.c -o shared.o
gcc -B./ -shared -o libshared1.so shared.o
gcc -B./ -O -g -DFOO -fPIC -c bar.c -o foobar.o
ar rv libfoo.a foobar.o
ar: creating libfoo.a
a - foobar.o
gcc -B./ -O -g -DBAR -fPIC -c bar.c -o barbar.o
ar rv libfoo.a barbar.o
a - barbar.o
gcc -B./ -o main1 main.o libshared1.so libfoo.a -Wl,-rpath,.
gcc -B./ -o main2 main.o libfoo.a
gcc -B./ -shared -o libshared3.so shared.o libfoo.a
gcc -B./ -o main3 main.o libshared3.so libfoo.a -Wl,-rpath,.
./main1
Shared library
Real bar
./main2
Real foo
./main3
Shared library
Real bar
Which gives the correct results for all three cases.
Please, is there any way we can achieve this WITHOUT having to modify
the original package?
Thanks,
Graham.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug.tar.gz
Type: application/x-gzip
Size: 813 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20050429/3a000840/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3385 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://sourceware.org/pipermail/binutils/attachments/20050429/3a000840/attachment-0001.bin>
More information about the Binutils
mailing list