This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Using a shared library to partly replace an archive library -ld changed behaviour


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.

Attachment: bug.tar.gz
Description: GNU Zip compressed data

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]