带有两个共享库的dlopen,可导出符号
我有一个Linux共享库foo.so,它使用 dlopen("foo.so",RTLD_NOW | RTLD_LOCAL)
从可执行文件加载.我想从foo.so中打开另一个库bar.so,该库引用foo.so中定义的符号,但是链接程序无法找到它们.我无法将RTLD_LOCAL更改为RTLD_GLOBAL,因为我没有可执行文件的源进行加载.我认为在链接foo.so时 -Wl,-export-dynamic
可能会有所帮助,但它不会将本地标志覆盖到dlopen.GCC的新属性可见性功能似乎也无法提供答案.
I have a linux shared library, foo.so, which is loaded from an executable using dlopen("foo.so", RTLD_NOW | RTLD_LOCAL)
. From foo.so I'd like to dlopen another library, bar.so, which references symbols defined in foo.so, but the linker fails to find them. I can't change RTLD_LOCAL to RTLD_GLOBAL, because I don't have the source to the executable doing the loading. I thought -Wl,--export-dynamic
when linking foo.so might help but it doesn't override the local flag to dlopen. GCC's new attribute visibility feature doesn't look like it offers the answer either.
有没有一种方法可以指示链接器将 bar.so 中未定义符号的引用解析为 foo.so 中的那些定义,而无需将 bar 与 -lfoo 或相似性链接起来,将符号移动到第三个库中并同时链接 foo 和反对吗?对我而言,唯一发生的事情是从foo.so本身内部使用RTLD_GLOBAL进行dlopen foo.so,然后是dlopen bar.so,但这使我有些混乱.谢谢.
Is there a way I can instruct the linker to resolve references to undefined symbols in bar.so to those definitions in foo.so, without linking bar with -lfoo or similarity moving the symbols into a 3rd library and linking both foo and bar against it? The only thing that occurs to me is to dlopen foo.so with RTLD_GLOBAL from within foo.so itself, then dlopen bar.so, but that strikes me as a bit of a mess. Thanks.
将 foo.so
与 bar.so
链接.
当可执行文件 dlopen()
的 foo.so
时,还将加载 bar.so
.
When the executable dlopen()
s foo.so
, bar.so
will also be loaded.
或者,对可执行文件进行二进制修补,将 RTLD_GLOBAL
添加到 dlopen()
调用的标志中.代码看起来像
Alternatively, binary-patch the executable to add RTLD_GLOBAL
to the flags for dlopen()
call. The code will look something like
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
),然后贴上.
Patch it to movl $0x102, 4(%esp)
instead (RTLD_GLOBAL == 0x100
), and voilà.
如果您知道 bar.so
的名称,则可以将 foo.so
链接到存根" bar.so
.您没有真实的" bar.so
没关系;重要的是 foo.so
对此具有依赖性.在运行时,只要加载 foo.so
,该依赖关系就会导致加载 bar.so
.
If you know the name of bar.so
, then you can link foo.so
against a "stub" bar.so
. It doesn't matter that you don't have "real" bar.so
; all that matters is that foo.so
has a dependency on it. At runtime that dependency will cause bar.so
to be loaded whenever foo.so
is loaded.