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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:22:24  来源:igfitidea点击:

How do I list the symbols in a .so file

c++cgccsymbolsname-mangling

提问by Moe

How do I list the symbols being exported from a .so file? If possible, I'd also like to know their source (e.g. if they are pulled in from a static library).

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

I'm using gcc 4.0.2, if that makes a difference.

我正在使用 gcc 4.0.2,如果这有区别的话。

回答by Steve Gury

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(-Cis 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

回答by P Shved

If your .sofile is in elf format, you can use readelf program to extract symbol information from the binary. This command will give you the symbol table:

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

readelf -Ws /usr/lib/libexample.so

You only should extract those that are defined in this .sofile, not in the libraries referenced by it. Seventh column should contain a number in this case. You can extract it by using a simple regex:

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

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 }';

回答by Pavel Lapin

objdump -TC /usr/lib/libexample.so

回答by cavila

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

回答by Peter Remmers

I kept wondering why -fvisibility=hiddenand #pragma GCC visibilitydid not seem to have any influence, as all the symbols were always visible with nm- until I found this post that pointed me to readelfand objdump, which made me realize that there seem to actually be twosymbol tables:

我一直想知道为什么-fvisibility=hidden#pragma GCC 可见性似乎没有任何影响,因为所有符号总是用nm可见- 直到我发现这篇文章将我指向readelfobjdump,这让我意识到有似乎实际上是两个符号表:

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

I think the former contains debugging symbols that can be stripped with stripor the -s switch that you can give to the linker or the installcommand. 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.

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

回答by user7610

For C++ .sofiles, the ultimate nmcommand 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

回答by Adi Shavit

For Android .sofiles, the NDK toolchain comes with the required tools mentioned in the other answers: readelf, objdumpand nm.

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

回答by Adam Mitz

Try adding -l to the nm flags in order to get the source of each symbol. If the library is compiled with debugging info (gcc -g) this should be the source file and line number. As Konrad said, the object file / static library is probably unknown at this point.

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

回答by Konrad Rudolph

You can use the nm -gtool from the binutils toolchain. However, their source is not always readily available. and I'm not actually even sure that this information can always be retrieved. Perhaps objcopyreveals further information.

您可以使用nm -gbinutils 工具链中的工具。然而,它们的来源并不总是容易获得。我什至不确定这些信息是否总是可以被检索到。或许能objcopy透露更多信息。

/EDIT: The tool's name is of course nm. The flag -gis used to show only exported symbols.

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

回答by zhaorufei

nm -g list the extern variable, which is not necessary exported symbol. Any non-static file scope variable(in C) are all extern variable.

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

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 nm 2.17.50.0.6-12.el5 20061020