Swift Name Mangling - Swift_0x01

From Brad.Cox to Chris.Lattner.

嘗試?yán)靡恍I(yè)余時(shí)間研究下 Swift,寫(xiě)一些由 OC 到 Swift 的變化。

背景

當(dāng)我使用 ClassDump 對(duì)一個(gè)項(xiàng)目操作的時(shí)候,輸出了一些看不懂的東西。(后來(lái)知道了這是一個(gè) OC Swift 混編的工程)

#import <UIKit/UIViewController.h>
@interface _TtC11MandrakeKit11LoadingView : UIViewController {
}
- (id)initWithCoder:(id)arg1;
- (id)initWithNibName:(id)arg1 bundle:(id)arg2;
- (void)viewDidLoad;
@end

通過(guò) Reveal 分析 UI,我大概知道這個(gè)類是 MandrakeKit.LoadingView,通過(guò)查看 MachO 發(fā)現(xiàn) __TEXT 段中有 __swift5_typeref,其中的數(shù)據(jù)跟這些很類似,所以這些就是Swift輸出的類名。

Swift 這樣進(jìn)行轉(zhuǎn)換的原因是為了防止不同的庫(kù)不會(huì)出現(xiàn)命名沖突。

OC & C

OC 的符號(hào)表中沒(méi)有這些復(fù)雜的符號(hào)重整,OC 使用 Selector + Type Encoding,并且OC 無(wú)重載。

C 語(yǔ)言有輕微的 Name Mangling,即會(huì)將 void main(){return 0;} 符號(hào)化為:_main,增加一個(gè)下劃線。

OC 舉一個(gè)栗子:Point類下的 + (id) initWithX: (int) number andY: (int) number;方法

+ (id) initWithX: (int) number andY: (int) number;
- (id) value;

_c_Point_initWithX_andY_
_i_Point_value

C++

對(duì)于如下方法,C++的NameMangling會(huì)翻譯成下面這樣:

    int foo(int a) { return a * 2; }
    int foo(double a) { return a * 2.0; }
    int main() { return foo(1) + foo(1.0); }

    0000000100000f30 T __Z3food
    0000000100000f10 T __Z3fooi
    0000000100000000 T __mh_execute_header
    0000000100000f60 T _main

C++編譯器遵循一套嚴(yán)格的 mangles 規(guī)則,參考這個(gè)鏈接Itanium C++ ABI documentation

int foo(double a) 為例,重整后的符號(hào)為 __Z3fooi

大致意思如下:

_ _Z 3 foo d

-   : 代表C風(fēng)格的符號(hào)
_Z  : 這個(gè)前綴標(biāo)記這個(gè)符號(hào)是一個(gè)mangled(重整)的全局C++名字
3   : 字符長(zhǎng)度,foo 這個(gè)名字,有3個(gè)字符
foo : 
d   : 代表`double`,如果是 `int` 的話就是`i`

Swift

Swift 的重整規(guī)則基于 C++,也有些不同,包含更多的信息和概念。

栗子:

xcrun swiftc -emit-library -o test -
public class myClass{
    public func calculate(x: Int) -> Int {
        return 0;
    }
}

nm -g test
0000000000002bb0 T _$s4test7myClassC9calculate1xS2i_tF
_$s4test7myClassC9calculate1xS2i_tF

_  // 通用起始
 $s // '$s' global  // Swift 穩(wěn)定mangling版本
  4test // 字符長(zhǎng)度,模塊名
  7myClass // 方法歸屬的類名
  C // 從屬關(guān)系,myClass 是 test 模塊中的 Class
    9calculate // 字符 calculate
     1x // 參數(shù)類型
     S2i // 堆棧中放入兩個(gè) Swift.Int
     _
       tF // 從屬關(guān)系,calculate 是 test.myClass 的 Function ???

這里解釋一下S2i,這個(gè)是從后往前取的,參數(shù)往里放是棧結(jié)構(gòu),先進(jìn)后出,第一個(gè)進(jìn)棧的是參數(shù) `x:Int`  第二個(gè)是返回的參數(shù) Int,所以S2i兩個(gè)`Swift.Int`。
如果入?yún)⑹?`x:String`,反參是 Int,那就變成是 `SSSi` 了。

/* 此段過(guò)期,是以前的老版本
_TFC4test7MyClass9calculatefS0_FT1xSi_Si

_T // Swift通用起始標(biāo)記
  F // Non-curried function
    C // Function of a class. (method)
      4test // 字符長(zhǎng)度,模塊名
        7MyClass // 方法歸屬的類名
          9calculate // 函數(shù)名
            f // 非柯里化函數(shù)(Uncurried Function)
              S0 // 指定 類實(shí)例 為類型堆棧的第一個(gè)參數(shù)
                _FT // 參數(shù)開(kāi)始
                  1x // 第一個(gè)參數(shù)參數(shù)名
                    Si // Swift 內(nèi)置類型 Swift.Int
                _Si // 返回類型,同上 Swift.Int
*/

// 結(jié)果:
test.MyClass.calculate(test.MyClass) -> (x: Swift.Int) -> Swift.Int

栗子2:

 didi ~  xcrun swiftc -emit-library -o test -
public func ?? (lhs: Int, rhs: Int) -> Int {
    return 0;
}

 didi ~  nm -g test
0000000000002d60 T _$s4test004GrIh3lhs3rhsS2i_SitF

_  // 通用起始
  $s // '$s' global  // Swift 穩(wěn)定mangling版本
    4test // 符號(hào) 4是長(zhǎng)度
      004GrIh // 00 特殊字符 GrIh 就是 emoji U+1F49B
        3lhs // 參數(shù) 3是字符串長(zhǎng)度
        3rhs // 參數(shù) 3是字符串長(zhǎng)度
         S2i // 解釋參數(shù)的類型,兩個(gè)Swift.Int
         _ // end??? 待填坑
          Si // Swift.Int
           tF // 從屬關(guān)系,?? 是 test 的 Function ???

//結(jié)果:
test.??(Swift.Int, Swift.Int) -> Swift.Int

以上

對(duì)大多數(shù)人來(lái)說(shuō),不是很多。從算法的意義上講,讀取變形的名稱是相當(dāng)簡(jiǎn)單的,但是對(duì)于人眼來(lái)說(shuō)則是不必要的困難。
這就是為什么存在拆解工具的原因。

補(bǔ)充

關(guān)于curried & uncurried function:
上面案例中的方法d是一個(gè)uncurried function,因?yàn)閰?shù)是一個(gè)一個(gè)傳遞進(jìn)去的,并不是當(dāng)做一個(gè)多元元組傳遞進(jìn)去的。(可能理解有誤。。)
這個(gè)概念是跟函數(shù)式編程相關(guān)的,暫未深入了解,挖個(gè)坑,稍后填坑。
ref:stackOverFlow:How is this exactly a curried function?


參考鏈接:

其他:
OS X ABI Mach-O File Format Reference

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容