Issue
I have two existing .so files:
- a.so
- b.so
ldd reports that neither of them know about the other, but a.so
depends on a function in b.so
in this contrived example:
# ldd -r a.so
linux-vdso.so.1 => (0x00007ffe8e7bb000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3d8830c000)
undefined symbol: b_test_func (./a.so)
# ldd -r b.so
linux-vdso.so.1 => (0x00007ffe8e7bb000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3d8830c000)
# objdump -T b.so
0000000000fac7a0 g DF .text 0000000000000f80 b_test_func
Since a.so
was not compiled against b.so
, the linker has left the symbol b_test_func
unresolved such that ldd
does not list b.so
as a dependency, otherwise you would see something like b.so => /foo/b.so
in the ldd a.so
output.
I need to dlmopen(LM_ID_NEWLM) a.so
into a new namespace, hence a.so
must depend on b.so
since RTLD_GLOBAL is not supported by dlmopen() because of this bug. (Note that dlopen(RTLD_GLOBAL) does work).
Therefore we need the glibc dynamic linker to resolve the linkage itself by making a.so
indicate that it needs b.so
so they can operate in the same namespace and dlmopen() will resolve the dependency automatically. Without the link shown by ldd
they won't use eachothers' shared symbols so dlsym() will fail to resolve.
Questions:
- Is there a way to modify
a.so
so thatldd a.so
will try to resolveb.so
? - What is this linkage shown by
ldd
known as so I can refer to it properly?
Solution
Is there a way to modify a.so so that ldd a.so will try to resolve b.so ?
On most UNIX systems, .so
is the final link product, and no further modification is possible.
You may be able to use patchelf --add-needed b.so a.so
, but simply dlmopen
ing b.so
before you dlmopen
a.so
(as suggested by Lorinczy Zsigmond) is probably an easier solution.
Answered By - Employed Russian