是什么让ELF库中的符号成为对象或普通符号?

问题描述 投票:1回答:2

我有一个应用程序正在通过dlopen加载一些插件,特别是dlopen(name, RTLD_LAZY|RTLD_DEEPBIND)。有一些插件(以二进制形式提供)加载正常,但我尝试构建的插件无法加载错误:

/opt/app/plugins/plugin.so: undefined symbol: Log_Modules

所有插件都引用该符号,并在此过程中加载提供它的库。然而,objdump -D印刷的条目不同。在加载它的插件中说

00000000      DO *UND*       00000000              Log_Modules

它在定义它的图书馆中说

000130dc g    DO .data       00000004  Base        Log_Modules

而在我建立的模块中说

00000000      D  *UND*       00000000              Log_Modules

objdump的手册页只是说旗帜意味着

符号是函数(F)或文件(f)或对象(O)的名称,或者只是普通符号(空格)的名称。

但我没有看到任何关于对象和普通符号之间差异的提示。所以

  • 有什么不同,
  • 是什么使得符号在C或C ++语言或链接器级别上是一个或另一个
  • 它确实应该使符号不能解决?
gcc shared-libraries ld elf
2个回答
2
投票

有什么不同

符号表.st_info包含STT_OBJECT而不是STT_FUNC

是什么使符号在C或C ++语言或链接器级别中的一个或另一个

C级别,编译器在发出汇编代码时会用@function标记函数标签,汇编器在发出符号表时会添加STT_FUNC标志。

它确实应该使符号不能解决?

不,你的问题很可能与此无关。

一般来说,objdump是查看ELF文件的错误工具(它映射到BFD数据模型,过去20多年来已经过时)。请改用readelf

狂野猜测:你的plugin.so定义,但不导出符号。使用

nm -D plugin.so | grep ' Log_Modules$'
nm    plugin.so | grep ' Log_Modules$'

如果Log_Modules出现在第二个命令输出中,但不是第一个,那么我的猜测是正确的。


0
投票

有什么不同

O标志对应于STT_OBJECT标志,表示一个对象,即一个变量。

是什么使符号在C或C ++语言或链接器级别中的一个或另一个

显然,链接器仅在实际看到定义的情况下用STT_OBJECT标记标记符号,即当定义它的库作为依赖项提供时。仅外部声明没有标记。

它确实应该使符号不能解决?

解析符号时,链接器会查找显式列出的依赖项,以及使用RTLD_GLOBAL加载的库,其中包含主可执行文件的依赖项。因此,当主可执行文件已经发生链接定义库时,插件将不会显式链接它,但如果它本身加载了dlopen(没有RTLD_GLOBAL),它就不会。

缺少标志本身不是问题,但它暗示了缺少库引用的实际问题。

© www.soinside.com 2019 - 2024. All rights reserved.