dlopen有两个共享库,导出符号

时间:2010-07-29 01:46:18

标签: linux shared-libraries dlopen

我有一个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,但这让我感到有点混乱。感谢。

2 个答案:

答案 0 :(得分:6)

foo.sobar.so相关联。

当可执行文件dlopen() s foo.sobar.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(重命名为其他)