如何在.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 – 直到我发现这篇文章,指出我readelfobjdump ,这让我意识到,那里似乎实际上是两个符号表:

  • 可以用nm列出的那个
  • 可以用readelfobjdump列出的那个

我认为前者包含可以剥离的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工具链随附其他答案中提到的所需工具: readelfobjdumpnm

nm -g列出externvariables,这是不需要导出的符号。 任何非静态文件范围variables(在C中)都是externvariables。

nm -D将在dynamic表中列出符号,您可以通过dlsymfind它的地址。

nm –version

GNU nm 2.17.50.0.6-12.el5 20061020