加载不同版本的多个共享库 [英] Loading multiple shared libraries with different versions
问题描述
我在Linux上有一个可执行文件,它载入 libfoo.so.1
(这是一个 SONAME
)作为它的依赖关系(通过另一个共享库)。它还链接到另一个系统库,该库又链接到 system 版本, libfoo.so.2
。因此, libfoo.so.1
和 libfoo.so.2
都是在执行期间加载,以及应该从版本1调用库函数的代码最终会从具有版本2的较新系统库调用(二进制不兼容)函数,因为某些符号保持不变。结果通常是堆栈粉碎和后续的段错误。
现在,与旧版本链接的库是一个封闭源代码的第三方库, t控制它编译的版本 libfoo
。假设,剩下的唯一选择是重建一系列与 libfoo.so.2
链接的系统库以链接 libfoo.so。 1
。
有没有办法避免用本地副本替换系统库,链接到旧的 libfoo
?我可以加载这两个库并让代码调用正确版本的符号吗?所以我需要一些特殊的符号级别的版本控制功能?
您可能可以执行一些版本脚本技巧:
http: //sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html
这可能需要你编写一个包装器在你的lib中引入libfoo.so.1,它显式地导出一些符号,并将所有其他符号作为本地掩码。例如:
MYSYMS {
global:
foo1;
foo2;
local:
*;
};
当你连接这个包装器时使用它:
gcc -shared - Wl, - version-script,mysyms.map -o mylib wrapper.o -lfoo -L / path / to / foo.so.1
这应该使libfoo .so.1的符号是包装本地的,不可用于主要的exe。
I have an executable on Linux that loads libfoo.so.1
(that's a SONAME
) as one of its dependencies (via another shared library). It also links to another system library, which, in turn, links to a system version, libfoo.so.2
. As a result, both libfoo.so.1
and libfoo.so.2
are loaded during execution, and code that was supposed to call functions from library with version 1 ends up calling (binary-incompatible) functions from a newer system library with version 2, because some symbols stay the same. The result is usually stack smashing and a subsequent segfault.
Now, the library which links against the older version is a closed-source third-party library, and I can't control what version of libfoo
it compiles against. Assuming that, the only other option left is rebuilding a bunch of system libraries that currently link with libfoo.so.2
to link with libfoo.so.1
.
Is there any way to avoid replacing system libraries wiith local copies that link to older libfoo
? Can I load both libraries and have the code calling correct version of symbols? So I need some special symbol-level versioning?
You may be able to do some version script tricks:
http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html
This may require that you write a wrapper around your lib that pulls in libfoo.so.1 that exports some symbols explicitly and masks all others as local. For example:
MYSYMS { global: foo1; foo2; local: *; };
and use this when you link that wrapper like:
gcc -shared -Wl,--version-script,mysyms.map -o mylib wrapper.o -lfoo -L/path/to/foo.so.1
This should make libfoo.so.1's symbols local to the wrapper and not available to the main exe.
这篇关于加载不同版本的多个共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!