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

Why does the nm tool output for the extern-only and defined-only options overlap?

我将从给出我对选项的理解开始:

  1. extern-only:只显示那些被二进制文件引用但其定义(代码或变量)将由另一个二进制文件提供的符号
  2. 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的项目是什么意思?

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

这里混杂了两个概念:

  • extern vs. local(在 C 中 extern vs. static,"local" 有时也称为 "private")
  • 已定义与未定义

前者描述符号的可用性,而后者描述其来源。是的,根据 man nm:

,甚至存在私有未定义符号的概念

Each symbol name is preceded by its value (blanks if undefined). [...] A lower case u in a dynamic shared library indicates a undefined reference to a private external in another module in the same library.

现在,当使用 -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 不过貌似没有补充标志。