为啥 extern-only 和 defined-only 选项的 nm 工具输出重叠?

Posted

技术标签:

【中文标题】为啥 extern-only 和 defined-only 选项的 nm 工具输出重叠?【英文标题】:Why does the nm tool output for the extern-only and defined-only options overlap?为什么 extern-only 和 defined-only 选项的 nm 工具输出重叠? 【发布时间】:2017-12-04 22:06:06 【问题描述】:

我将首先说明我对选项的理解:

    extern-only:只显示那些被二进制文件引用但其定义(代码或变量)将由另一个二进制文件提供的符号 defined-only:只显示那些定义包含在二进制文件中的符号。

这是我的命令及其输出:

$nm -defined-only GenerationOfNow | grep FIRAZeroingWeakContainer  
000000010002c128 t -[FIRAZeroingWeakContainer .cxx_destruct]  
000000010002c0fb t -[FIRAZeroingWeakContainer object]  
000000010002c114 t -[FIRAZeroingWeakContainer setObject:]  
000000010021a218 S _OBJC_CLASS_$_FIRAZeroingWeakContainer  
00000001002177f8 s _OBJC_IVAR_$_FIRAZeroingWeakContainer._object  
000000010021a1f0 S _OBJC_METACLASS_$_FIRAZeroingWeakContainer

$nm -extern-only GenerationOfNow | grep FIRAZeroingWeakContainer  
000000010021a218 S _OBJC_CLASS_$_FIRAZeroingWeakContainer  
000000010021a1f0 S _OBJC_METACLASS_$_FIRAZeroingWeakContainer

如您所见,-extern-only 输出是 -defined-only 输出的子集。为什么?也许我的问题应该是:那些在第二列中有 S 的项目是什么意思?

【问题讨论】:

【参考方案1】:

您将-extern-only-undefined-only 混淆了。

这里混合了两个概念:

外部与本地(在 C 中 externstatic,“本地”有时也称为“私有”) 已定义与未定义

前者描述了一个符号的可用性,而后者描述了它的起源。是的,根据man nm,甚至存在私有未定义符号的概念:

每个符号名称前面都有它的值(如果未定义,则为空白)。 [...] 动态共享库中的小写 u 表示对同一库中另一个模块中的私有外部的未定义引用。

现在,当使用-undefined-only 时,您实际上确实得到了-undefined-only 的补码

bash$ nm test.dylib 
0000000000000f60 T _derp
0000000000000f70 t _herp
                 U _printf
                 U dyld_stub_binder
bash$ nm -defined-only test.dylib 
0000000000000f60 T _derp
0000000000000f70 t _herp
bash$ nm -undefined-only test.dylib 
_printf
dyld_stub_binder
bash$ nm -extern-only test.dylib 
0000000000000f60 T _derp
                 U _printf
                 U dyld_stub_binder

-extern-only 但是似乎没有互补标志。

【讨论】:

以上是关于为啥 extern-only 和 defined-only 选项的 nm 工具输出重叠?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C 和 C++ 关键字“#defined”或“typedefed”也是它们的大写版本?

以错误的方式使用#define 来调用函数。为啥? [关闭]

为啥“#define WC(p) L#p”在 GCC 和 Clang 中不起作用?

为啥有人使用 define(['jquery'...], function($...)... [重复]

为啥我在 Laravel 中收到“Route [/login] not defined 错误”?

为啥会出现这个问题 encodeURL is not defined