简体   繁体   English

如何列出 a.so 文件中的符号

[英]How do I list the symbols in a .so file

How do I list the symbols being exported from a.so file?如何列出从 .so 文件导出的符号? If possible, I'd also like to know their source (eg if they are pulled in from a static library).如果可能的话,我还想知道它们的来源(例如,如果它们是从静态库中提取的)。

I'm using gcc 4.0.2, if that makes a difference.我正在使用 gcc 4.0.2,如果这有所作为的话。

The standard tool for listing symbols is nm , you can use it simply like this:列出符号的标准工具是nm ,您可以像这样简单地使用它:

nm -gD yourLib.so

If you want to see symbols of a C++ library, add the "-C" option which demangle the symbols (it's far more readable demangled).如果您想查看 C++ 库的符号,请添加“-C”选项来对符号进行分解(分解后的可读性更高)。

nm -gDC yourLib.so

If your.so file is in elf format, you have two options:如果你的 .so 文件是 elf 格式,你有两个选择:

Either objdump ( -C is also useful for demangling C++):要么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

Or use readelf :或者使用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

If your .so file is in elf format, you can use readelf program to extract symbol information from the binary.如果你的.so文件是 elf 格式,你可以使用 readelf 程序从二进制文件中提取符号信息。 This command will give you the symbol table:此命令将为您提供符号表:

readelf -Ws /usr/lib/libexample.so

You only should extract those that are defined in this .so file, not in the libraries referenced by it.您只应提取在此.so文件中定义的那些,而不是在它引用的库中。 Seventh column should contain a number in this case.在这种情况下,第七列应包含一个数字。 You can extract it by using a simple regex:您可以使用简单的正则表达式提取它:

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

or, as proposed by Caspin ,:或者,正如Caspin所提议的,:

readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
objdump -TC /usr/lib/libexample.so

For shared libraries libNAME.so the -D switch was necessary to see symbols in my Linux对于共享库 libNAME.so 必须使用 -D 开关才能在我的 Linux 中查看符号

nm -D libNAME.so

and for static library as reported by others以及其他人报告的静态库

nm -g libNAME.a

I kept wondering why -fvisibility=hidden and #pragma GCC visibility did not seem to have any influence, as all the symbols were always visible with nm - until I found this post that pointed me to readelf and objdump , which made me realize that there seem to actually be two symbol tables:我一直想知道为什么-fvisibility=hidden#pragma GCC 可见性似乎没有任何影响,因为所有符号在nm 下始终可见 - 直到我发现这篇文章将我指向readelfobjdump ,这让我意识到那里似乎实际上是两个符号表:

  • The one you can list with nm您可以使用nm列出的那个
  • The one you can list with readelf and objdump您可以使用readelfobjdump列出的那个

I think the former contains debugging symbols that can be stripped with strip or the -s switch that you can give to the linker or the install command.我认为前者包含可以用strip或 -s 开关去除的调试符号,您可以将它们提供给链接器或安装命令。 And even if nm does not list anything anymore, your exported symbols are still exported because they are in the ELF "dynamic symbol table", which is the latter.即使 nm 不再列出任何内容,您导出的符号仍然会被导出,因为它们在 ELF“动态符号表”中,也就是后者。

For C++ .so files, the ultimate nm command is nm --demangle --dynamic --defined-only --extern-only <my.so>对于 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)

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

For Android .so files, the NDK toolchain comes with the required tools mentioned in the other answers: readelf , objdump and nm .对于 Android .so文件,NDK 工具链附带了其他答案中提到的所需工具: readelfobjdumpnm

You can use the nm -g tool from the binutils toolchain.您可以使用 binutils 工具链中的nm -g工具。 However, their source is not always readily available.然而,它们的来源并不总是容易获得。 and I'm not actually even sure that this information can always be retrieved.而且我什至不确定这些信息是否总能被检索到。 Perhaps objcopy reveals further information.也许objcopy揭示了更多信息。

/EDIT: The tool's name is of course nm . /编辑:该工具的名称当然是nm The flag -g is used to show only exported symbols.标志-g用于仅显示导出的符号。

Try adding -l to the nm flags in order to get the source of each symbol.尝试将 -l 添加到 nm 标志以获取每个符号的来源。 If the library is compiled with debugging info (gcc -g) this should be the source file and line number.如果库是用调试信息 (gcc -g) 编译的,这应该是源文件和行号。 As Konrad said, the object file / static library is probably unknown at this point.正如康拉德所说,目标文件/静态库此时可能是未知的。

nm -g list the extern variable, which is not necessary exported symbol. nm -g 列出extern 变量,它不是必需的导出符号。 Any non-static file scope variable(in C) are all extern variable.任何非静态文件范围变量(在 C 中)都是外部变量。

nm -D will list the symbol in the dynamic table, which you can find it's address by dlsym. nm -D 将列出动态表中的符号,您可以通过 dlsym 找到它的地址。

nm --version纳米--版本

GNU nm 2.17.50.0.6-12.el5 20061020 GNU 纳米 2.17.50.0.6-12.el5 20061020

If you just want to know if there are symbols present you can use如果您只想知道是否存在符号您可以使用

objdump -h /path/to/object

or to list the debug info或列出调试信息

objdump -g /path/to/object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM