美文网首页
Swift Name Mangling - Swift_0x01

Swift Name Mangling - Swift_0x01

作者: 扬仔360 | 来源:发表于2021-03-10 23:22 被阅读0次

    From Brad.Cox to Chris.Lattner.

    尝试利用一些业余时间研究下 Swift,写一些由 OC 到 Swift 的变化。

    背景

    当我使用 ClassDump 对一个项目操作的时候,输出了一些看不懂的东西。(后来知道了这是一个 OC Swift 混编的工程)

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

    通过 Reveal 分析 UI,我大概知道这个类是 MandrakeKit.LoadingView,通过查看 MachO 发现 __TEXT 段中有 __swift5_typeref,其中的数据跟这些很类似,所以这些就是Swift输出的类名。

    Swift 这样进行转换的原因是为了防止不同的库不会出现命名冲突

    OC & C

    OC 的符号表中没有这些复杂的符号重整,OC 使用 Selector + Type Encoding,并且OC 无重载。

    C 语言有轻微的 Name Mangling,即会将 void main(){return 0;} 符号化为:_main,增加一个下划线。

    OC 举一个栗子: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++

    对于如下方法,C++的NameMangling会翻译成下面这样:

        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++编译器遵循一套严格的 mangles 规则,参考这个链接Itanium C++ ABI documentation

    int foo(double a) 为例,重整后的符号为 __Z3fooi

    大致意思如下:

    _ _Z 3 foo d
    
    -   : 代表C风格的符号
    _Z  : 这个前缀标记这个符号是一个mangled(重整)的全局C++名字
    3   : 字符长度,foo 这个名字,有3个字符
    foo : 
    d   : 代表`double`,如果是 `int` 的话就是`i`
    

    Swift

    Swift 的重整规则基于 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 稳定mangling版本
      4test // 字符长度,模块名
      7myClass // 方法归属的类名
      C // 从属关系,myClass 是 test 模块中的 Class
        9calculate // 字符 calculate
         1x // 参数类型
         S2i // 堆栈中放入两个 Swift.Int
         _
           tF // 从属关系,calculate 是 test.myClass 的 Function ???
    
    这里解释一下S2i,这个是从后往前取的,参数往里放是栈结构,先进后出,第一个进栈的是参数 `x:Int`  第二个是返回的参数 Int,所以S2i两个`Swift.Int`。
    如果入参是 `x:String`,反参是 Int,那就变成是 `SSSi` 了。
    
    /* 此段过期,是以前的老版本
    _TFC4test7MyClass9calculatefS0_FT1xSi_Si
    
    _T // Swift通用起始标记
      F // Non-curried function
        C // Function of a class. (method)
          4test // 字符长度,模块名
            7MyClass // 方法归属的类名
              9calculate // 函数名
                f // 非柯里化函数(Uncurried Function)
                  S0 // 指定 类实例 为类型堆栈的第一个参数
                    _FT // 参数开始
                      1x // 第一个参数参数名
                        Si // Swift 内置类型 Swift.Int
                    _Si // 返回类型,同上 Swift.Int
    */
    
    // 结果:
    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 稳定mangling版本
        4test // 符号 4是长度
          004GrIh // 00 特殊字符 GrIh 就是 emoji U+1F49B
            3lhs // 参数 3是字符串长度
            3rhs // 参数 3是字符串长度
             S2i // 解释参数的类型,两个Swift.Int
             _ // end??? 待填坑
              Si // Swift.Int
               tF // 从属关系,💛 是 test 的 Function ???
    
    //结果:
    test.💛(Swift.Int, Swift.Int) -> Swift.Int
    

    以上

    对大多数人来说,不是很多。从算法的意义上讲,读取变形的名称是相当简单的,但是对于人眼来说则是不必要的困难。
    这就是为什么存在拆解工具的原因。

    补充

    关于curried & uncurried function:
    上面案例中的方法d是一个uncurried function,因为参数是一个一个传递进去的,并不是当做一个多元元组传递进去的。(可能理解有误。。)
    这个概念是跟函数式编程相关的,暂未深入了解,挖个坑,稍后填坑。
    ref:stackOverFlow:How is this exactly a curried function?


    参考链接:

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

    相关文章

      网友评论

          本文标题:Swift Name Mangling - Swift_0x01

          本文链接:https://www.haomeiwen.com/subject/lwngqltx.html