9

我有一个 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 中的那些定义,而无需使用 -lfoo 链接 bar 或相似性将符号移动到第三个库中并将 foo 和 bar 链接到它? 我唯一想到的是从 foo.so 本身使用 RTLD_GLOBAL dlopen foo.so,然后 dlopen bar.so,但这让我觉得有点乱。谢谢。

4

2 回答 2

6

链接foo.so反对bar.so

当可执行文件dlopen()s foo.sobar.so也将被加载。

或者,对可执行文件进行二进制修补以添加RTLD_GLOBALdlopen()调用标志。代码看起来像

    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项。

于 2010-07-31T01:15:59.500 回答
0

这是另一种方式显示如下:

excutable --dlopen local--> fakefoo.so(rename to foo) --dlopen global--> foo.so(rename to other)

于 2020-07-30T04:33:32.220 回答