[Date Prev][Date Next] [Chronological] [Thread] [Top]

AIX shared libraries (ITS#1480)



Full_Name: Ralph Goers
Version: 2.0.18
OS: AIX 4.3.3
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (66.51.196.164)


libldap.so is built incorrectly on AIX. shared objects of this type should be
linked using ld with -lc, not with cc or cc_r. Without this programs will
coredump when libldap is loaded since it has unresolved references to liblber.
The following is from "C and C++ Application Development on AIX" (Redbook number
SG24-5674-00) starting at page 66.


To build shared objects enabled for run-time linking, use the -G flag and build
the shared object with the ld command rather than the compiler cc, xlc, or xlC
commands.

The function of the -G option to the compiler command is very similar in
function to the -G option to the linker (ld) command, but there is a very
subtle,
yet important, difference when it comes to creating shared objects for use
with runtime linking.

The important difference is the way the two options impact the handling of
unresolved symbols.
---- skipping down some ------
cc -o example main.c -brtl -L?pwd? libone.so libtwo.so
Note the use of the -brtl option, which is required to enable the run-time
linker. If we try and run the example program, an error message is produced:

# ./example
in function 1
Segmentation fault(coredump)

It can be seen from the output that the program has managed to start and get
as far as the printf statement in function1. It then experiences a fatal error
when trying to call function2. If we look at the header information for
libone.so
with the dump -Tv command, we can check the status of the symbols:
# dump -Tv libone.so
libone.so:
***Loader Section***
***Loader Symbol Table Information***
[Index] Value Scn IMEX Sclass Type IMPid Name
[0] 0x00000000 undef IMP DS EXTref libc.a(shr.o) printf
[1] 0x200001e8 .data EXP DS SECdef [noIMid] function1
[2] 0x00000000 undef IMP DS EXTref [noIMid] function2
It can be seen that the symbol function2 is marked as undef, which is what we
expect. However, the problem is that the IMPid is marked as [noIMid], which
means that the shared object does not know where to resolve the symbol
function2. If we use the ld command to create the shared object, instead of
the compiler, then the result is slightly different. Create the shared object
with
the following commands:
cc -c source1.c
ld -G -o libone.so source1.o -bnoentry -bexapall -lc
The -bnoentry and -bexpall options are described previously. The -lc option is
required to link the C library to resolve the printf function. If we look at
the
symbol information in the header section with the dump -Tv command:
# dump -Tv libone.so
libone.so:
***Loader Section***
***Loader Symbol Table Information***
[Index] Value Scn IMEX Sclass Type IMPid Name
[0] 0x00000000 undef IMP DS EXTref libc.a(shr.o) printf
[1] 0x00000008 .data EXP DS SECdef [noIMid] function1
[2] 0x00000000 undef IMP DS EXTref .. function2
the difference is the IMPid for the symbol function2. The shared object now
thinks it will resolve the symbol from the special module called ?..? (dot
dot).
This indicates that the symbol will be resolved by the run-time linker. If we
create libtwo.so using the same method, then the example program works
correctly.
The run-time linker is called by the program startup code before entering the
application?s main routine.