我有一个linux共享库foo.so,它是使用dlopen("foo.so", RTLD_NOW | RTLD_LOCAL)
从可执行文件加载的。从foo.so我想dlopen另一个库bar.so,它引用了foo.so中定义的符号,但链接器无法找到它们。我无法将RTLD_LOCAL更改为RTLD_GLOBAL,因为我没有执行加载的可执行文件的源代码。我认为-Wl,--export-dynamic
在链接foo.so时可能会有所帮助,但它不会覆盖dlopen的本地标志。 GCC的新属性可见性功能看起来不像它提供了答案。
有没有办法可以指示链接器解析bar.so中未定义符号的引用到foo.so中的那些定义,没有链接bar与-lfoo或相似性将符号移动到第3个库并链接foo和对吧?对我来说唯一的事情就是从foo.so本身中删除foo.so和RTLD_GLOBAL,然后dlopen bar.so,但这让我感到有点混乱。感谢。
答案 0 :(得分:6)
将foo.so
与bar.so
相关联。
当可执行文件dlopen()
s foo.so
,bar.so
也将被加载。
或者,对可执行文件进行二进制修补,以将RTLD_GLOBAL
添加到dlopen()
调用的标志中。代码看起来像
movl $2, 4(%esp) # $2 == RTLD_NOW; RTLD_LOCAL is 0
movl $0xNNNNN, (%esp) # $0xNNNNN == &"foo.so"
call dlopen
将其修改为movl $0x102, 4(%esp)
而不是(RTLD_GLOBAL == 0x100
),然后瞧。
编辑:
如果您知道bar.so
的名称,则可以将foo.so
与“存根”bar.so
相关联。你没有“真实”bar.so
并不重要;重要的是foo.so
依赖于它。在运行时,只要加载bar.so
,依赖项就会导致foo.so
加载。
答案 1 :(得分:0)
这是另一种显示方式,如下所示:
可执行文件--dlopen本地-> fakefoo.so(重命名为foo)--dlopen全局-> foo.so(重命名为其他)