假设我有三个库:libMissingSymbol.so,libMiddle.so和libSymbolHaver.so。 libMissingSymbol包含在libSymbolHaver中定义的符号,但只对libMiddle有依赖性。 libMiddle应该依赖于libSymbolHaver,但它没有。我没有这些库汇编的源代码或未链接的目标文件。我可以将libMiddle与libSymbolHaver链接起来,以便libMissingSymbol可以在加载时找到它需要的符号吗?有没有办法只使用这三个共享对象文件和任何必要的工具来解决这个问题?我必须最终得到具有相同内容(包括SONAME)的库,禁止将依赖项更改为libMiddle,以免在项目中进一步破坏。
假设的readelf输出(为了相关性而修剪)以澄清:
$ 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
答案 0 :(得分:1)
我是否可以将libMiddle与libSymbolHaver链接,以便libMissingSymbol可以在加载时找到所需的符号?
否:除AIX之外的所有UNIX链接器都会考虑.so
最终链接产品,并且无法进行进一步修改。
<强>更新强>
以不同方式执行此操作的可行性(例如,反编译libMiddle并使用正确的依赖关系重建它)?
我不相信这也是可行的 - 修改完全链接的ELF文件并且不违反无数的内部一致性限制非常难。
我建议使用以下方法,这很可能只是工作(TM)。
放弃您的“仅使用这三个库”限制。这似乎是人为的和不必要的。
复制libMiddle.so
- &gt; libZiddle.so
(如果出现问题,请务必在其他地方制作原始libMiddle.so
的副本。)
二进制修补SONAME
中的libZiddle.so
以匹配新名称。字符串"libMiddle.so"
位于库的.dynstr
部分,并且(我相信)不会以任何方式进行哈希处理,因此更改其中的一个字母不会在新库中引入任何自我不一致。
完成此操作后,请比较readelf -a libMiddle.so
和readelf -a libZiddle.so
,SONAME
应该是唯一的差异。
删除libMiddle.so
。
将包含libMiddle.so
,和的新some_unused_function()
链接到 libZiddle.so
和 libSymbolHaver.so
。
现在任何目前链接到libMiddle.so
且失败并且缺少符号(例如libMissingSymbol.so
)的二进制文件都会找到新的(空)libMiddle.so
,但因为新的libMiddle.so
需要libZiddle.so
(其中大部分符号都是)和 libSymbolHaver.so
,它应该可以正常工作。