[英]How do I list the symbols in a .so file
如何列出从 .so 文件导出的符号? 如果可能的话,我还想知道它们的来源(例如,如果它们是从静态库中提取的)。
我正在使用 gcc 4.0.2,如果这有所作为的话。
列出符号的标准工具是nm
,您可以像这样简单地使用它:
nm -gD yourLib.so
如果您想查看 C++ 库的符号,请添加“-C”选项来对符号进行分解(分解后的可读性更高)。
nm -gDC yourLib.so
如果你的 .so 文件是 elf 格式,你有两个选择:
要么objdump
( -C
对分解 C++ 也很有用):
$ objdump -TC libz.so
libz.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000002010 l d .init 0000000000000000 .init
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
或者使用readelf
:
$ readelf -Ws libz.so
Symbol table '.dynsym' contains 112 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000002010 0 SECTION LOCAL DEFAULT 10
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.2.5 (14)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __errno_location@GLIBC_2.2.5 (14)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
如果你的.so
文件是 elf 格式,你可以使用 readelf 程序从二进制文件中提取符号信息。 此命令将为您提供符号表:
readelf -Ws /usr/lib/libexample.so
您只应提取在此.so
文件中定义的那些,而不是在它引用的库中。 在这种情况下,第七列应包含一个数字。 您可以使用简单的正则表达式提取它:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
或者,正如Caspin所提议的,:
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
对于共享库 libNAME.so 必须使用 -D 开关才能在我的 Linux 中查看符号
nm -D libNAME.so
以及其他人报告的静态库
nm -g libNAME.a
我一直想知道为什么-fvisibility=hidden和#pragma GCC 可见性似乎没有任何影响,因为所有符号在nm 下始终可见 - 直到我发现这篇文章将我指向readelf和objdump ,这让我意识到那里似乎实际上是两个符号表:
我认为前者包含可以用strip或 -s 开关去除的调试符号,您可以将它们提供给链接器或安装命令。 即使 nm 不再列出任何内容,您导出的符号仍然会被导出,因为它们在 ELF“动态符号表”中,也就是后者。
对于 C++ .so
文件,最终的nm
命令是nm --demangle --dynamic --defined-only --extern-only <my.so>
# nm --demangle --dynamic --defined-only --extern-only /usr/lib64/libqpid-proton-cpp.so | grep work | grep add
0000000000049500 T proton::work_queue::add(proton::internal::v03::work)
0000000000049580 T proton::work_queue::add(proton::void_function0&)
000000000002e7b0 W proton::work_queue::impl::add_void(proton::internal::v03::work)
000000000002b1f0 T proton::container::impl::add_work_queue()
000000000002dc50 T proton::container::impl::container_work_queue::add(proton::internal::v03::work)
000000000002db60 T proton::container::impl::connection_work_queue::add(proton::internal::v03::work)
来源: https ://stackoverflow.com/a/43257338
对于 Android .so
文件,NDK 工具链附带了其他答案中提到的所需工具: readelf
、 objdump
和nm
。
您可以使用 binutils 工具链中的nm -g
工具。 然而,它们的来源并不总是容易获得。 而且我什至不确定这些信息是否总能被检索到。 也许objcopy
揭示了更多信息。
/编辑:该工具的名称当然是nm
。 标志-g
用于仅显示导出的符号。
尝试将 -l 添加到 nm 标志以获取每个符号的来源。 如果库是用调试信息 (gcc -g) 编译的,这应该是源文件和行号。 正如康拉德所说,目标文件/静态库此时可能是未知的。
nm -g 列出extern 变量,它不是必需的导出符号。 任何非静态文件范围变量(在 C 中)都是外部变量。
nm -D 将列出动态表中的符号,您可以通过 dlsym 找到它的地址。
纳米--版本
GNU 纳米 2.17.50.0.6-12.el5 20061020
如果您只想知道是否存在符号,您可以使用
objdump -h /path/to/object
或列出调试信息
objdump -g /path/to/object
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.