记一次 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++ 编译后的符号。

至此,本次探索之旅也到此结束。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 10,239评论 4 57
  • 七八春秋,谁不念,芦沟晓月?中原地,刀光剑影,铁蹄猖獗。永定河畔烟与火,金陵城内尸和血。忆当初,多少好男儿,冲冠发...
    北方北葵阅读 172评论 0 3
  • 文 / 西门君 图 / 网络 1. 标题里的这句话,是一个叫做小蔓的女孩亲口对我说的。 她是一个活力四射的女孩子,...
    西门君不吐槽阅读 545评论 0 0