我有一个应用程序通过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
的手册页只是说该标志意味着
The symbol is the name of a function (F) or a file (f) or an object (O) or just a normal symbol (a space).
但我没有看到任何关于对象和普通符号之间区别的提示。所以
- 有什么区别
- 在 C 或 C++ 语言或链接器级别上使符号成为其中之一的因素以及
- 它确实应该使符号无法解析吗?
最佳答案
what is the difference
符号表.st_info
包含STT_OBJECT
而不是STT_FUNC
。
what makes the symbol one or the other at the C or C++ language or linker level
在C
级别,编译器在发出汇编代码时将使用@function
标记函数标签,汇编器在发出符号时将添加STT_FUNC
标志表。
is it indeed supposed to make the symbol not resolve?
没有。您的问题很可能与此无关。
一般来说,objdump
是查看 ELF 文件的错误工具(它映射到 BFD 数据模型,该模型在过去 20 多年中已过时)。请改用 readelf
。
大胆猜测:您的 plugin.so
定义了该符号,但未导出该符号。使用
nm -D plugin.so | grep ' Log_Modules$'
nm plugin.so | grep ' Log_Modules$'
如果 Log_Modules
出现在第二个命令输出中,但没有出现在第一个命令输出中,那么我的猜测是正确的。
关于gcc - 是什么使 ELF 库中的符号成为对象或普通符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55520724/