将符号限制为Linux可执行文件的本地范围

时间:2009-11-26 16:26:15

标签: linux linker symbols

有人可以建议我们可以限制将符号导出到全局符号表吗?

提前致谢


您好,

感谢您的回复...

实际上我有一个静态链接到第三方库的可执行文件说“ver1.a”,并且还使用了第三方“.so”文件,该文件再次链接到同一个库,但不同的版本说“ver2.a” 。问题是这两个版本的实现是不同的。开始时,加载可执行文件时,“ver1.a”中的符号将导出到全局符号表。现在每当加载“.so”时,它将尝试引用ver2.a中的符号,它最终将引用先前加载的“ver1.a”中的符号。这会使我们的二进制文件崩溃。

我们想到了一个解决方案,我们不会将可执行文件的符号导出到全局符号表,因此当“.so”被加载并尝试使用ver2.a中的符号时,它将无法在全局符号表中找到它并且它将使用自己的符号,即ver2.a

中的符号

我无法通过哪种方式限制将符号导出到全局符号表。我尝试使用--version-script和retain-symbol-file,但它没有用。对于-fvisibility = hidden选项,它给出一个错误“-f选项只能与-shared一起使用”。所以我想,这也像“--version-script”只适用于共享库而不适用于可执行二进制文件。

代码在c ++,OS-Linux,gcc version-3.2中。可能无法重新编译任何第三方库和“.so”。因此,排除了使用bsymbolic标志重新编译“so”文件的选项。

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:2)

使用dlopen拉入第三方库。

您可以通过创建自己的共享库来避免这种情况,该共享库隐藏所有第三方符号并仅向其公开您自己的API,但如果所有其他方法都失败,则dlopen将为您提供完全控制。

答案 1 :(得分:1)

我听到了类似的问题:Segfault on C++ Plugin Library with Duplicate Symbols

如果您可以重建第三方库,可以尝试添加链接器标志-Bsymbolic(gcc / g ++的标志为-Wl,-Bsymbolic)。这可能会解决您的问题。这一切都取决于你的代码和东西的组织,因为有使用它的警告:
http://www.technovelty.org/code/c/bsymbolic.html
http://software.intel.com/en-us/articles/performance-tools-for-software-developers-bsymbolic-can-cause-dangerous-side-effects/

如果你不能重建它,根据第一个警告链接:

  事实上,唯一的事情是-Bsymbolic   标志在构建共享时执行   库在动态中添加一个标志   被称为二进制文件的部分   DT_SYMBOLIC。

那么也许有一种方法可以将DT_SYMBOLIC标志添加到动态部分后链接中?

答案 2 :(得分:0)

最简单的解决方案是重命名可执行文件中的符号(通过更改源代码),这样它们就不会与共享库发生冲突。

下一个最简单的事情是使用'objcopy -L problem_symbol'本地化“问题”符号。

最后,如果你没有直接链接到第三方库(但是反过来,就像bmargulies建议的那样),你的其他共享库都没有使用定义“问题”符号,您没有链接-rdynamic或其等价物,那么该符号不应该导出到可执行文件的动态符号表,因此您不应该没有冲突。

注意:'nm a.out' 仍然,将符号显示为全局定义,但这与动态链接无关。您想查看a.out的{​​{1>} 动态符号表。