I have a couple questions about Solaris 2.5 shared libraries. Please
been kind of flaky lately.
1) I have a program prog and 2 shared libraries, small.so and big.so.
Under 2.5 if libraries are loaded in the order small and then big,
they load ok. If they are loaded in the order big and then small,
I get this error from dlopen:
Dynamic loading error: ld.so.1: prog: fatal: file=small.so:
relocation [R_SPARC_WDISP22] value 0x25fadb (symbol `_cerror') does not fit.
If I use exactly the same program and shared libraries under 2.4 the
loading order doesn't matter. It seems to me that either
A) the dynamic loader under 2.5 has a bug; or
B) this really does exceed 22 bits of relocation and I am probably
just missing the error on 2.4 because some system libraries are
smaller, or perhaps fewer of them are loaded or they are loaded in a
different order, bringing the address within range. The code size
alone of big.so is 5,999,472. 2**22 is 4,194,304. So it is entirely
believable that a 22 bit relocaton field has been exceeded. (Probably
you can actually handle offsets bigger than 2**22 because they are
going to be at least word aligned, but maybe you need 1 bit for the
sign. Just guessing about this.)
If it is B), is this related to compiling -pic vs. -PIC? The
description of these on the CC man page doesn't make it clear whether
this is related. I can't recompile small.so -PIC since it is a 3rd
party library. The supplier of this library has been extremely
uncooperative in the past about fixing serious bugs in their products
and I don't think it is worthwhile asking them to build it
differently. Also, I can't just load small.so first since it depends
on other optional software being present on the system. The scenario
described above is actually a simplified version of the environment.
Note for gcc users: -pic and -PIC are the same as -fpic and -fPIC.
2) If you have a function f() defined in so.so, and you load so.so
from program basef, and basef also defines a function f(), which is
used? It appears from the program below that the function in basef is
I ask this because small.so (from question 1) is actually quite large itself
(almost 400K of code) because it statically links in and defines _cerror and
most of the rest of libc. They apparently statically linked it in
thinking it would take precedence over the versions of libc routines
in programs using small.so. So they have wasted a lot of memory in
small.so with versions of system routines that will never get called.
all: basef baseh so.so
CC -g -o basef base.cc -R. -ldl
CC -g -DH -o baseh base.cc -R. -ldl
CC -PIC -g -G -o so.so so.cc
rm -f base.o basef baseh so.so
#define f h
void error(char *str)
printf("Base function called\n");
handle = dlopen("so.so", RTLD_NOW | RTLD_GLOBAL);
error("Couldn't open shared library ./so.so");
addr = dlsym(handle, "g");
error("Couldn't find func g() in so.so");
printf("function f() in shared lib called\n");
84 Sherman St.
Cambridge, Mass. 02140