什么是 DSO?
DSO 是一个动态共享对象,或者不太正式的shared library。
什么是隐藏符号?
隐藏符号是一个符号(即函数或数据对象的名称)
已使用隐藏链接编译,例如根据(特定于 GCC)
声明:
int x __attribute__ ((visibility ("hidden")));
如果x 在一个 DSO 中定义,则动态链接无法从一个 DSO 引用它
不同的 DSO。链接器可以看到x(不是static),但不是
可用于动态链接。文档here
如果隐藏了怎么引用?
不可能,这是你被警告的。例如。链接时警告:
/usr/lib/libc_nonshared.a(stat.oS) 中的隐藏符号 `stat' 被 DSO 引用
告诉您链接中的 DSO 引用符号 stat,并且
链接器可以在/usr/lib/libc_nonshared.a 中找到stat 的定义,
但是(显然)该定义不在引用它的 DSO 中
并且无法从该 DSO 中引用,因为它是隐藏的。
如果问题 DSO 未正确构建以供使用,则会出现此问题
作为 DSO。见this example
并跟进解决方案。
继续 OP 的跟进
如果某个 DSO 已经引用了隐藏符号,那么为什么 DSO 会出现问题?
链接器说:
DSO X 包含对符号 S 的引用。我可以找到符号S的定义是另一个链接模块Y,
但该定义将无法满足X 中的引用动态(即在运行时),因为S 在Y 中有隐藏链接。
我可以确认问题出在非共享对象上 [...][但是] 我没有在我的非共享对象中明确隐藏这些符号。
您可能没有明确标记非共享对象中隐藏的任何符号。根据它的构建方式,符号
默认情况下可能隐藏,除非明确标记否则。
假设非共享对象是libnonshared.a,据称隐藏的符号是foo。运行:
objdump -t libnonshared.a
获取有关libnonshared.a 中符号的信息。在输出中,查找 foo 的条目。它是否包含标签.hidden? - 例如
0000000000000000 g F .text 000000000000000b .hidden foo
此条目说foo 是一个全局符号(标记为g - 这就是链接器能够看到它的原因)但是它对于动态链接是隐藏的.
如果是这种情况,那么您需要修复libnonshared.a 的构建,以便它不会隐藏foo。
如果没有,那我就难住了。