Using a shared library to partly replace an archive library

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