This is the mail archive of the binutils@sourceware.org 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: 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.


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