记一次 mangle & demangle 之旅
今晚阅读 objc 的源码时,看到一个很长很长的符号:
__ZN4objc8DenseMapIP11objc_objectmLb1ENS_12DenseMapInfoIS2_EENS3_ImEEE16FindAndConstructERKS2_
这是什么鬼???
反汇编了那么多的 APP,怎么从来没有见过这么变态的名字?
苹果的开发人员是有多么变态?
很快,我注意到这个符号里面有些数字。之前阅读 Swift 源码时,看到过类似的情况。在大脑的记忆中搜索了一遍,得出了一个关键字 demangle。
mangle 的中文含义是“破坏,撕裂”。Swift 在编译过程中,会破坏原来的格式,变为一种不利于人类阅读的格式。该过程即为“mangle”。
demangle 的中文含义是“解构,还原函数”。把不利于阅读的符号转为利于人类阅读的符号,即为“demangle”。
比如,在 Swift 中,SwiftClassExample.myClass
编译后的符号为 _TtC17SwiftClassExample7myClass
(根据 Swift 版本的不同,可能会有变化)。
下面,我们尝试用以下命令进行验证:
> xcrun swift-demangle --compact _TtC17SwiftClassExample7myClass
> SwiftClassExample.myClass
很明显,我们可以把 Swift 编译后的符号转为正常的可读格式。
回到之前的 objc 上面,__ZN4objc8DenseMapIP11objc_objectmLb1ENS_12DenseMapInfoIS2_EENS3_ImEEE16FindAndConstructERKS2_
是不是被 mangle
的符号呢?
尝试以“demangle 函数名” 为关键字进行搜索。搜索结果如下所示:
demangle 函数名通过查看第一个结果 如何识别C++编译以后的函数名(demangle) ,我们可以得出,这个符号是 c++ mangle
后的符号。
同时,文中提到linux下有一个工具可以帮助我们demangle
。
下面,我们尝试用c++filt
命令进行验证:
> c++filt __ZN4objc8DenseMapIP11objc_objectmLb1ENS_12DenseMapInfoIS2_EENS3_ImEEE16FindAndConstructERKS2_
> objc::DenseMap<objc_object*, unsigned long, true, objc::DenseMapInfo<objc_object*>, objc::DenseMapInfo<unsigned long> >::FindAndConstruct(objc_object* const&)
很明显,这个符号是 c++ 编译后的符号。
至此,本次探索之旅也到此结束。