nm vs"readelf -s"

cam*_*ino 35 linux readelf nm

假设我们有一个名为libtest.so的共享库,其中有一个函数"foo"

使用条带丢弃libtest.so中的所有符号

$strip libtest.so
Run Code Online (Sandbox Code Playgroud)

所以,现在如果我们使用:

$nm libtest.so
Run Code Online (Sandbox Code Playgroud)

它会打印出来:

nm:libtest.so:没有符号

但如果我们使用:

$readelf -s libtest.so 
Run Code Online (Sandbox Code Playgroud)

foo函数仍然可以从其结果中看出:

...

10:000005dc 5 FUNC GLOBAL DEFAULT 12 _Z3foov

...

我们也可以使用命令字符串来检查它:

$strings libtest.so
Run Code Online (Sandbox Code Playgroud)

...

_Z3foov

...

这是我的问题,为什么nm没有给条纹libtest.so带来任何结果?

谢谢

Emp*_*ian 59

为什么nm没有为条带化libtest.so提供结果

原始中有两个符号表libtest.so:"常规" 符号表(in .symtab.strtabsections)和动态符号表(in .dynsym.dynstrsections).

如果strip删除了两个符号表,那么您的库将完全无用:动态加载程序无法解析其中的任何符号.所以,strip做有意义的唯一的事:删除"常规"符号表,使动态的完整无缺.

您可以使用nm -D或在动态符号表中查看符号readelf -s.

"常规"符号表仅用于调试(例如,它包含静态函数的条目,这些条目不由库导出,并且不显示在动态符号表中).

但是动态加载器从不查看"常规"符号表(其格式不适合快速符号查找); 只有在动态的.因此正确的程序操作不需要"常规"符号表,但动态的是.

  • 你的用户名很棒。所以,基本上,如果我在编译时将静态库链接到二进制文件,库的符号将显示为 nm,但如果我进行动态链接,符号将显示在 readelf -S 和 nm -D 中,对吗? (2认同)