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

aby*_*s.7 32 c++ linker gcc shared-libraries elf

我有一个问题链接一些共享库与g ++.它给了我一个警告:

hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
Run Code Online (Sandbox Code Playgroud)

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

  1. 什么是DSO?
  2. 什么是隐藏的符号?
  3. 如果被隐藏的话怎么引用呢?

Mik*_*han 33

什么是DSO?

DSO是一个动态共享对象,或小于正式一个共享库.

什么是隐藏的符号?

隐藏符号是一个符号已被编译(即,函数或数据对象名称)隐藏联动,例如,作为按照(GCC特异性)的声明:

int x __attribute__ ((visibility ("hidden")));
Run Code Online (Sandbox Code Playgroud)

如果x在一个DSO中定义,则动态链接不能从不同的DSO引用它.链接器可以看到x(它不是static),但它不可用于动态链接.文档在这里

如果被隐藏的话怎么引用呢?

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

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

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

如果问题DSO未正确构建用作DSO,则会出现此问题.请参阅此示例 并按照解决方案的后续步骤进行操作.

继续进行OP的跟进

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

链接器说:

DSO X包含对符号的引用S.我可以发现符号的定义S是另一个链接模块Y,但是该定义不能用于X 动态地(即在运行时)满足引用,因为它S具有隐藏的链接Y.

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

您可能没有明确标记隐藏在非共享对象中的任何符号.这取决于它是如何构建的,符号可以默认为隐藏,除非明确标明,否则.

假设非共享对象是libnonshared.a,并且涉嫌隐藏的符号是foo.跑:

objdump -t libnonshared.a
Run Code Online (Sandbox Code Playgroud)

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

0000000000000000 g     F .text  000000000000000b .hidden foo
Run Code Online (Sandbox Code Playgroud)

此条目表示这foo是一个全局符号(标记g- 这就是链接器能够看到它的原因),它隐藏了动态链接.

如果情况确实如此,那么你需要去修复它的构建,libnonshared.a以便它不会隐藏foo.如果没有,那我就难倒了.