This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: ld magic: -Bgroup
- From: "Fu, He Wei PSE NKG" <hewei dot fu at siemens dot com>
- To: "Lutz Birkhahn" <lbirkhahn at adomo dot com>, <binutils at sourceware dot org>
- Date: Sun, 5 Nov 2006 18:18:39 +0800
- Subject: RE: ld magic: -Bgroup
It seems that dynamic linker (ld.so) didn't implement DF_1_GROUP(0x04)
flags in DT_FLAGS_1??
-----Original Message-----
From: Lutz Birkhahn [mailto:lbirkhahn@adomo.com]
Sent: Friday, November 03, 2006 4:20 PM
To: binutils@sourceware.org
Subject: ld magic: -Bgroup
Not sure if I completely understand the concept of -Bgroup, but I
thought
it would solve my problem:
Let's say I have two 3rd-party shared libraries, libA and libB. Both of
these reference another function libC_func(), which is defined in other
shared libraries (libCommonA.so for libA, libCommonB.so for libB).
Now I need to link my program to both libA and libB, and each of the
libraries should use their own version of libC_func(), and not a common
one. Isn't that what the -Bgroup option of ld is supposed to do?
In ASCII art:
/-- libA.so --- libCommonA.so --- libC_func()
prog -
\-- libB.so --- libCommonB.so --- libC_func()
So I'm trying to compile libA with this command:
gcc -shared -Wl,-Bgroup -o libA.so libA.c -L. -lCommonA
/lib/ld-2.3.4.so
and libB is compiled like this:
gcc -shared -Wl,-Bgroup -o libB.so libB.c -L. -lCommonB
/lib/ld-2.3.4.so
The main program, "prog" is compiled with this command:
gcc -o prog prog.c -L libA -lA -L libB -lB
But when I run the program, it's in both cases using libA's libC_func().
When I use the -Bgroup switch, isn't the linker supposed to satisfy all
of libB's references from that library's group?
objdump -x libB.so tells me that it needs libCommonB.so, and in the
"Dynamic Section" it has "FLAGS_1 0x4" (that's from the -Bgroup,
right?). Running the program with strace tells me that it is actually
loading both libCommonA and libCommonB, but it's still only using the
function from the first one (or the other way around if I set my
LD_LIBRARY_PATH to search in libB's directory first).
I have attached a test program as tar file, just go to the top direc-
tory and run make, and then "./prog".
gcc version: 4.0.2
ld version: 2.15.92.0.2 20040927
(This is on a RHEL4 system)
I'm puzzled now. Any hints what's wrong?
/lutz
In case attachments are stripped off, here are the contents of the
files:
--------------- Makefile ---------------
# Makefile
prog: libA/libA.so libB/libB.so prog.c
gcc -o prog prog.c \
-L libA -lA \
-L libB -lB
libA/libA.so:
make -C libA
libB/libB.so:
make -C libB
clean:
make -C libA clean
make -C libB clean
rm -f prog
--------------- prog.c ---------------
/* prog.c */
#include <stdio.h>
#include "libA/libA.h"
#include "libB/libB.h"
int main (int ac, char **av)
{
printf ("prog calling libA_func()\n");
libA_func();
printf ("prog calling libB_func()\n");
libB_func();
printf ("prog done\n");
return 0;
}
--------------- libA/Makefile ---------------
# libA/Makefile
libA.so: libA.c libCommonA.so
gcc -shared -Wl,-Bgroup -o libA.so libA.c -L.
-lCommonA /lib/ld-2.3.4.so
libCommonA.so: libCommonA.c
gcc -shared -Wl,-Bgroup -o libCommonA.so libCommonA.c
/lib/ld-2.3.4.so
clean:
rm -f *.so
--------------- libA/libA.h ---------------
/* libA/libA.h */
void libA_func();
--------------- libA/libA.c ---------------
/* libA/libA.c */
#include <stdio.h>
#include "libCommonA.h"
void libA_func ()
{
printf ("libA_func() calling libC_func\n");
libC_func();
}
--------------- libA/libCommonA.h ---------------
/* libA/libCommonA.h */
void libC_func();
--------------- libA/libCommonA.c ---------------
/* libA/libCommonA.c */
#include <stdio.h>
void libC_func ()
{
printf ("libA's libC_func\n");
}
--------------- libB/Makefile ---------------
# libB/Makefile
libB.so: libB.c libCommonB.so
gcc -shared -Wl,-Bgroup -o libB.so libB.c -L.
-lCommonB /lib/ld-2.3.4.so
libCommonB.so: libCommonB.c
gcc -shared -Wl,-Bgroup -o libCommonB.so libCommonB.c
/lib/ld-2.3.4.so
clean:
rm -f *.so
--------------- libB/libB.h ---------------
/* libB/libB.h */
void libB_func();
--------------- libB/libB.c ---------------
/* libB/libB.c */
#include <stdio.h>
#include "libCommonB.h"
void libB_func ()
{
printf ("libB_func() calling libC_func\n");
libC_func();
}
--------------- libB/libCommonB.h ---------------
/* libB/libCommonB.h */
void libC_func();
--------------- libB/libCommonB.c ---------------
/* libB/libCommonB.c */
#include <stdio.h>
void libC_func ()
{
printf ("libB's libC_func\n");
}
------------------------------
Current output:
$ ./prog
prog calling libA_func()
libA_func() calling libC_func
libA's libC_func
prog calling libB_func()
libB_func() calling libC_func
libA's libC_func <=============
prog done
In the second to last line I expected to see "libB's libC_func", not
libA's.