schorr@ead.dsa.com (Andrew J. Schorr) (10/19/90)
According to the man page for ld, In this version of ld, the first definition of each symbol in the link always takes precedence and is used even if the first reference follows the definition. However, this does not appear to be completely true when shared libraries are involved. Here is an example: I have a shared library; some of the routines exported by this library include calls to printf. For some applications, I want to substitute my own version of printf for the one in libc.a. To do this, I simply link in printf.o (containing my version of printf) when I compile. This works fine if I use a static version of my library. However, if I use the shared version, the library routines will use the printf defined in libc.a. I think I understand why this happens: the printf in the shared library is resolved when the shared library is linked, not when the application program is linked. This behavior is very problematic. I normally use SunOS, and Sun's dynamic linking behaves normally: the references in the shared library are resolved when the library is linked at run-time. The only possible work-around that I can see is a painful one: have multiple versions of the shared library, one for each version of printf that I want to use. Is there any reasonable way to get around this problem? If not, will it be fixed? -Andy P.S. For anyone who is still confused about how to make shared objects under AIX 3.1, here is my understanding of the process: First, make the following definitions: LIBOBJS = {object files containing routines to be exported} Note that these are just normal object files (no special compilation flags required; nothing analogous to SunOS's -pic option). SHDEPLIBS = {libraries containing routines that are referenced by exported routines} Typically, SHDEPLIBS = -lc 1. Create a list of symbols to be exported. The following command will create a list containing all externally defined symbols: nm -g $(LIBOBJS) | awk '$(NF-1) == "D" {print $NF}' > shlib.exp 2. Create the shared object: ld -o shared_object.o $(LIBOBJS) -bE:shlib.exp -bM:SRE \ -T512 -H512 $(SHDEPLIBS) 3. Insert shared_object.o into an archive (if so desired). N.B. It seems tempting to leave out the SHDEPLIBS and use the -r flag in step 2. This will appear to work, but will give you an error at run-time.
bengsig@oracle.nl (Bjorn Engsig) (10/23/90)
Article <1990Oct18.140050@ead.dsa.com> by schorr@ead.dsa.com (Andrew J. Schorr) says: |According to the man page for ld, | | In this version of ld, the first definition of each symbol in | the link always takes precedence and is used even if the first | reference follows the definition. | | For some |applications, I want to substitute my own version of printf for the |one in libc.a. It has always been a bad habit to define your own version of a standard function - I would recommend using a routine my_printf, of which you have tow versions, one calling printf and one doing it your way. |I think I understand why this happens: the printf in the shared |library is resolved when the shared library is linked, not when |the application program is linked. Yes, printf is part of the big shared object in libc.a. There is no way to omit parts of this of course. See what ar tv libc.a gives you. |If not, will it be fixed? I don't think there is anything to fix. The C compiler plus environments like ld, work exactly like ANSI says it should. Andrew also said: |N.B. It seems tempting to leave out the SHDEPLIBS and use the -r flag | in step 2. This will appear to work, but will give you an error | at run-time. So true, this is almost something that should be put in a FAQ list, so to rephrase: Shared objects (in shared archives or not) MUST be fully linked, i.e. no unresolved references are allowed in shared objects. -- Bjorn Engsig, E-mail: bengsig@oracle.com, bengsig@oracle.nl ORACLE Corporation From IBM: auschs!ibmaus!cs.utexas.edu!uunet!oracle!bengsig "Stepping in others footsteps, doesn't bring you ahead"