何时在nm中使用--dynamic选项

时间:2013-03-11 18:10:07

标签: linux

有时当我在.so文件上执行nm(例如,libstdc ++。so.6)时,它没有说明符号,我需要使用nm --dynamic。但对于其他一些.so文件,我可以看到没有--dynamic的符号。

医生说:

显示动态符号而不是普通符号。这仅对动态对象有意义,例如某些类型的共享库。

但令人困惑的是......共享库的“类型”需要什么 - 动态?这是如何确定的?在编译图书馆期间?我认为所有共享库都是动态的(我的意思是,可以在运行时动态加载),但似乎我的理解不太正确。

2 个答案:

答案 0 :(得分:13)

如果您的符号未从共享库导出,很可能最终会导致normal symbol table而不是dynamic symbol table

ELF文件中有许多类型的符号。

  • 符号是Normal Symbol table的一部分。这是nm libabc.soobjdump --syms libabc.so的输出。这些符号仅在静态链接期间使用。

  • 符号是Dynamic Symbol table的一部分。这是nm --dynamic libabc.soobjdump --dynamic-syms libabc.so的输出。动态符号表是运行时链接器/加载器使用的表,它绑定引用它们的ELF文件和定义它们的ELF文件之间的符号。它也被static linker使用,同时将共享库与需要它的应用程序链接起来。这是有助于在链接期间显示所有undefined symbol errors的组件。

  • Hidden symbols - 这些是使用_attribute_ ((visibility("hidden")))标记的符号。这些符号不会导出到外部,只能在库中使用。在链接步骤期间检查可见性,因此仅对共享库强制执行。默认可见性为public,即除非另有说明,否则将导出符号。可以使用-fvisibility=default|internal|hidden|protected修改行为。

  

将默认的ELF图像符号可见性设置为指定的   option-all符号将被标记为this,除非在其中被覆盖   代码。使用此功能可以非常显着地改善链接   和共享对象库的加载时间,产生更多优化   代码,提供近乎完美的API导出并防止符号冲突。它   强烈建议您在任何共享对象中使用它   分发。尽管有命名法,但默认总是意味着公共,即;   可以从共享对象外部链接。   受保护和内部在实际使用中相当无用,所以   只会隐藏其他常用选项。默认为   -fvisibility未指定为默认值,即将每个符号设为公共 - 这会导致与以前版本的GCC相同的行为。

     

这些技术的概述,它们的好处以及如何使用它们   在http://gcc.gnu.org/wiki/Visibility

要回答您的问题,您何时会使用--dynamic的{​​{1}}选项,那么您希望列出共享库导出的所有符号,以及唯一可用的符号。参考它们的ELF图像。

答案 1 :(得分:0)

如果共享库被剥离,则需要在共享库中使用--dynamic-D选项,因此只包含动态符号表。

您可能希望将此选项用于其他共享库以显式显示动态符号表,因为这是动态链接器参考的表。

file实用程序指示是否剥离共享库。例如:

$ file /usr/lib64/libcrypt-nss-2.26.so
[..] ELF 64-bit LSB shared object, x86-64 [..], not stripped
$ file /usr/lib64/libxml2.so.2.9.7
[..] ELF 64-bit LSB shared object, x86-64 [..], stripped

不同符号表如何包含不同符号的示例:

$ nm -D /usr/lib64/libcrypt-nss-2.26.so | wc -l
39
$ nm /usr/lib64/libcrypt-nss-2.26.so | wc -l 
112