关于隐藏符号被DSO引用的警告意味着什么?

时间:2014-05-16 13:38:07

标签: c++ gcc linker shared-libraries elf

我在将一些共享库与g ++链接时遇到问题。它给了我一个警告:

hidden symbol XXX in YYY is referenced by DSO /usr/lib/...

我已经阅读了一些有关特定问题的相关问题,但我想在整体上理解它 - 这个警告意味着什么,原因是什么:

  1. 什么是DSO?
  2. 什么是隐藏符号?
  3. 如果它被隐藏了怎么能被引用?

1 个答案:

答案 0 :(得分:30)

什么是DSO?

DSO 动态共享对象,或者更不正式的shared library

什么是隐藏符号?

隐藏符号是一个符号(即函数或数据对象的名称) 已使用隐藏链接编译,例如根据(GCC具体) 声明:

int x __attribute__ ((visibility ("hidden")));

如果在一个DSO中定义x,则动态链接无法从a引用它 不同的DSO。链接器可以看到x(它不是static),但事实并非如此 可用于动态链接。文档here

如果它被隐藏了怎么能被引用?

它不可能,这是你被警告的内容。例如。链接时间警告:

  

隐藏符号`stat'在/usr/lib/libc_nonshared.a(stat.oS)中由DSO引用

告诉您链接中的DSO引用了符号stat,和 链接器可以在stat中找到/usr/lib/libc_nonshared.a的定义, 但(显然)该定义不在引用它的DSO中 并且不能从该DSO引用,因为它是隐藏的。

如果问题DSO未正确构建以供使用,则会出现此问题 作为DSO。见this example 并按照解决方案的后续行动。

继续进行OP的跟进

  

如果某些DSO已经引用了隐藏符号,那么为什么问题出在DSO上?

链接器说:

DSO X包含对符号S的引用。我可以找到符号S的定义是另一个链接模块Y, 但是该定义无法满足X 动态中的引用(即在运行时),因为S在{{1}中隐藏了链接}}

  

我可以确认问题来自非共享对象[...] [但]我没有在我的非共享对象中明确隐藏这些符号。

您可能没有明确标记隐藏在非共享对象中的任何符号。根据它的构建方式,符号 默认情况下可能会隐藏,除非明确标记否则

假设非共享对象为Y,并且涉嫌隐藏的符号为libnonshared.a。运行:

foo

获取有关objdump -t libnonshared.a 中符号的信息。在输出中,查找libnonshared.a的条目。它是否包含标记foo? - 例如

.hidden

此条目表示0000000000000000 g F .text 000000000000000b .hidden foo 是一个全局符号(标记为foo - 这就是链接器能够看到它的原因)它'隐藏动态链接。

如果情况确实如此,那么您需要修复g的版本,以便它不会隐藏libnonshared.a。 如果没有,那我就难倒了。