Say that I have three libraries: libMissingSymbol.so, libMiddle.so, and libSymbolHaver.so. libMissingSymbol contains a symbol defined in libSymbolHaver, but only has a dependency on libMiddle. libMiddle is supposed to have a dependency on libSymbolHaver, but it doesn't. I don't have the source code or unlinked object files that these libraries were assembled from. Is it possible for me to link libMiddle with libSymbolHaver so that libMissingSymbol can find the symbol it needs at load time? Is there any way that I can fix this using only these three shared object files and any necessary tools? I have to end up with libraries with the same contents (including SONAMEs) barring the dependency change to libMiddle in order to not break things further down the line in my project.
Hypothetical readelf output (trimmed for relevance) to clarify:
$ readelf -s libMissingSymbol.so
123: 00000000 0 OBJECT GLOBAL DEFAULT UND MangledSymbol
$ readelf -d libMissingSymbol.so
Dynamic section at offset 0x42434 contains 37 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libMiddle.so]
0x0000000e (SONAME) Library soname: [libMissingSymbol.so]
$ readelf -d libMiddle.so
Dynamic section at offset 0x75b28 contains 29 entries:
Tag Type Name/Value
0x0000000e (SONAME) Library soname: [libMiddle.so]
$ readelf -s libSymbolHaver.so
35: 00064d0c 4 OBJECT GLOBAL DEFAULT 22 MangledSymbol
Is it possible for me to link libMiddle with libSymbolHaver so that libMissingSymbol can find the symbol it needs at load time?
No: all UNIX linkers, except the AIX one, consider .so
the final link product and no further modification is possible.
Update:
viability of doing this a different way (e.g. decompiling libMiddle and rebuilding it with the correct dependencies)?
I don't believe that is viable either -- it is really hard to modify a fully-linked ELF file and not violate myriad of internal consistency constraints.
I suggest the following approach, which is very likely to just work(TM).
Abandon your "only using these three libraries" restriction. It appears to be artificial and unnecessary.
Copy libMiddle.so
-> libZiddle.so
(be sure to make a copy of the original libMiddle.so
somewhere else in case things go wrong).
binary-patch the SONAME
in libZiddle.so
to match the new name. The string "libMiddle.so"
is in the .dynstr
section of the library, and (I believe) is not hashed in any way, so changing one letter in it will not introduce any self-inconsistencies into the new library.
Once you've done this, compare readelf -a libMiddle.so
and readelf -a libZiddle.so
, the SONAME
should be the only difference.
Remove libMiddle.so
.
Link a new libMiddle.so
containing some_unused_function()
, and having dynamic dependency on both libZiddle.so
and libSymbolHaver.so
.
Now any binary that currently links against libMiddle.so
and fails with missing symbol (e.g. libMissingSymbol.so
) will find the new (empty) libMiddle.so
, but because the new libMiddle.so
requires both libZiddle.so
(where most of the symbols are) and libSymbolHaver.so
, it should just work.
User contributions licensed under CC BY-SA 3.0