deadcode strip

优质
小牛编辑
132浏览
2023-12-01

deadcode strip

  • 死代码剥离, clang在链接过程中deadcode strip默认就是生效的

  • dead_strip

      -dead_strip
    
      Remove functions and data that are unreachable by the entry point or exported symbols.
    
  • 区分于Other Linker Flags (OTHER_LDFLAGS), Other Linker Flags (OTHER_LDFLAGS)是仅限于静态库的


dead_strip与其他链接参数对比

  • 准备test.m文件

    • 定义了全局函数: global_function() 从符号角度讲是导出符号
    • 定义了静态函数: static_function() 从符号角度讲是本地符号
    • 没有使用global_function()全局函数

      #import <Foundation/Foundation.h>
      
      // 全局符号 导出符号
      void global_function() {
      
      }
      
      // 本地符号
      static void static_function() {
      
      }
      int main() {
          // global_function();
          NSLog(@"testApp ------");
          return 0;
      }
      
  • 脚本生成可执行文件, 并查看__TEXT, 对比-dead_strip作用

    • 加上-dead_strip

      SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk
      
      # 链接OCTest到test.m中生成.o文件
      clang -x objective-c \
      -target x86_64-apple-macos11.1 \
      -fobjc-arc \
      -isysroot $SYSROOT \
      -I./OCStaticLib \
      -c test.m \
      -o test.o
      
      # 将.o生成执行文件
      clang -target x86_64-apple-macos11.1 \
      -fobjc-arc \
      -isysroot $SYSROOT \
      -Xlinker -dead_strip \
      -L./OCStaticLib \
      -lOCTest \
      test.o -o test
      
      test:
      (__TEXT,__text) section
      _main:
      100003f50:    55    pushq    %rbp
      100003f51:    48 89 e5    movq    %rsp, %rbp
      100003f54:    48 83 ec 10    subq    $16, %rsp
      100003f58:    48 8d 05 a9 00 00 00    leaq    169(%rip), %rax ## Objc cfstring ref: @"testApp ------"
      100003f5f:    c7 45 fc 00 00 00 00    movl    $0, -4(%rbp)
      100003f66:    48 89 c7    movq    %rax, %rdi
      100003f69:    b0 00    movb    $0, %al
      100003f6b:    e8 08 00 00 00    callq    0x100003f78 ## symbol stub for: _NSLog
      100003f70:    31 c0    xorl    %eax, %eax
      100003f72:    48 83 c4 10    addq    $16, %rsp
      100003f76:    5d    popq    %rbp
      100003f77:    c3    retq
      
    • 不加-dead_strip

      SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk
      
      # 链接OCTest到test.m中生成.o文件
      clang -x objective-c \
      -target x86_64-apple-macos11.1 \
      -fobjc-arc \
      -isysroot $SYSROOT \
      -I./OCStaticLib \
      -c test.m \
      -o test.o
      
      # 将.o生成执行文件
      clang -target x86_64-apple-macos11.1 \
      -fobjc-arc \
      -isysroot $SYSROOT \
      -L./OCStaticLib \
      -lOCTest \
      test.o -o test
      
      test:
      (__TEXT,__text) section
      _global_function:
      100003f40:    55    pushq    %rbp
      100003f41:    48 89 e5    movq    %rsp, %rbp
      100003f44:    5d    popq    %rbp
      100003f45:    c3    retq
      100003f46:    66 2e 0f 1f 84 00 00 00 00 00    nopw    %cs:(%rax,%rax)
      _main:
      100003f50:    55    pushq    %rbp
      100003f51:    48 89 e5    movq    %rsp, %rbp
      100003f54:    48 83 ec 10    subq    $16, %rsp
      100003f58:    48 8d 05 a9 00 00 00    leaq    169(%rip), %rax ## Objc cfstring ref: @"testApp ------"
      100003f5f:    c7 45 fc 00 00 00 00    movl    $0, -4(%rbp)
      100003f66:    48 89 c7    movq    %rax, %rdi
      100003f69:    b0 00    movb    $0, %al
      100003f6b:    e8 08 00 00 00    callq    0x100003f78 ## symbol stub for: _NSLog
      100003f70:    31 c0    xorl    %eax, %eax
      100003f72:    48 83 c4 10    addq    $16, %rsp
      100003f76:    5d    popq    %rbp
      100003f77:    c3    retq
      

在没有使用global_function()全局函数情况下, 增加了-dead_strip参数后, 被优化掉了

  • 满足两个条件

    1. 没有被入口点使用
    2. 没有被导出符号使用

OC中的-dead_strip

  1. 准备代码

     #import <Foundation/Foundation.h>
     #import "OCTest.h"
    
     int main() {
         OCTest *oc = [OCTest new];
         [oc test:nil];
         NSLog(@"testApp ------");
         return 0;
     }
    
  2. 脚本

     SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk
    
     # 链接OCTest到test.m中生成.o文件
     clang -x objective-c \
     -target x86_64-apple-macos11.1 \
     -fobjc-arc \
     -isysroot $SYSROOT \
     -I./OCStaticLib \
     -c test.m \
     -o test.o
    
     # 将.o生成执行文件
     clang -target x86_64-apple-macos11.1 \
     -fobjc-arc \
     -isysroot $SYSROOT \
     -Xlinker -dead_strip \
     -Xlinker -all_load \
     -L./OCStaticLib \
     -lOCTest \
     test.o -o test
    

    在连接过程中默认参数noall_load, 避免Other Linker Flags将代码剥离掉, 所以设置为all_load, 来观察dead_strip的作用效果

  3. 查看__TEXT

     test:
     (__TEXT,__text) section
     -[OCTest test:]:
     100003470:    55    pushq    %rbp
     100003471:    48 89 e5    movq    %rsp, %rbp
     100003474:    48 83 ec 20    subq    $32, %rsp
     100003478:    48 89 7d f8    movq    %rdi, -8(%rbp)
     10000347c:    48 89 75 f0    movq    %rsi, -16(%rbp)
     100003480:    48 c7 45 e8 00 00 00 00    movq    $0, -24(%rbp)
     100003488:    48 8d 7d e8    leaq    -24(%rbp), %rdi
     10000348c:    48 89 d6    movq    %rdx, %rsi
     10000348f:    e8 28 09 00 00    callq    0x100003dbc ## symbol stub for: _objc_storeStrong
     100003494:    48 8d 05 75 0b 00 00    leaq    2933(%rip), %rax ## Objc cfstring ref: @"__TestExample"
     10000349b:    48 89 c7    movq    %rax, %rdi
     10000349e:    b0 00    movb    $0, %al
     1000034a0:    e8 0b 09 00 00    callq    0x100003db0 ## symbol stub for: _NSLog
     1000034a5:    31 c9    xorl    %ecx, %ecx
     1000034a7:    89 ce    movl    %ecx, %esi
     1000034a9:    48 8d 7d e8    leaq    -24(%rbp), %rdi
     1000034ad:    e8 0a 09 00 00    callq    0x100003dbc ## symbol stub for: _objc_storeStrong
     1000034b2:    48 83 c4 20    addq    $32, %rsp
     1000034b6:    5d    popq    %rbp
     ...
     省略
    

    OC中即便没有使用, 静态库中的符号也不会被剥离掉, 因为OC是动态语言