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.
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.
Link foo.so
against bar.so
.
When the executable dlopen()
s foo.so
, bar.so
will also be loaded.
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
Patch it to movl $0x102, 4(%esp)
instead (RTLD_GLOBAL == 0x100
), and voilà.
EDIT:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With