如何在.so文件中列出符号
如何列出从.so文件导出的符号。 如果可能的话,我也想知道他们的来源(例如,如果他们从一个静态库拉入)。
我使用gcc 4.0.2,如果这有所作为
列出符号的标准工具是nm
,你可以简单地使用它:
nm -g yourLib.so
如果你想看到一个C ++库的符号,添加“-C”选项来去除符号(它的可读性更强)。
nm -gC yourLib.so
如果你的.so文件是elf格式,你有两个select:
objdump
( -C
对demangling C ++也是有用的):
$ objdump -TC libz.so libz.so: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000002010 ld .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
文件中定义的那些,而不是在它所引用的库中。 在这种情况下,第七列应该包含一个数字。 你可以使用一个简单的正则expression式来提取它:
readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
或者按照Caspin的build议,
readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so
我一直想知道为什么-fvisibility = hidden和#pragma GCC的可见性似乎没有任何影响,因为所有的符号总是可见的nm – 直到我发现这篇文章,指出我readelf和objdump ,这让我意识到,那里似乎实际上是两个符号表:
- 可以用nm列出的那个
- 可以用readelf和objdump列出的那个
我认为前者包含可以剥离的debugging符号,或者可以提供给链接器或安装命令的-s开关。 即使nm不再列出任何东西,导出的符号仍然被导出,因为它们在ELF“dynamic符号表”中,后者是后者。
对于共享库libNAME.so,-D开关对于在我的Linux中查看符号是必需的
nm -D libNAME.so
和其他人报告的静态库
nm -g libNAME.a
尝试添加-l nm标志为了得到每个符号的来源。 如果库是用debugging信息(gcc -g)编译的,这应该是源文件和行号。 正如康拉德所说,目标文件/静态库在这一点上可能是未知的。
您可以使用binutils工具链中的nm -g
工具。 但是,他们的来源并不总是随时可用。 我甚至不确定这个信息总是可以被检索到的。 也许objcopy
揭示进一步的信息。
/编辑:工具的名字当然是nm
。 标志-g
用于仅显示导出的符号。
对于Android .so
文件,NDK工具链随附其他答案中提到的所需工具: readelf
, objdump
和nm
。
nm -g列出externvariables,这是不需要导出的符号。 任何非静态文件范围variables(在C中)都是externvariables。
nm -D将在dynamic表中列出符号,您可以通过dlsymfind它的地址。
nm –version
GNU nm 2.17.50.0.6-12.el5 20061020