2010-07-29 69 views
6

我有一个Linux共享库,foo.so,它是从使用dlopen("foo.so", RTLD_NOW | RTLD_LOCAL)可执行加载。从foo.so开始,我想将另一个库bar.so放到另一个库中,它引用了foo.so中定义的符号,但链接程序未能找到它们。我无法将RTLD_LOCAL更改为RTLD_GLOBAL,因为我没有执行加载的可执行文件的源代码。我认为-Wl,--export-dynamic当链接foo.so可能会帮助,但它不会覆盖本地标志为dlopen。 GCC的新属性可见性功能看起来并不像它提供的答案。dlopen的具有两个共享库,导出符号

有没有一种方法可以指示链接器将bar.so中未定义符号的引用解析为foo.so中的那些定义,而不使用链接栏与-lfoo或相似性将符号移动到第3个库中并将这两个foo并阻止它呢?这发生在我的唯一的事情是从内部foo.so本身,然后使用dlopen bar.so与RTLD_GLOBAL到dlopen的foo.so,但在我看来是一个有点乱。谢谢。

回答

4

链接foo.sobar.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加载到被加载。

+0

感谢您的答复。我无法将foo.so与bar.so链接,因为bar.so将是用户提供的插件。我也无法修补的可执行文件,因为这通常会是超级用户拥有的客户的系统上,我不知道修补它会下去太清楚他们,它确实复杂安装过程颇有几分。它也会打破执行官开放的其他图书馆,其中一些依赖于RTLD_LOCAL。我想我必须跟着dlopen foo.so从本身入手,这似乎很有效。干杯 – 2010-07-31 12:10:41

相关问题