如何在.so文件中列出符号

Moe*_*Moe 444 c c++ gcc symbols name-mangling

如何列出从.so文件导出的符号?如果可能的话,我也想知道它们的来源(例如,如果它们是从静态库中引入的).

我正在使用gcc 4.0.2,如果这有所不同.

Ste*_*ury 534

用于列出符号的标准工具是nm,您可以像这样使用它:

nm -gD yourLib.so
Run Code Online (Sandbox Code Playgroud)

如果要查看C++库的符号,请添加"-C"选项,该符号对符号进行解码(它的解码性更强).

nm -gDC yourLib.so
Run Code Online (Sandbox Code Playgroud)

如果您的.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
Run Code Online (Sandbox Code Playgroud)

或使用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
Run Code Online (Sandbox Code Playgroud)

  • 但是,这并不总是适用于.so文件,因此您可能必须使用另一个答案中提到的"readelf"解决方案. (33认同)
  • 请注意,OS X版本的nm缺少用于解码符号的"-C"选项.可以使用c ++ filt代替.示例脚本:http://v8.googlecode.com/svn/branches/bleeding_edge/tools/mac-nm nm -g /usr/lib/libstdc++.6.dylib | c ++ filt -p -i (9认同)
  • 请注意,`readelf -Ws`将显示*all*符号,而`nm -g`仅显示外部可见符号.如果您正在检查多个符号文件并开始交换命令,这可能会造成混淆. (5认同)
  • 我还要在列表中添加`objectdump -TC`.与`readelf -Ws`相反,它没有显示损坏的名称. (3认同)
  • @BrooksMoses对于.so文件,您可能需要在nm命令行中添加--dynamic。 (2认同)

P S*_*ved 80

如果您的.so文件是elf格式,则可以使用readelf程序从二进制文件中提取符号信息.此命令将为您提供符号表:

readelf -Ws /usr/lib/libexample.so
Run Code Online (Sandbox Code Playgroud)

您只应提取在此.so文件中定义的那些,而不是在它引用的库中.在这种情况下,第七列应包含数字.您可以使用简单的正则表达式提取它:

readelf -Ws /usr/lib/libstdc++.so.6 | grep '^\([[:space:]]\+[^[:space:]]\+\)\{6\}[[:space:]]\+[[:digit:]]\+'
Run Code Online (Sandbox Code Playgroud)

或者,如Caspin所建议的那样:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
Run Code Online (Sandbox Code Playgroud)

  • readelf -Ws /usr/lib/libstdc++.so.6 | awk'{print $ 8}'; 正则表达式很棒,但有时一点点awk很长的路要走. (18认同)

小智 52

objdump -TC /usr/lib/libexample.so
Run Code Online (Sandbox Code Playgroud)

  • 好的.给出证明有用的解码名称 (3认同)

cav*_*ila 39

对于共享库libNAME.so,在我的Linux中查看符号需要-D开关

nm -D libNAME.so
Run Code Online (Sandbox Code Playgroud)

以及其他人报告的静态库

nm -g libNAME.a
Run Code Online (Sandbox Code Playgroud)


Pet*_*ers 34

我一直想知道为什么-fvisibility =隐藏的#pragma GCC的知名度似乎没有产生任何影响,因为所有的符号总是与可见的纳米 -直到我发现这个职位,指出我readelfobjdump的,这让我认识到,有似乎实际上是两个符号表:

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

我认为前者包含可以使用strip剥离的调试符号或者可以为链接器或install命令提供的-s开关.即使nm不再列出任何内容,导出的符号仍会被导出,因为它们位于ELF"动态符号表"中,后者就是后者.

  • nm -D - 允许您列出动态符号表 (9认同)
  • 谢谢!这解释了为什么有时"nm"没有显示.so文件的任何符号. (3认同)

use*_*610 14

对于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)
Run Code Online (Sandbox Code Playgroud)

来源:https://stackoverflow.com/a/43257338

  • @Treviño `nm` 在我的系统上有 `--with-symbol-versions` 。我用 `glibc.so` 尝试过,但不管有没有它,输出都是一样的......需要更多的调查。eidt:我还忘记使用“--dynamic”。有了这个,它就起作用了。我在输出中得到例如“iswupper”不带和“iswupper@@GLIBC_2.2.5”带。 (2认同)

Ada*_*itz 11

尝试将-l添加到nm标志以获取每个符号的来源.如果使用调试信息(gcc -g)编译库,则应该是源文件和行号.正如Konrad所说,此时对象文件/静态库可能是未知的.


Adi*_*vit 11

对于Android的.so文件时,NDK工具链附带有其他的答案中提到的所需的工具:readelf,objdumpnm.


Kon*_*lph 9

您可以使用nm -gbinutils工具链中的工具.但是,它们的来源并不总是随时可用.我甚至不确定是否总能检索到这些信息.或许可以objcopy揭示更多信息

/编辑:工具的名称当然是nm.该标志-g用于仅显示导出的符号.


zha*_*fei 6

nm -g列出extern变量,这不是必需的导出符号.任何非静态文件范围变量(在C中)都是外部变量.

nm -D将列出动态表中的符号,您可以通过dlsym找到它的地址.

nm --version

GNU nm 2.17.50.0.6-12.el5 20061020