加载不同版本的多个共享库 [英] Loading multiple shared libraries with different versions

查看:177
本文介绍了加载不同版本的多个共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆