Gcc 是什么使ELF库中的符号成为对象或普通符号?
我有一个应用程序正在通过Gcc 是什么使ELF库中的符号成为对象或普通符号?,gcc,shared-libraries,ld,elf,Gcc,Shared Libraries,Ld,Elf,我有一个应用程序正在通过dlopen加载一些插件,特别是dlopen(name,RTLD_LAZY | RTLD_DEEPBIND)。有一些插件(以二进制形式提供)可以正常加载,但我尝试构建的插件加载失败,出现错误: /opt/app/plugins/plugin.so: undefined symbol: Log_Modules 所有插件都引用该符号,提供该符号的库将在该过程中加载。但是,objdump-D打印的条目不同。在加载它的插件中说 00000000 DO *UND*
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
的手册页上说,该标志的意思是
符号是函数(F)、文件(F)、对象(O)或普通符号(空格)的名称
但是我没有看到任何关于物体和普通符号之间区别的提示。所以
- 有什么区别, 是什么使符号在C或C++语言或链接器级别和中成为一个或另一个符号?
- 它真的应该使符号无法解析吗
.st_info
包含STT_对象
,而不是STT_FUNC
符号在C或C++语言或链接器级别
中的符号 在C
级别,编译器将在发出汇编代码时用@function
标记函数标签,而汇编器将在发出符号表时添加STT_FUNC
标志
它真的应该使符号无法解析吗
不,你的问题很可能与此无关
一般来说,objdump
是查看ELF文件的错误工具(它映射到BFD数据模型,该模型在过去20多年中已经过时)。改用readelf
胡乱猜测:你的插件。因此
定义了符号,但没有导出符号。使用
nm -D plugin.so | grep ' Log_Modules$'
nm plugin.so | grep ' Log_Modules$'
如果Log_Modules
显示在第二个命令输出中,而不是第一个命令输出中,那么我的猜测是正确的
有什么区别
O
标志对应于STT\u对象
标志,表示一个对象,即一个变量
符号在C或C++语言或链接器级别
中的符号 显然,链接器仅在实际看到定义时,即定义它的库作为依赖项提供时,才使用STT_对象
标记符号。外部声明本身没有标记
它真的应该使符号无法解析吗
解析符号时,链接器查找显式列出的依赖项,以及加载了RTLD_GLOBAL
的库,其中包括主可执行文件的依赖项。因此,当主可执行文件已经链接到定义库时,插件将不会显式链接它,但如果它本身加载了dlopen
(没有RTLD\u GLOBAL
),则不会
没有标记本身不是问题,但它暗示了缺少库引用的实际问题。请注意,我问题中的所有三行都有
D
标记,这意味着它们在第一个命令的输出中。对于定义符号的库,第二个命令的输出是空的,因为已经提供了它。函数工作正常。但我需要知道的是何时设置STT_对象标志。这不是你问题的答案,但不管怎样。@EmployedRussian,是的,是的。我没有指出为什么最后一段才是答案,所以我添加了它。