gpt4 book ai didi

Linux、GNU GCC、ld、版本脚本和 ELF 二进制格式——它是如何工作的?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:40:45 30 4
gpt4 key购买 nike

我正在努力了解更多关于 Linux 中的库版本控制以及如何将其全部投入使用的信息。这是上下文:

-- 我有两个版本的动态库,它们公开了同一组接口(interface),比如 libsome1.solibsome2.so

-- 应用程序链接到 libsome1.so

-- 此应用程序使用 libdl.so 动态加载另一个模块,比如 libmagic.so

-- 现在 libmagic.so 链接到 libsome2.so。显然,如果不使用链接器脚本隐藏 libmagic.so 中的符号,在运行时所有对 libsome2.so 中接口(interface)的调用都将解析为 libsome1.so。这可以通过检查 libVersion() 返回的值与宏 LIB_VERSION 的值来确认。

-- 所以我接下来尝试使用链接描述文件编译和链接 libmagic.so通过它。这有效...或者至少 libVersion()LIB_VERSION 值匹配(并且它报告版本 2 而不是 1)。

-- 然而,当一些数据结构被序列化到磁盘时,我注意到一些损坏。在应用程序的目录中,如果我删除 libsome1.so 并在其位置创建一个指向 libsome2.so 的软链接(soft link),一切都会按预期工作并且不会发生相同的损坏.

我不禁想到这可能是由于运行时链接器对符号的解析存在一些冲突造成的。我已经尝试了很多事情,比如尝试链接 libsome2.so 以便所有符号都与 symbol@@VER_2 一致(我仍然对此感到困惑,因为命令 nm -CD libsome2.so 仍然将符号列为 symbol 而不是 symbol@@VER_2)...似乎没有任何效果!!!求助!!!!!!

编辑:我应该早点提到它,但有问题的应用程序是 Firefox,libsome1.solibsqlite3.so 附带的。我不太有重新编译它们的选择。此外,使用版本脚本来隐藏符号似乎是目前唯一的解决方案。那么当符号被隐藏时到底发生了什么?他们是否成为 SO 的“本地”? rtld 不知道它们的存在吗?当导出函数引用隐藏符号时会发生什么?

最佳答案

尝试同时编译 libsome1.solibsome2.so 以添加符号版本控制,每个都有自己的版本(使用 --version-script 选项到 ld)。然后使用新库链接应用程序和 libmagic.so。然后,libsome1.solibsome2.so 应该是完全分开的。

如果存在未版本化的符号引用,问题仍然会发生。此类引用可以通过版本化定义来满足(这样就可以在不破坏二进制兼容性的情况下将符号版本化添加到库中)。如果有多个同名符号,有时很难预测将使用哪一个。

关于工具,nm -D 不显示有关符号版本控制的任何信息。请尝试使用 objdump -Treadelf -s

关于Linux、GNU GCC、ld、版本脚本和 ELF 二进制格式——它是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4665452/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com