LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

一 、概念介绍:LLVM和OLLVM

  • LLVM是一个完整的编译器架构,其中前端编译器使用了clang。
    LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

    代码经过LLVM的编译过程:

    LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响
    其中,解释一下IR(也成为BitCode码),LLVM编译器在传统的三层模型中加入了中介码,前端完成源码解析编译后,转成中介码,LLVM编译器针对中介码进行优化和改良,然后将中介码送入目标平台编译器生成目标代码,整个编译过程中都是中介码在参与,所以说跟目标语言和平台无关,但是与架构相关。

  • OLLVM(Obfuscator-llvm)
    在原有的LLVM上添加PASS,添加了bla/sub/bcf/fla等pass,这些pass对IR(Bitcode)进行处理,如指令替换(sub),控制流平展(fla),控制流伪造(bcf)等。
    LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响
    这点从OLLVM的源码中也能体现出来:

    // Flags for obfuscation
    static cl::opt<bool> Flattening("fla", cl::init(false),
                                    cl::desc("Enable the flattening pass"));
    
    static cl::opt<bool> BogusControlFlow("bcf", cl::init(false),
                                          cl::desc("Enable bogus control flow"));
    
    static cl::opt<bool> Substitution("sub", cl::init(false),
                                      cl::desc("Enable instruction substitutions"));
    
    static cl::opt<std::string> AesSeed("aesSeed", cl::init(""),
                                        cl::desc("seed for the AES-CTR PRNG"));
    
    static cl::opt<bool> Split("split", cl::init(false),
                               cl::desc("Enable basic block splitting"));
    
     MPM.add(createSplitBasicBlock(Split));
     MPM.add(createBogus(BogusControlFlow));
     MPM.add(createFlattening(Flattening));
    

注:即使不用ollvm,LLVM本身也是有很多pass的,具体的类型主要有以下几种

  • ImmutablePass
  • MoudlePass
  • CallGraphSCCPass
  • FuncationPass
  • LoopPass
  • RegionPass
  • BasicBlockPass
  • MachineFunctionPass

二、官方LLVM和其Clang

1.安装

官方下载llvm,下载源码包,官方把llvm和clang分开,需要把llvm和clang源码包都下载下来。

解压,改clang的包名,移动至llvm的tools下。
在llvm同级目录新建build目录,cd build

cmake -G "Unix Makefiles" --enable-optimized -DCMAKE_BUILD_TYPE=Release ../llvm-5.0.2.src

2.使用clang编译.c文件

源代码:

#include<stdio.h>
int main() {
        int a  = 4,b = 5;
        printf("a+b=%d",a+b);
        printf("hello world\n");
        return 0;
}
  • 用clang将源文件编译为LLVM IR的二进制文件(Bitcode)

    1. 编译不添加-fembed-bitcode参数,即clang -emit-llvm -c test.c -o test.bc
      然而.bc文件不易读取其内容,命令 llvm-dis test.bc可以将bc转化为.ll变为可读的IR文件
      执行cat test.ll,输出如下:
    ; ModuleID = 'test.bc'
    source_filename = "test.c"
    target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
    target triple = "x86_64-unknown-linux-gnu"
    
    @.str = private unnamed_addr constant [7 x i8] c"a+b=%d\00", align 1
    @.str.1 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
    
    ; Function Attrs: noinline nounwind optnone uwtable
    define i32 @main() #0 {
      %1 = alloca i32, align 4
      %2 = alloca i32, align 4
      %3 = alloca i32, align 4
      store i32 0, i32* %1, align 4
      store i32 4, i32* %2, align 4
      store i32 5, i32* %3, align 4
      %4 = load i32, i32* %2, align 4
      %5 = load i32, i32* %3, align 4
      %6 = add nsw i32 %4, %5
      %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %6)
      %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0))
      ret i32 0
    }
    
    declare i32 @printf(i8*, ...) #1
    
    attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
    
    !llvm.module.flags = !{!0}
    !llvm.ident = !{!1}
    
    !0 = !{i32 1, !"wchar_size", i32 4}
    !1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"}
    
    1. 添加-fembed-bitcode参数,即clang -emit-llvm -fembed-bitcode -c test.c -o test_bitcode.bc,产生的bc文件经过llvm-dis文件处理,cat查看,输出如下:
    ; ModuleID = 'test_bitcode.bc'
    source_filename = "test.c"
    target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
    target triple = "x86_64-unknown-linux-gnu"
    
    @.str = private unnamed_addr constant [7 x i8] c"a+b=%d\00", align 1
    @.str.1 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
    @llvm.embedded.module = private constant [2756 x i8] c"BC\C0\DE5\14\00\00\05\00\00\00b\0C0$IY\BEf\EE\D3\BE-D\012\05\00\00\00\00!                                                                                 \0C\00\00_\02\00\00\0B\02!\00\02\00\00\00\13\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0B                                                                                 B\84\102\148\08\18K\0A2B\88H\90\14 CF\88\A5\00\192B\E4H\0E\90\11\22\C4PAQ\81\8C\E1\83\E5\8A\04!F\06Q\18\00\00(\01\00\00\1B\D8&\F                                                                                 8\FF\FF\FF\FF\01p\00\09(\03 \0C\88qx\07y\90\87r\18\07z`\87|h\03yx\87zp\07r(\07rh\03rH\07{H\07r(\876\98\87x\90\07zh\03s\80\876h\8                                                                                 7p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \C8!\1D\E6!\1C\C4\81\1D\CA\A1\0D\E8!\1C\D2\81\1D\DA`\1C\C2\81\1D\D8a\1E\00s\08\07v\98\87r\00\08                                                                                 v(\87y\98\876\80\07y(\87qH\87y(\8760\07xh\87p \07\C0\1C\C2\81\1D\E6\A1\1C\00\C2\1D\DE\A1\0D\CCA\1E\C2\A1\1D\CA\A1\0D\E0\E1\1D\D2                                                                                 \C1\1D\E8\A1\1C\E4\A1\0D\CA\81\1D\D2\A1\1D\00z\90\87z(\07`p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\876p\87wp\876`\8                                                                                 7r\08\07s\00\08wx\876H\07w0\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA@\1D\EA\A1\1D\E0\A1\0D\E8!\1C\C4\81\1                                                                                 D\CAa\1E\00s\08\07v\98\87r\00\08wx\876p\87pp\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA`\1E\D2\E1\1C\DC\A1\                                                                                 1C\C8\A1\0D\F4\A1\1C\E4\E1\1D\E6\A1\0D\CC\01\1E\DA\A0\1D\C2\81\1E\D0\010\87p`\87y(\07\80p\87wh\03z\90\87p\80\07xH\07w8\876h\87p\                                                                                 A0\07t\00\CC!\1C\D8a\1E\CA\01 \E6\81\1E\C2a\1C\D6\A1\0D\E0A\1E\DE\81\1E\CAa\1C\E8\E1\1D\E4\A1\0D\C4\A1\1E\CC\C1\1C\CAA\1E\DA`\1E                                                                                 \D2A\1F\CA\01\C0\03\80\A0\87p\90\87s(\07zh\83q\80\87z\00\F0\01\0F\EC\A0\0D\EC\80\0E\00\82\1E\C2A\1E\CE\A1\1C\E8\A1\0D\CC\A1\1C\C                                                                                 2\81\1E\EAA\1E\CAa\1E\8050\07|\98\07y`\835h\87v\C0\076X\83y\98\87r`\835\98\87y(\079`\835\C0\07<\B8\03\80\A8\07w\98\87p0\87rh\03s                                                                                 \80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \EAa\1E\CA\A1\0D\E6\E1\1D\CC\81\1E\DA\C0\1C\D8\E1\1D\C2\81\1E\00s\08\07v\98\87r\006\B                                                                                 8\8C\F0\FF\FF\FF\FF\031\0E\EF \0F\F2P\0E\E3@\0F\EC\90\0Fm \0F\EFP\0F\EE@\0E\E5@\0Em@\0E\E9`\0F\E9@\0E\E5\D0\06\F3\10\0F\F2@\0Fm`                                                                                 \0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\049\A4\C3<\84\838\B0C9\B4\01=\84C:\B0C\1B\8CC8\B0\03;\CC\03`\0E\E1\C0\0E\F3P\0                                                                                 E\00\C1\0E\E50\0F\F3\D0\06\F0 \0F\E50\0E\E90\0F\E5\D0\06\E6\00\0F\ED\10\0E\E4\00\98C8\B0\C3<\94\03@\B8\C3;\B4\819\C8C8\B4C9\B4\0                                                                                 1<\BCC:\B8\03=\94\83<\B4A9\B0C:\B4\03@\0F\F2P\0F\E5\00\0C\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90                                                                                 \0E\ED\D0\06\EE\F0\0E\EE\D0\06\ECP\0E\E1`\0E\00\E1\0E\EF\D0\06\E9\E0\0E\E60\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\0                                                                                 0\84;\BCC\1B\B8C8\B8\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em0\0F\E9p\0E\EEP\0E\E4\D0\06\FAP\0E\F2\F0                                                                                 \0E\F3\D0\06\E6\00\0Fm\D0\0E\E1@\0F\E8\00\98C8\B0\C3<\94\03@\B8\C3;\B4\01=\C8C8\C0\03<\A4\83;\9CC\1B\B4C8\D0\03:\00\E6\10\0E\EC0                                                                                 \0F\E5\00\10\F3@\0F\E10\0E\EB\D0\06\F0 \0F\EF@\0F\E50\0E\F4\F0\0E\F2\D0\06\E2P\0F\E6`\0E\E5 \0Fm0\0F\E9\A0\0F\E5\00\E0\01@\D0C8\                                                                                 C8\C39\94\03=\B4\C18\C0C=\00\F8\80\07v\D0\06v@\07\00A\0F\E1 \0F\E7P\0E\F4\D0\06\E6P\0E\E1@\0F\F5 \0F\E50\0F\C0\1A\98\03>\CC\83<\                                                                                 B0\C1\1A\B4C;\E0\03\1B\AC\C1<\CCC9\B0\C1\1A\CC\C3<\94\83\1C\B0\C1\1A\E0\03\1E\DC\01@\D4\83;\CCC8\98C9\B4\819\C0C\1B\B4C8\D0\03:\                                                                                 00\E6\10\0E\EC0\0F\E5\00\10\F50\0F\E5\D0\06\F3\F0\0E\E6@\0Fm`\0E\EC\F0\0E\E1@\0F\809\84\03;\CCC9\00\00\00I\18\00\00\02\00\00\00\                                                                                 13\82`B \00\00\00\89 \00\00\0E\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\108s\04H\1E\00                                                                                 E6\00\CD\1C\01\18\94\A0\C8\08\AAPH9\10@5\02\00\00\130|\C0\03;\F8\05;\A0\836\A8\07wX\07wx\87{p\876`\87tp\87z\C0\8768\07w\A8\87\0D                                                                                 eP\0Em\D0\0EzP\0Em\90\0Ev@\07z`\07t\D0\06\E6\80\07p\A0\07q \07x\D0\06\EE\80\07z\10\07v\A0\07s \07z`\07t\D0\06\B3\10\07r\80\07J\0                                                                                 F\08\11\12A\86\8C\14\09\014B\18\D6\98\08i\F2\85\1D\0F@\04C\91\04\00\00\04\00\00\00;\1E\C2\18\06#\09\00\00\08\00\00\00\86D\0Aa\00                                                                                 \00\10\00\00\00\00\00\00\00\C0\90\C81\12 \00\04\00\00\00\00\00\00\00\90\D8 PxL\00\00 \0B\04\00\00\0A\00\00\002\1E\98\10\19\11L\9                                                                                 0\8C\09&G\C6\04C\0A5\C2+q\AFD\A6Q\06]f\B3\DF\A0\FB[\CE&+\A8J\A0\10\00\B1\18\00\00m\00\00\003\08\80\1C\C4\E1\1Cf\14\01=\88C8\84\C                                                                                 3\8CB\80\07yx\07s\98q\0C\E6\00\0F\ED\10\0E\F4\80\0E3\0CB\1E\C2\C1\1D\CE\A1\1Cf0\05=\88C8\84\83\1B\CC\03=\C8C=\8C\03=\CCx\8Ctp\07                                                                                 {\08\07yH\87pp\07zp\03vx\87p \87\19\CC\11\0E\EC\90\0E\E10\0Fn0\0F\E3\F0\0E\F0P\0E3\10\C4\1D\DE!\1C\D8!\1D\C2a\1Ef0\89;\BC\83;\D0                                                                                 C9\B4\03<\BC\83<\84\03;\CC\F0\14v`\07{h\077h\87rh\077\80\87p\90\87p`\07v(\07v\F8\05vx\87w\80\87_\08\87q\18\87r\98\87y\98\81,\EE\                                                                                 F0\0E\EE\E0\0E\F5\C0\0E\EC0\03b\C8\A1\1C\E4\A1\1C\CC\A1\1C\E4\A1\1C\DCa\1C\CA!\1C\C4\81\1D\CAa\06\D6\90C9\C8C9\98C9\C8C9\B8\C38\                                                                                 94C8\88\03;\94\C3/\BC\83<\FC\82;\D4\03;\B0\C3\0C\C7i\87pX\87rp\83th\07x`\87t\18\87t\A0\87\19\CES\0F\EE\00\0F\F2P\0E\E4\90\0E\E3@                                                                                 \0F\E1 \0E\ECP\0E3 (\1D\DC\C1\1E\C2A\1E\D2!\1C\DC\81\1E\DC\E0\1C\E4\E1\1D\EA\01\1Ef\18Q8\B0C:\9C\83;\CCP$v`\07{h\077`\87wx\07x\9                                                                                 8QL\F4\90\0F\F0P\0E3\1Ej\1E\CAa\1C\E8!\1D\DE\C1\1D~\01\1E\E4\A1\1C\CC!\1D\F0a\06T\85\838\CC\C3;\B0C=\D0C9\FC\C2<\E4C;\88\C3;\B0\                                                                                 C3\8C\C5\0A\87y\98\87w\18\87t\08\07z(\07r\00\00\00\00y \00\00&\00\00\00b\1EH C\88\0C\199\19$\90\91@\C6\C8\C8h\22P\08\142\9E\18\1                                                                                 9!G\C8\90Q\14\08=\00\00\0A\1B\00\00wchar_sizeclang version 5.0.2 (tags/RELEASE_502/final)\00\00#\08\851\82P\1C3\0CC@\CC\10\082\1                                                                                 2\98\A0\8C\D8\D8\EC\DA\5C\DA\DE\C8\EA\D8\CA\5C\CC\D8\C2\CE\E6F\09\88T\D8\D8\EC\DA\5C\D2\C8\CA\DC\E8F\09\0A\00\00\00\A9\18\00\00\                                                                                 0B\00\00\00\0B\0Ar(\87w\80\07zXp\98C=\B8\C38\B0C9\D0\C3\82\E6\1C\C6\A1\0D\E8A\1E\C2\C1\1D\E6!\1D\E8!\1D\DE\C1\1D\00\D1\10\00\00\                                                                                 06\00\00\00\07\CC<\A4\83;\9C\03;\94\03=\A0\83<\94C8\90\C3\01\00\00\00a \00\00\1E\00\00\00\13\04A,\10\00\00\00\06\00\00\00T#\00\A                                                                                 5@8\D4\11\08@\81\14\C8P\C7@\04\05R \00\00\00\003\11Ea\8C\C2LDQ\18\A30\13Q\14\C6(\0C\1B\10\C31\00\C3\06\84\80\0C\C0\B0\01\11\18\0                                                                                 3@B\0D\12j\98\10\80`\C4\C0\00@\10\0C\92\07\09F\0C\0A\00\04\C1 \81\90dBb\00\00\00\00\02\00\00\00\0B\0E\A0\08\84\81@\00\00\00\00\0                                                                                 0q \00\00\03\00\00\002\0E\10\22\84\02\C3\04\00\00\00\00\00\00\00\00e\0C\00\00/\00\00\00\12\03\94p\01\00\00\00\00\00\00\00\14\00\                                                                                 00\00\05\00\00\00D\00\00\00\01\00\00\00P\00\00\00\00\00\00\00P\00\00\00\04\00\00\00\B0\00\00\00\00\00\00\00\19\00\00\00\18\00\00                                                                                 \001\00\00\00\06\00\00\00E\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\00\00\00\00\0A\00\00\00\04\00\00\00\0A\00\00\00\04\00\00                                                                                 \00\FF\FF\FF\FF\00$\00\00\0E\00\00\00\06\00\00\00\0E\00\00\00\06\00\00\00\FF\FF\FF\FF\08$\00\007\00\00\00\06\00\00\00\00\00\00\0                                                                                 0\04\00\00\00\FF\FF\FF\FF\00\18\00\00=\00\00\00\08\00\00\00\04\00\00\00\06\00\00\00\FF\FF\FF\FF\00\18\00\00\00\00\00\00]\0C\00\0                                                                                 0\15\00\00\00\12\03\94\A5\00\00\00\00.str.str.1mainprintf5.0.2x86_64-unknown-linux-gnutest.c.L.str.L.str.1\00\00\00\00\00\00\00"                                                                                 , section ".llvmbc"
    @llvm.cmdline = private constant [652 x i8] c"-triple\00x86_64-unknown-linux-gnu\00-emit-llvm-bc\00-emit-llvm-uselists\00-fembed                                                                                 -bitcode=all\00-disable-llvm-passes\00-disable-free\00-disable-llvm-verifier\00-discard-value-names\00-main-file-name\00test.c\0                                                                                 0-mrelocation-model\00static\00-mthread-model\00posix\00-mdisable-fp-elim\00-fmath-errno\00-masm-verbose\00-mconstructor-aliases                                                                                 \00-munwind-tables\00-target-cpu\00x86-64\00-dwarf-column-info\00-debugger-tuning=gdb\00-coverage-notes-file\00/home/wangyankun/                                                                                 llvm/testClang/test_bitcode.gcno\00-resource-dir\00/mnt/home/wangyankun/llvm/mybuild/lib/clang/5.0.2\00-fdebug-compilation-dir\0                                                                                 0/home/wangyankun/llvm/testClang\00-ferror-limit\0019\00-fmessage-length\00128\00-fobjc-runtime=gcc\00-fdiagnostics-show-option\                                                                                 00", section ".llvmcmd"
    @llvm.compiler.used = appending global [2 x i8*] [i8* getelementptr inbounds ([2756 x i8], [2756 x i8]* @llvm.embedded.module, i32 0, i32 0), i8* getelementptr inbounds ([652 x i8], [652 x i8]* @llvm.cmdline, i32 0, i32 0)], section "llvm.metadata"
    
    ; Function Attrs: noinline nounwind optnone uwtable
    define i32 @main() #0 {
      %1 = alloca i32, align 4
      %2 = alloca i32, align 4
      %3 = alloca i32, align 4
      store i32 0, i32* %1, align 4
      store i32 4, i32* %2, align 4
      store i32 5, i32* %3, align 4
      %4 = load i32, i32* %2, align 4
      %5 = load i32, i32* %3, align 4
      %6 = add nsw i32 %4, %5
      %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %6)
      %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0))
      ret i32 0
    }
    
    declare i32 @printf(i8*, ...) #1
    
    attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
    
    !llvm.module.flags = !{!0}
    !llvm.ident = !{!1}
    
    !0 = !{i32 1, !"wchar_size", i32 4}
    !1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"}
    

    diff两个.ll文件,文件相比于不添加-fembed-bitcode编译出来的的文件,多了很多16进制信息。而剩余部分是相同的,猜测-fembed-bitcode添加了一些数据在原有编译的基础上。

  • 用clang将源文件编译为Object文件
    1.不添加-fembed-bitcode参数编译clang -c test.c -o test.o后生成目标文件(ELF文件)
    然后,通过Objdump -h test.o查看其各个段的信息:
    LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

    2.添加-fembed-bitcode参数编译,clang -fembed-bitcode -c test.c -o test_bitcode.o
    通过Objdump -h test_bitcode.o查看输出LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

    比较发现,附带-fembed-bitcode参数编译出来的目标文件,多了llvmbc,llvmcmd段。
    通过Otool工具查看的结果中,输出字段的含义在源码中可以找到:

    struct section { /* for 32-bit architectures */
    	char		sectname[16];	/* name of this section */
    	char		segname[16];	/* segment this section goes in */
    	uint32_t	addr;		/* memory address of this section */
    	uint32_t	size;		/* size in bytes of this section */
    	uint32_t	offset;		/* file offset of this section */
    	uint32_t	align;		/* section alignment (power of 2) */
    	uint32_t	reloff;		/* file offset of relocation entries */
    	uint32_t	nreloc;		/* number of relocation entries */
    	uint32_t	flags;		/* flags (section type and attributes)*/
    	uint32_t	reserved1;	/* reserved (for offset or index) */
    	uint32_t	reserved2;	/* reserved (for count or sizeof) */
    };
    
  • 用clang将源文件编译为LLVM Assembly文件
    clang -emit-llvm -S test.c -o test.ll
    与用llvm-dis处理bc文件生成的ll文件相同,见上。

通过上面的实践,观察ll文件和elf文件的变化,可以得出结论:

通过 -fembed-bitcode 参数,clang把对应的bitcode文件整个嵌入到了object文件中

注:

非Archive类型的build,比如直接⌘ + B,即使开启了bitcode,也不会编出bitcode,那么会产生什么样的文件呢?通过观察编译日志可以看出xcode在此时使用了-fembed-bitcode-marker 这样一个参数,我们来试一下:

`$ clang -fembed-bitcode-marker -c test.c -o test_bitcode_marker.o $ otool -l test_bitcode_marker.o # 以下为otool输出节选 Section   sectname __bitcode    segname __LLVM       addr 0x0000000000000039       size 0x0000000000000001    # 只有一个字节     offset 769      align 2^0 (1)     reloff 0     nreloc 0      flags 0x00000000 $ objdump -s -section=__bitcode test_bitcode_marker.o Contents of section __bitcode:  0039 00                                   . # 只有一个字节 0x00 `

这样的方式编译出的文件结构与-fembed-bitcode 的结果是一样的,唯一的区别就是 __LLVM,__bitcode__LLVM,__cmdline 的内容并没有将实际的bitcode文件和编译参数嵌入进来,取而代之的一个字节的占位符 0x00

三、第三方LLVM(OLLVM)编译器和其Clang

1.安装

与官方LLVM安装方式一致,唯一区别就是不用下载clang移至llvm下,因为Ollvm包含了clang,直接编译即可。

Obfuscator-LLVM下载地址

编译命令:cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator-llvm-4.0

2.使用第三方clang编译.c文件

  • 用clang将源文件编译为LLVM IR的二进制文件(Bitcode)

    1. 编译不添加-fembed-bitcode参数,即clang -emit-llvm -c test.c -o test.bc

      ; ModuleID = 'test.bc'
      source_filename = "test.c"
      target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      target triple = "x86_64-unknown-linux-gnu"
      
      @.str = private unnamed_addr constant [7 x i8] c"a+b=%d\00", align 1
      @.str.1 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
      
      ; Function Attrs: noinline nounwind uwtable
      define i32 @main() #0 {
        %1 = alloca i32, align 4
        %2 = alloca i32, align 4
        %3 = alloca i32, align 4
        store i32 0, i32* %1, align 4
        store i32 4, i32* %2, align 4
        store i32 5, i32* %3, align 4
        %4 = load i32, i32* %2, align 4
        %5 = load i32, i32* %3, align 4
        %6 = add nsw i32 %4, %5
        %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %6)    %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0))        ret i32 0
      }
      
      declare i32 @printf(i8*, ...) #1
      
      attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
      attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 
      !llvm.ident = !{!0}
      
      !0 = !{!"Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)"}
      
    2. 添加-fembed-bitcode参数,即clang -emit-llvm -fembed-bitcode -c test.c -o test_bitcode.bc

      ; ModuleID = 'test-bitcode.bc'
      source_filename = "test.c"
      target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      target triple = "x86_64-unknown-linux-gnu"
      
      @.str = private unnamed_addr constant [7 x i8] c"a+b=%d\00", align 1
      @.str.1 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
      @llvm.embedded.module = private constant [2424 x i8] c"BC\C0\DE5\14\00\00\05\00\00\00b\0C0$IY\BE&\EE\D3~-D\012\05\00\00\00\00!\0C\00\00T\02\00\00\0B\82 \00\02\00\00\00\13\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0BB\84\102\148\08\18K\0A2B\88H\90\14 CF\88\A5\00\192B\E4H\0E\90\11\22\C4PAQ\81\8C\E1\83\E5\8A\04!F\06Q\18\00\00(\01\00\00\1B\D4&\F8\FF\FF\FF\FF\01p\00\09\08\03b\1C\DEA\1E\E4\A1\1C\C6\81\1E\D8!\1F\DA@\1E\DE\A1\1E\DC\81\1C\CA\81\1C\DA\80\1C\D2\C1\1E\D2\81\1C\CA\A1\0D\E6!\1E\E4\81\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08rH\87y\08\07q`\87rh\03z\08\87t`\876\18\87p`\07v\98\07\C0\1C\C2\81\1D\E6\A1\1C\00\82\1D\CAa\1E\E6\A1\0D\E0A\1E\CAa\1C\D2a\1E\CA\A1\0D\CC\01\1E\DA!\1C\C8\010\87p`\87y(\07\80p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\07\80\1E\E4\A1\1E\CA\01\18\DC\E1\1D\DA\C0\1C\E4!\1C\DA\A1\1C\DA\00\1E\DE!\1D\DC\81\1E\CAA\1E\DA\A0\1C\D8!\1D\DA\A1\0D\DC\E1\1D\DC\A1\0D\D8\A1\1C\C2\C1\1C\00\C2\1D\DE\A1\0D\D2\C1\1D\CCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876P\87zh\07xh\03z\08\07q`\87r\98\07\C0\1C\C2\81\1D\E6\A1\1C\00\C2\1D\DE\A1\0D\DC!\1C\DCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876\98\87t8\07w(\07rh\03}(\07yx\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA\80\1E\E4!\1C\E0\01\1E\D2\C1\1D\CE\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\88y\A0\87p\18\87uh\03x\90\87w\A0\87r\18\07zx\07yh\03q\A8\07s0\87r\90\876\98\87t\D0\87r\00\F0\00 \E8!\1C\E4\E1\1C\CA\81\1E\DA`\1C\E0\A1\1E\00|\C0\03;h\03;\A0\03\80\A0\87p\90\87s(\07zh\03s(\87p\A0\87z\90\87r\98\07`\0D\CC\01\1F\E6A\1E\D8`\0D\DA\A1\1D\F0\81\0D\D6`\1E\E6\A1\1C\D8`\0D\E6a\1E\CAA\0E\D8`\0D\F0\01\0F\EE\00 \EA\C1\1D\E6!\1C\CC\A1\1C\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\88z\98\87rh\83yx\07s\A0\8760\07vx\87p\A0\07\C0\1C\C2\81\1D\E6\A1\1C\80\0D.#\FC\FF\FF\FF\FF@\8C\C3;\C8\83<\94\C38\D0\03;\E4C\1B\C8\C3;\D4\83;\90C9\90C\1B\90C:\D8C:\90C9\B4\C1<\C4\83<\D0C\1B\98\03<\B4A;\84\03=\A0\03`\0E\E1\C0\0E\F3P\0E\00A\0E\E90\0F\E1 \0E\ECP\0Em@\0F\E1\90\0E\EC\D0\06\E3\10\0E\EC\C0\0E\F3\00\98C8\B0\C3<\94\03@\B0C9\CC\C3<\B4\01<\C8C9\8CC:\CCC9\B4\819\C0C;\84\039\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90\0E\ED\00\D0\83<\D4C9\00\83;\BCC\1B\98\83<\84C;\94C\1B\C0\C3;\A4\83;\D0C9\C8C\1B\94\03;\A4C;\B4\81;\BC\83;\B4\01;\94C8\98\03@\B8\C3;\B4A:\B8\839\CCC\1B\98\03<\B4A;\84\03=\A0\03`\0E\E1\C0\0E\F3P\0E\00\E1\0E\EF\D0\06\EE\10\0E\EE0\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\84;\BCC\1B\CCC:\9C\83;\94\039\B4\81>\94\83<\BC\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em@\0F\F2\10\0E\F0\00\0F\E9\E0\0E\E7\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\C4<\D0C8\8C\C3:\B4\01<\C8\C3;\D0C9\8C\03=\BC\83<\B4\818\D4\839\98C9\C8C\1B\CCC:\E8C9\00x\00\10\F4\10\0E\F2p\0E\E5@\0Fm0\0E\F0P\0F\00>\E0\81\1D\B4\81\1D\D0\01@\D0C8\C8\C39\94\03=\B4\819\94C8\D0C=\C8C9\CC\03\B0\06\E6\80\0F\F3 \0Fl\B0\06\ED\D0\0E\F8\C0\06k0\0F\F3P\0El\B0\06\F30\0F\E5 \07l\B0\06\F8\80\07w\00\10\F5\E0\0E\F3\10\0E\E6P\0Em`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00D=\CCC9\B4\C1<\BC\839\D0C\1B\98\03;\BCC8\D0\03`\0E\E1\C0\0E\F3P\0E\00\00\00\00\00I\18\00\00\02\00\00\00\13\82`B \00\00\00\89 \00\00\0E\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\108s\04H\1E\00E6\00\CD\1C\01\18\94\A0\C8\08\AAPH9\10@5\02\00\00\130|\C0\03;\F8\05;\A0\836\A8\07wX\07wx\87{p\876`\87tp\87z\C0\8768\07w\A8\87\0DeP\0Em\D0\0EzP\0Em\90\0Ev@\07z`\07t\D0\06\E6\80\07p\A0\07q \07x\D0\06\EE\80\07z\10\07v\A0\07s \07z`\07t\D0\06\B3\10\07r\80\07:\0FD\90!#EB\80\1DL0\14I\00\00@\00\00\C0\0Ef\18\8C$\00\00 \00\00`\C8c\00\00\10\00\00\00\00\00\00\00\C0\90'\01\02@\00\00\00\00\00\00\00\00\8D\10\865&B\9A|Ab\83@a'\01\00\80,\10\09\00\00\002\1E\98\0C\19\11L\90\8C\09&G\C6\04C\0A5\C2+q\AFD\A6Q\06]f\B3\DF\A0\FB[\CE&+\00\B1\18\00\00h\00\00\003\08\80\1C\C4\E1\1Cf\14\01=\88C8\84\C3\8CB\80\07yx\07s\98q\0C\E6\00\0F\ED\10\0E\F4\80\0E3\0CB\1E\C2\C1\1D\CE\A1\1Cf0\05=\88C8\84\83\1B\CC\03=\C8C=\8C\03=\CCx\8Ctp\07{\08\07yH\87pp\07zp\03vx\87p \87\19\CC\11\0E\EC\90\0E\E10\0Fn0\0F\E3\F0\0E\F0P\0E3\10\C4\1D\DE!\1C\D8!\1D\C2a\1Ef0\89;\BC\83;\D0C9\B4\03<\BC\83<\84\03;\CC\F0\14v`\07{h\077h\87rh\077\80\87p\90\87p`\07v(\07v\F8\05vx\87w\80\87_\08\87q\18\87r\98\87y\98\81,\EE\F0\0E\EE\E0\0E\F5\C0\0E\EC0\03b\C8\A1\1C\E4\A1\1C\CC\A1\1C\E4\A1\1C\DCa\1C\CA!\1C\C4\81\1D\CAa\06\D6\90C9\C8C9\98C9\C8C9\B8\C38\94C8\88\03;\94\C3/\BC\83<\FC\82;\D4\03;\B0\C3\0C\C7i\87pX\87rp\83th\07x`\87t\18\87t\A0\87\19\CES\0F\EE\00\0F\F2P\0E\E4\90\0E\E3@\0F\E1 \0E\ECP\0E3 (\1D\DC\C1\1E\C2A\1E\D2!\1C\DC\81\1E\DC\E0\1C\E4\E1\1D\EA\01\1Ef\18Q8\B0C:\9C\83;\CCP$v`\07{h\077`\87wx\07x\98QL\F4\90\0F\F0P\0E3\1Ej\1E\CAa\1C\E8!\1D\DE\C1\1D~\01\1E\E4\A1\1C\CC!\1D\F0a\06T\85\838\CC\C3;\B0C=\D0C9\FC\C2<\E4C;\88\C3;\B0\03\00y \00\00\22\00\00\00b\1EH C\88\0C\199\19$\90\91@\C6\C8\C8h\22P\08\142\9E\18\19!G\C8\90Q\0C\88T\00\00\A5\00\00\00Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)\00\00\003\04\81\8C\04&(\1566\BB6\974\B227\BAQ\82\00\00\00\00\A9\18\00\00\0B\00\00\00\0B\0Ar(\87w\80\07zXp\98C=\B8\C38\B0C9\D0\C3\82\E6\1C\C6\A1\0D\E8A\1E\C2\C1\1D\E6!\1D\E8!\1D\DE\C1\1D\00a \00\00\1E\00\00\00\13\04A,\10\00\00\00\06\00\00\00T%0\02P\08\A5@8\D4\11\08@q\14\C7P\C7@\04\C5Q\1C\003\11Ea\8C\C2LDQ\18\A30\13Q\14\C6(\0C\1B\10\032\00\C3\06\84p\0C\C0\B0\01\11\18\03@B\0D\12j\98\10\80`\C4\C0\00@\10\0C\92\07\09F\0C\0A\00\04\C1 \81\90lBb\00\00\00\00\02\00\00\00\0B\0E\A0\08\84\818\00\00\00\00\00q \00\00\0D\00\00\00R\0E\10\22d\82\A4\1C D\C8\E4H9@\88\90\A1\8C\05\84\08\@llvm.cmdline = private constant [663 x i8] c"-triple\00x86_64-unknown-linux-gnu\00-emit-llvm-bc\00-emit-llvm-uselists\00-fembed-bitcode=all\00-disable-llvm-passes\00-disable-free\00-disable-llvm-verifier\00-discard-value-names\00-main-file-name\00test.c\00-mrelocation-model\00static\00-mthread-model\00posix\00-mdisable-fp-elim\00-fmath-errno\00-masm-verbose\00-mconstructor-aliases\00-munwind-tables\00-target-cpu\00x86-64\00-dwarf-column-info\00-debugger-tuning=gdb\00-coverage-notes-file\00/home/wangyankun/ollvm/testOClang/test-bitcode.gcno\00-resource-dir\00/mnt/home/wangyankun/ollvm/obuild/bin/../lib/clang/4.0.1\00-fdebug-compilation-dir\00/home/wangyankun/ollvm/testOClang\00-ferror-limit\0019\00-fmessage-length\00114\00-fobjc-runtime=gcc\00-fdiagnostics-show-option\00", section ".llvmcmd"
      @llvm.compiler.used = appending global [2 x i8*] [i8* getelementptr inbounds ([2424 x i8], [2424 x i8]* @llvm.embedded.module, i32 0, i32 0), i8* getelementptr inbounds ([663 x i8], [663 x i8]* @llvm.cmdline, i32 0, i32 0)], section "llvm.metadata"
      
      ; Function Attrs: noinline nounwind uwtable
      define i32 @main() #0 {
        %1 = alloca i32, align 4
        %2 = alloca i32, align 4
        %3 = alloca i32, align 4
        store i32 0, i32* %1, align 4
        store i32 4, i32* %2, align 4
        store i32 5, i32* %3, align 4
        %4 = load i32, i32* %2, align 4
        %5 = load i32, i32* %3, align 4
        %6 = add nsw i32 %4, %5
        %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %6)    %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0))        ret i32 0
      }
      
      declare i32 @printf(i8*, ...) #1
      
      attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
      attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 
      !llvm.ident = !{!0}
      
      !0 = !{!"Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)"}
      

      两者diff的结果为:

      1c1
      < ; ModuleID = 'test.bc'
      ---
      > ; ModuleID = 'test-bitcode.bc'
      7a8,10
      > @llvm.embedded.module = private constant [2424 x i8] c"BC\C0\DE5\14\00\00\05\00\00\00b\0C0$IY\BE&\EE\D3~-D\012\05\00\00\00\00!\0C\00\00T\02\00\00\0B\82 \00\02\00\00\00\13\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0BB\84\102\148\08\18K\0A2B\88H\90\14 CF\88\A5\00\192B\E4H\0E\90\11\22\C4PAQ\81\8C\E1\83\E5\8A\04!F\06Q\18\00\00(\01\00\00\1B\D4&\F8\FF\FF\FF\FF\01p\00\09\08\03b\1C\DEA\1E\E4\A1\1C\C6\81\1E\D8!\1F\DA@\1E\DE\A1\1E\DC\81\1C\CA\81\1C\DA\80\1C\D2\C1\1E\D2\81\1C\CA\A1\0D\E6!\1E\E4\81\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08rH\87y\08\07q`\87rh\03z\08\87t`\876\18\87p`\07v\98\07\C0\1C\C2\81\1D\E6\A1\1C\00\82\1D\CAa\1E\E6\A1\0D\E0A\1E\CAa\1C\D2a\1E\CA\A1\0D\CC\01\1E\DA!\1C\C8\010\87p`\87y(\07\80p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\07\80\1E\E4\A1\1E\CA\01\18\DC\E1\1D\DA\C0\1C\E4!\1C\DA\A1\1C\DA\00\1E\DE!\1D\DC\81\1E\CAA\1E\DA\A0\1C\D8!\1D\DA\A1\0D\DC\E1\1D\DC\A1\0D\D8\A1\1C\C2\C1\1C\00\C2\1D\DE\A1\0D\D2\C1\1D\CCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876P\87zh\07xh\03z\08\07q`\87r\98\07\C0\1C\C2\81\1D\E6\A1\1C\00\C2\1D\DE\A1\0D\DC!\1C\DCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876\98\87t8\07w(\07rh\03}(\07yx\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA\80\1E\E4!\1C\E0\01\1E\D2\C1\1D\CE\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\88y\A0\87p\18\87uh\03x\90\87w\A0\87r\18\07zx\07yh\03q\A8\07s0\87r\90\876\98\87t\D0\87r\00\F0\00 \E8!\1C\E4\E1\1C\CA\81\1E\DA`\1C\E0\A1\1E\00|\C0\03;h\03;\A0\03\80\A0\87p\90\87s(\07zh\03s(\87p\A0\87z\90\87r\98\07`\0D\CC\01\1F\E6A\1E\D8`\0D\DA\A1\1D\F0\81\0D\D6`\1E\E6\A1\1C\D8`\0D\E6a\1E\CAA\0E\D8`\0D\F0\01\0F\EE\00 \EA\C1\1D\E6!\1C\CC\A1\1C\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\88z\98\87rh\83yx\07s\A0\8760\07vx\87p\A0\07\C0\1C\C2\81\1D\E6\A1\1C\80\0D.#\FC\FF\FF\FF\FF@\8C\C3;\C8\83<\94\C38\D0\03;\E4C\1B\C8\C3;\D4\83;\90C9\90C\1B\90C:\D8C:\90C9\B4\C1<\C4\83<\D0C\1B\98\03<\B4A;\84\03=\A0\03`\0E\E1\C0\0E\F3P\0E\00A\0E\E90\0F\E1 \0E\ECP\0Em@\0F\E1\90\0E\EC\D0\06\E3\10\0E\EC\C0\0E\F3\00\98C8\B0\C3<\94\03@\B0C9\CC\C3<\B4\01<\C8C9\8CC:\CCC9\B4\819\C0C;\84\039\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90\0E\ED\00\D0\83<\D4C9\00\83;\BCC\1B\98\83<\84C;\94C\1B\C0\C3;\A4\83;\D0C9\C8C\1B\94\03;\A4C;\B4\81;\BC\83;\B4\01;\94C8\98\03@\B8\C3;\B4A:\B8\839\CCC\1B\98\03<\B4A;\84\03=\A0\03`\0E\E1\C0\0E\F3P\0E\00\E1\0E\EF\D0\06\EE\10\0E\EE0\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\84;\BCC\1B\CCC:\9C\83;\94\039\B4\81>\94\83<\BC\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em@\0F\F2\10\0E\F0\00\0F\E9\E0\0E\E7\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\C4<\D0C8\8C\C3:\B4\01<\C8\C3;\D0C9\8C\03=\BC\83<\B4\818\D4\839\98C9\C8C\1B\CCC:\E8C9\00x\00\10\F4\10\0E\F2p\0E\E5@\0Fm0\0E\F0P\0F\00>\E0\81\1D\B4\81\1D\D0\01@\D0C8\C8\C39\94\03=\B4\819\94C8\D0C=\C8C9\CC\03\B0\06\E6\80\0F\F3 \0Fl\B0\06\ED\D0\0E\F8\C0\06k0\0F\F3P\0El\B0\06\F30\0F\E5 \07l\B0\06\F8\80\07w\00\10\F5\E0\0E\F3\10\0E\E6P\0Em`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00D=\CCC9\B4\C1<\BC\839\D0C\1B\98\03;\BCC8\D0\03`\0E\E1\C0\0E\F3P\0E\00\00\00\00\00I\18\00\00\02\00\00\00\13\82`B \00\00\00\89 \00\00\0E\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\108s\04H\1E\00E6\00\CD\1C\01\18\94\A0\C8\08\AAPH9\10@5\02\00\00\130|\C0\03;\F8\05;\A0\836\A8\07wX\07wx\87{p\876`\87tp\87z\C0\8768\07w\A8\87\0DeP\0Em\D0\0EzP\0Em\90\0Ev@\07z`\07t\D0\06\E6\80\07p\A0\07q \07x\D0\06\EE\80\07z\10\07v\A0\07s \07z`\07t\D0\06\B3\10\07r\80\07:\0FD\90!#EB\80\1DL0\14I\00\00@\00\00\C0\0Ef\18\8C$\00\00 \00\00`\C8c\00\00\10\00\00\00\00\00\00\00\C0\90'\01\02@\00\00\00\00\00\00\00\00\8D\10\865&B\9A|Ab\83@a'\01\00\80,\10\09\00\00\002\1E\98\0C\19\11L\90\8C\09&G\C6\04C\0A5\C2+q\AFD\A6Q\06]f\B3\DF\A0\FB[\CE&+\00\B1\18\00\00h\00\00\003\08\80\1C\C4\E1\1Cf\14\01=\88C8\84\C3\8CB\80\07yx\07s\98q\0C\E6\00\0F\ED\10\0E\F4\80\0E3\0CB\1E\C2\C1\1D\CE\A1\1Cf0\05=\88C8\84\83\1B\CC\03=\C8C=\8C\03=\CCx\8Ctp\07{\08\07yH\87pp\07zp\03vx\87p \87\19\CC\11\0E\EC\90\0E\E10\0Fn0\0F\E3\F0\0E\F0P\0E3\10\C4\1D\DE!\1C\D8!\1D\C2a\1Ef0\89;\BC\83;\D0C9\B4\03<\BC\83<\84\03;\CC\F0\14v`\07{h\077h\87rh\077\80\87p\90\87p`\07v(\07v\F8\05vx\87w\80\87_\08\87q\18\87r\98\87y\98\81,\EE\F0\0E\EE\E0\0E\F5\C0\0E\EC0\03b\C8\A1\1C\E4\A1\1C\CC\A1\1C\E4\A1\1C\DCa\1C\CA!\1C\C4\81\1D\CAa\06\D6\90C9\C8C9\98C9\C8C9\B8\C38\94C8\88\03;\94\C3/\BC\83<\FC\82;\D4\03;\B0\C3\0C\C7i\87pX\87rp\83th\07x`\87t\18\87t\A0\87\19\CES\0F\EE\00\0F\F2P\0E\E4\90\0E\E3@\0F\E1 \0E\ECP\0E3 (\1D\DC\C1\1E\C2A\1E\D2!\1C\DC\81\1E\DC\E0\1C\E4\E1\1D\EA\01\1Ef\18Q8\B0C:\9C\83;\CCP$v`\07{h\077`\87wx\07x\98QL\F4\90\0F\F0P\0E3\1Ej\1E\CAa\1C\E8!\1D\DE\C1\1D~\01\1E\E4\A1\1C\CC!\1D\F0a\06T\85\838\CC\C3;\B0C=\D0C9\FC\C2<\E4C;\88\C3;\B0\03\00y \00\00\22\00\00\00b\1EH C\88\0C\199\19$\90\91@\C6\C8\C8h\22P\08\142\9E\18\19!G\C8\90Q\0C\88T\00\00\A5\00\00\00Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)\00\00\003\04\81\8C\04&(\1566\BB6\974\B227\BAQ\82\00\00\00\00\A9\18\00\00\0B\00\00\00\0B\0Ar(\87w\80\07zXp\98C=\B8\C38\B0C9\D0\C3\82\E6\1C\C6\A1\0D\E8A\1E\C2\C1\1D\E6!\1D\E8!\1D\DE\C1\1D\00a \00\00\1E\00\00\00\13\04A,\10\00\00\00\06\00\00\00T%0\02P\08\A5@8\D4\11\08@q\14\C7P\C7@\04\C5Q\1C\003\11Ea\8C\C2LDQ\18\A30\13Q\14\C6(\0C\1B\10\032\00\C3\06\84p\0C\C0\B0\01\11\18\03@B\0D\12j\98\10\80`\C4\C0\00@\10\0C\92\07\09F\0C\0A\00\04\C1 \81\90lBb\00\00\00\00\02\00\00\00\0B\0E\A0\08\84\818\00\00\00\00\00q \00\00\0D\00\00\00R\0E\10\22d\82\A4\1C D\C8\E4H9@\88\90\A1\8C\05\84\08\D9\80\F1DH3\15*\E0J@0\00\D2X\80\E1KS\E4\D7\06@\F8\D2\14\01\00\00\00\00\00\00\00", section ".llvmbc"
      > @llvm.cmdline = private constant [663 x i8] c"-triple\00x86_64-unknown-linux-gnu\00-emit-llvm-bc\00-emit-llvm-uselists\00-fembed-bitcode=all\00-disable-llvm-passes\00-disable-free\00-disable-llvm-verifier\00-discard-value-names\00-main-file-name\00test.c\00-mrelocation-model\00static\00-mthread-model\00posix\00-mdisable-fp-elim\00-fmath-errno\00-masm-verbose\00-mconstructor-aliases\00-munwind-tables\00-target-cpu\00x86-64\00-dwarf-column-info\00-debugger-tuning=gdb\00-coverage-notes-file\00/home/wangyankun/ollvm/testOClang/test-bitcode.gcno\00-resource-dir\00/mnt/home/wangyankun/ollvm/obuild/bin/../lib/clang/4.0.1\00-fdebug-compilation-dir\00/home/wangyankun/ollvm/testOClang\00-ferror-limit\0019\00-fmessage-length\00114\00-fobjc-runtime=gcc\00-fdiagnostics-show-option\00", section ".llvmcmd"
      > @llvm.compiler.used = appending global [2 x i8*] [i8* getelementptr inbounds ([2424 x i8], [2424 x i8]* @llvm.embedded.module, i32 0, i32 0), i8* getelementptr inbounds ([663 x i8], [663 x i8]* @llvm.cmdline, i32 0, i32 0)], section "llvm.metadata"
      

      同样附加了很多bitcode的信息16进制信息。

  • 用clang将源文件编译为Object文件

    1. 不添加-fembed-bitcode参数编译clang -c test.c -o test.o后生成目标文件(ELF文件)
      LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

    2. .添加-fembed-bitcode参数编译,clang -fembed-bitcode -c test.c -o test_bitcode.o

    LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响
    同样多了llvmbc和llvmcmd段。

    通过objdump -S -j .llvmbc test-bitcode.o查看.llvmbc段的反汇编后的汇编代码,源代码这么简单的一段程序,.llvmbc这个段的内容就显示到975行后还有剩余。

    .text的反汇编后的汇编代码如下所示:
    LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响

四、LLVM和OLLVM的Clang编译结果diff

  • Diff IR文件(.ll文件)

    • 不添加-fembed-bitcode编译的文件比较,diff llvm/testClang/test.ll ollvm/testOClang/test.ll

      < ; Function Attrs: noinline nounwind optnone uwtable
      ---
      > ; Function Attrs: noinline nounwind uwtable
      27c27
      < attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
      ---
      > attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
      30,31c30
      < !llvm.module.flags = !{!0}
      < !llvm.ident = !{!1}
      ---
      > !llvm.ident = !{!0}
      33,34c32
      < !0 = !{i32 1, !"wchar_size", i32 4}
      < !1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"}
      ---
      > !0 = !{!"Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)"}
      

      不同点:

      1. Function Attrs和attributes中差了一个optnone参数,这个属性,经过百度查询可知:optnone属性基本上抑制了函数或方法的所有优化,而不管整个编译单元应用的优化级别如何
      2. 末尾标注的编译器不同,即llvm.module.flag和llvm.ident不同。以ollvm编译的bc文件,没有llvm.module.flag属性且llvm.ident不同于官方的clang version 5.0.2 (tags/RELEASE_502/final)而是Obfuscator-LLVM clang version 4.0.1
    • 添加-fembed-bitcode编辑的文件比较,diff llvm/testClang/test_bitcode.ll ollvm/testOClang/test-bitcode.ll

      1c1
      < ; ModuleID = 'test_bitcode.bc'
      ---
      > ; ModuleID = 'test-bitcode.bc'
      8,10c8,10
      < @llvm.embedded.module = private constant [2756 x i8] c"BC\C0\DE5\14\00\00\05\00\00\00b\0C0$IY\BEf\EE\D3\BE-D\012\05\00\00\00\00!\0C\00\00_\02\00\00\0B\02!\00\02\00\00\00\13\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0BB\84\102\148\08\18K\0A2B\88H\90\14 CF\88\A5\00\192B\E4H\0E\90\11\22\C4PAQ\81\8C\E1\83\E5\8A\04!F\06Q\18\00\00(\01\00\00\1B\D8&\F8\FF\FF\FF\FF\01p\00\09(\03 \0C\88qx\07y\90\87r\18\07z`\87|h\03yx\87zp\07r(\07rh\03rH\07{H\07r(\876\98\87x\90\07zh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \C8!\1D\E6!\1C\C4\81\1D\CA\A1\0D\E8!\1C\D2\81\1D\DA`\1C\C2\81\1D\D8a\1E\00s\08\07v\98\87r\00\08v(\87y\98\876\80\07y(\87qH\87y(\8760\07xh\87p \07\C0\1C\C2\81\1D\E6\A1\1C\00\C2\1D\DE\A1\0D\CCA\1E\C2\A1\1D\CA\A1\0D\E0\E1\1D\D2\C1\1D\E8\A1\1C\E4\A1\0D\CA\81\1D\D2\A1\1D\00z\90\87z(\07`p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\876p\87wp\876`\87r\08\07s\00\08wx\876H\07w0\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA@\1D\EA\A1\1D\E0\A1\0D\E8!\1C\C4\81\1D\CAa\1E\00s\08\07v\98\87r\00\08wx\876p\87pp\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA`\1E\D2\E1\1C\DC\A1\1C\C8\A1\0D\F4\A1\1C\E4\E1\1D\E6\A1\0D\CC\01\1E\DA\A0\1D\C2\81\1E\D0\010\87p`\87y(\07\80p\87wh\03z\90\87p\80\07xH\07w8\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \E6\81\1E\C2a\1C\D6\A1\0D\E0A\1E\DE\81\1E\CAa\1C\E8\E1\1D\E4\A1\0D\C4\A1\1E\CC\C1\1C\CAA\1E\DA`\1E\D2A\1F\CA\01\C0\03\80\A0\87p\90\87s(\07zh\83q\80\87z\00\F0\01\0F\EC\A0\0D\EC\80\0E\00\82\1E\C2A\1E\CE\A1\1C\E8\A1\0D\CC\A1\1C\C2\81\1E\EAA\1E\CAa\1E\8050\07|\98\07y`\835h\87v\C0\076X\83y\98\87r`\835\98\87y(\079`\835\C0\07<\B8\03\80\A8\07w\98\87p0\87rh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \EAa\1E\CA\A1\0D\E6\E1\1D\CC\81\1E\DA\C0\1C\D8\E1\1D\C2\81\1E\00s\08\07v\98\87r\006\B8\8C\F0\FF\FF\FF\FF\031\0E\EF \0F\F2P\0E\E3@\0F\EC\90\0Fm \0F\EFP\0F\EE@\0E\E5@\0Em@\0E\E9`\0F\E9@\0E\E5\D0\06\F3\10\0F\F2@\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\049\A4\C3<\84\838\B0C9\B4\01=\84C:\B0C\1B\8CC8\B0\03;\CC\03`\0E\E1\C0\0E\F3P\0E\00\C1\0E\E50\0F\F3\D0\06\F0 \0F\E50\0E\E90\0F\E5\D0\06\E6\00\0F\ED\10\0E\E4\00\98C8\B0\C3<\94\03@\B8\C3;\B4\819\C8C8\B4C9\B4\01<\BCC:\B8\03=\94\83<\B4A9\B0C:\B4\03@\0F\F2P\0F\E5\00\0C\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90\0E\ED\D0\06\EE\F0\0E\EE\D0\06\ECP\0E\E1`\0E\00\E1\0E\EF\D0\06\E9\E0\0E\E60\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\84;\BCC\1B\B8C8\B8\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em0\0F\E9p\0E\EEP\0E\E4\D0\06\FAP\0E\F2\F0\0E\F3\D0\06\E6\00\0Fm\D0\0E\E1@\0F\E8\00\98C8\B0\C3<\94\03@\B8\C3;\B4\01=\C8C8\C0\03<\A4\83;\9CC\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\F3@\0F\E10\0E\EB\D0\06\F0 \0F\EF@\0F\E50\0E\F4\F0\0E\F2\D0\06\E2P\0F\E6`\0E\E5 \0Fm0\0F\E9\A0\0F\E5\00\E0\01@\D0C8\C8\C39\94\03=\B4\C18\C0C=\00\F8\80\07v\D0\06v@\07\00A\0F\E1 \0F\E7P\0E\F4\D0\06\E6P\0E\E1@\0F\F5 \0F\E50\0F\C0\1A\98\03>\CC\83<\B0\C1\1A\B4C;\E0\03\1B\AC\C1<\CCC9\B0\C1\1A\CC\C3<\94\83\1C\B0\C1\1A\E0\03\1E\DC\01@\D4\83;\CCC8\98C9\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\F50\0F\E5\D0\06\F3\F0\0E\E6@\0Fm`\0E\EC\F0\0E\E1@\0F\809\84\03;\CCC9\00\00\00I\18\00\00\02\00\00\00\13\82`B \00\00\00\89 \00\00\0E\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\108s\04H\1E\00E6\00\CD\1C\01\18\94\A0\C8\08\AAPH9\10@5\02\00\00\130|\C0\03;\F8\05;\A0\836\A8\07wX\07wx\87{p\876`\87tp\87z\C0\8768\07w\A8\87\0DeP\0Em\D0\0EzP\0Em\90\0Ev@\07z`\07t\D0\06\E6\80\07p\A0\07q \07x\D0\06\EE\80\07z\10\07v\A0\07s \07z`\07t\D0\06\B3\10\07r\80\07J\0F\08\11\12A\86\8C\14\09\014B\18\D6\98\08i\F2\85\1D\0F@\04C\91\04\00\00\04\00\00\00;\1E\C2\18\06#\09\00\00\08\00\00\00\86D\0Aa\00\00\10\00\00\00\00\00\00\00\C0\90\C81\12 \00\04\00\00\00\00\00\00\00\90\D8 PxL\00\00 \0B\04\00\00\0A\00\00\002\1E\98\10\19\11L\90\8C\09&G\C6\04C\0A5\C2+q\AFD\A6Q\06]f\B3\DF\A0\FB[\CE&+\A8J\A0\10\00\B1\18\00\00m\00\00\003\08\80\1C\C4\E1\1Cf\14\01=\88C8\84\C3\8CB\80\07yx\07s\98q\0C\E6\00\0F\ED\10\0E\F4\80\0E3\0CB\1E\C2\C1\1D\CE\A1\1Cf0\05=\88C8\84\83\1B\CC\03=\C8C=\8C\03=\CCx\8Ctp\07{\08\07yH\87pp\07zp\03vx\87p \87\19\CC\11\0E\EC\90\0E\E10\0Fn0\0F\E3\F0\0E\F0P\0E3\10\C4\1D\DE!\1C\D8!\1D\C2a\1Ef0\89;\BC\83;\D0C9\B4\03<\BC\83<\84\03;\CC\F0\14v`\07{h\077h\87rh\077\80\87p\90\87p`\07v(\07v\F8\05vx\87w\80\87_\08\87q\18\87r\98\87y\98\81,\EE\F0\0E\EE\E0\0E\F5\C0\0E\EC0\03b\C8\A1\1C\E4\A1\1C\CC\A1\1C\E4\A1\1C\DCa\1C\CA!\1C\C4\81\1D\CAa\06\D6\90C9\C8C9\98C9\C8C9\B8\C38\94C8\88\03;\94\C3/\BC\83<\FC\82;\D4\03;\B0\C3\0C\C7i\87pX\87rp\83th\07x`\87t\18\87t\A0\87\19\CES\0F\EE\00\0F\F2P\0E\E4\90\0E\E3@\0F\E1 \0E\ECP\0E3 (\1D\DC\C1\1E\C2A\1E\D2!\1C\DC\81\1E\DC\E0\1C\E4\E1\1D\EA\01\1Ef\18Q8\B0C:\9C\83;\CCP$v`\07{h\077`\87wx\07x\98QL\F4\90\0F\F0P\0E3\1Ej\1E\CAa\1C\E8!\1D\DE\C1\1D~\01\1E\E4\A1\1C\CC!\1D\F0a\06T\85\838\CC\C3;\B0C=\D0C9\FC\C2<\E4C;\88\C3;\B0\C3\8C\C5\0A\87y\98\87w\18\87t\08\07z(\07r\00\00\00\00y \00\00&\00\00\00b\1EH C\88\0C\199\19$\90\91@\C6\C8\C8h\22P\08\142\9E\18\19!G\C8\90Q\14\08=\00\00\0A\1B\00\00wchar_sizeclang version 5.0.2 (tags/RELEASE_502/final)\00\00#\08\851\82P\1C3\0CC@\CC\10\082\12\98\A0\8C\D8\D8\EC\DA\5C\DA\DE\C8\EA\D8\CA\5C\CC\D8\C2\CE\E6F\09\88T\D8\D8\EC\DA\5C\D2\C8\CA\DC\E8F\09\0A\00\00\00\A9\18\00\00\0B\00\00\00\0B\0Ar(\87w\80\07zXp\98C=\B8\C38\B0C9\D0\C3\82\E6\1C\C6\A1\0D\E8A\1E\C2\C1\1D\E6!\1D\E8!\1D\DE\C1\1D\00\D1\10\00\00\06\00\00\00\07\CC<\A4\83;\9C\03;\94\03=\A0\83<\94C8\90\C3\01\00\00\00a \00\00\1E\00\00\00\13\04A,\10\00\00\00\06\00\00\00T#\00\A5@8\D4\11\08@\81\14\C8P\C7@\04\05R \00\00\00\003\11Ea\8C\C2LDQ\18\A30\13Q\14\C6(\0C\1B\10\C31\00\C3\06\84\80\0C\C0\B0\01\11\18\03@B\0D\12j\98\10\80`\C4\C0\00@\10\0C\92\07\09F\0C\0A\00\04\C1 \81\90dBb\00\00\00\00\02\00\00\00\0B\0E\A0\08\84\81@\00\00\00\00\00q \00\00\03\00\00\002\0E\10\22\84\02\C3\04\00\00\00\00\00\00\00\00e\0C\00\00/\00\00\00\12\03\94p\01\00\00\00\00\00\00\00\14\00\00\00\05\00\00\00D\00\00\00\01\00\00\00P\00\00\00\00\00\00\00P\00\00\00\04\00\00\00\B0\00\00\00\00\00\00\00\19\00\00\00\18\00\00\001\00\00\00\06\00\00\00E\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\00\00\00\00\0A\00\00\00\04\00\00\00\0A\00\00\00\04\00\00\00\FF\FF\FF\FF\00$\00\00\0E\00\00\00\06\00\00\00\0E\00\00\00\06\00\00\00\FF\FF\FF\FF\08$\00\007\00\00\00\06\00\00\00\00\00\00\00\04\00\00\00\FF\FF\FF\FF\00\18\00\00=\00\00\00\08\00\00\00\04\00\00\00\06\00\00\00\FF\FF\FF\FF\00\18\00\00\00\00\00\00]\0C\00\00\15\00\00\00\12\03\94\A5\00\00\00\00.str.str.1mainprintf5.0.2x86_64-unknown-linux-gnutest.c.L.str.L.str.1\00\00\00\00\00\00\00", section ".llvmbc"
      < @llvm.cmdline = private constant [652 x i8] c"-triple\00x86_64-unknown-linux-gnu\00-emit-llvm-bc\00-emit-llvm-uselists\00-fembed-bitcode=all\00-disable-llvm-passes\00-disable-free\00-disable-llvm-verifier\00-discard-value-names\00-main-file-name\00test.c\00-mrelocation-model\00static\00-mthread-model\00posix\00-mdisable-fp-elim\00-fmath-errno\00-masm-verbose\00-mconstructor-aliases\00-munwind-tables\00-target-cpu\00x86-64\00-dwarf-column-info\00-debugger-tuning=gdb\00-coverage-notes-file\00/home/wangyankun/llvm/testClang/test_bitcode.gcno\00-resource-dir\00/mnt/home/wangyankun/llvm/mybuild/lib/clang/5.0.2\00-fdebug-compilation-dir\00/home/wangyankun/llvm/testClang\00-ferror-limit\0019\00-fmessage-length\00128\00-fobjc-runtime=gcc\00-fdiagnostics-show-option\00", section ".llvmcmd"     < @llvm.compiler.used = appending global [2 x i8*] [i8* getelementptr inbounds ([2756 x i8], [2756 x i8]* @llvm.embedded.module, i32 0, i32 0), i8* getelementptr inbounds ([652 x i8], [652 x i8]* @llvm.cmdline, i32 0, i32 0)], section "llvm.metadata"
      ---
      > @llvm.embedded.module = private constant [2424 x i8] c"BC\C0\DE5\14\00\00\05\00\00\00b\0C0$IY\BE&\EE\D3~-D\012\05\00\00\00\00!\0C\00\00T\02\00\00\0B\82 \00\02\00\00\00\13\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0BB\84\102\148\08\18K\0A2B\88H\90\14 CF\88\A5\00\192B\E4H\0E\90\11\22\C4PAQ\81\8C\E1\83\E5\8A\04!F\06Q\18\00\00(\01\00\00\1B\D4&\F8\FF\FF\FF\FF\01p\00\09\08\03b\1C\DEA\1E\E4\A1\1C\C6\81\1E\D8!\1F\DA@\1E\DE\A1\1E\DC\81\1C\CA\81\1C\DA\80\1C\D2\C1\1E\D2\81\1C\CA\A1\0D\E6!\1E\E4\81\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08rH\87y\08\07q`\87rh\03z\08\87t`\876\18\87p`\07v\98\07\C0\1C\C2\81\1D\E6\A1\1C\00\82\1D\CAa\1E\E6\A1\0D\E0A\1E\CAa\1C\D2a\1E\CA\A1\0D\CC\01\1E\DA!\1C\C8\010\87p`\87y(\07\80p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\07\80\1E\E4\A1\1E\CA\01\18\DC\E1\1D\DA\C0\1C\E4!\1C\DA\A1\1C\DA\00\1E\DE!\1D\DC\81\1E\CAA\1E\DA\A0\1C\D8!\1D\DA\A1\0D\DC\E1\1D\DC\A1\0D\D8\A1\1C\C2\C1\1C\00\C2\1D\DE\A1\0D\D2\C1\1D\CCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876P\87zh\07xh\03z\08\07q`\87r\98\07\C0\1C\C2\81\1D\E6\A1\1C\00\C2\1D\DE\A1\0D\DC!\1C\DCa\1E\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\08wx\876\98\87t8\07w(\07rh\03}(\07yx\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA\80\1E\E4!\1C\E0\01\1E\D2\C1\1D\CE\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\88y\A0\87p\18\87uh\03x\90\87w\A0\87r\18\07zx\07yh\03q\A8\07s0\87r\90\876\98\87t\D0\87r\00\F0\00 \E8!\1C\E4\E1\1C\CA\81\1E\DA`\1C\E0\A1\1E\00|\C0\03;h\03;\A0\03\80\A0\87p\90\87s(\07zh\03s(\87p\A0\87z\90\87r\98\07`\0D\CC\01\1F\E6A\1E\D8`\0D\DA\A1\1D\F0\81\0D\D6`\1E\E6\A1\1C\D8`\0D\E6a\1E\CAA\0E\D8`\0D\F0\01\0F\EE\00 \EA\C1\1D\E6!\1C\CC\A1\1C\DA\C0\1C\E0\A1\0D\DA!\1C\E8\01\1D\00s\08\07v\98\87r\00\88z\98\87rh\83yx\07s\A0\8760\07vx\87p\A0\07\C0\1C\C2\81\1D\E6\A1\1C\80\0D.#\FC\FF\FF\FF\FF@\8C\C3;\C8\83<\94\C38\D0\03;\E4C\1B\C8\C3;\D4\83;\90C9\90C\1B\90C:\D8C:\90C9\B4\C1<\C4\83<\D0C\1B\98\03<\B4A;\84\03=\A0\03`\0E\E1\C0\0E\F3P\0E\00A\0E\E90\0F\E1 \0E\ECP\0Em@\0F\E1\90\0E\EC\D0\06\E3\10\0E\EC\C0\0E\F3\00\98C8\B0\C3<\94\03@\B0C9\CC\C3<\B4\01<\C8C9\8CC:\CCC9\B4\819\C0C;\84\039\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90\0E\ED\00\D0\83<\D4C9\00\83;\BCC\1B\98\83<\84C;\94C\1B\C0\C3;\A4\83;\D0C9\C8C\1B\94\03;\A4C;\B4\81;\BC\83;\B4\01;\94C8\98\03@\B8\C3;\B4A:\B8\839\CCC\1B\98\03<\B4A;\84\03=\A0\03`\0E\E1\C0\0E\F3P\0E\00\E1\0E\EF\D0\06\EE\10\0E\EE0\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\84;\BCC\1B\CCC:\9C\83;\94\039\B4\81>\94\83<\BC\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em@\0F\F2\10\0E\F0\00\0F\E9\E0\0E\E7\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\C4<\D0C8\8C\C3:\B4\01<\C8\C3;\D0C9\8C\03=\BC\83<\B4\818\D4\839\98C9\C8C\1B\CCC:\E8C9\00x\00\10\F4\10\0E\F2p\0E\E5@\0Fm0\0E\F0P\0F\00>\E0\81\1D\B4\81\1D\D0\01@\D0C8\C8\C39\94\03=\B4\819\94C8\D0C=\C8C9\CC\03\B0\06\E6\80\0F\F3 \0Fl\B0\06\ED\D0\0E\F8\C0\06k0\0F\F3P\0El\B0\06\F30\0F\E5 \07l\B0\06\F8\80\07w\00\10\F5\E0\0E\F3\10\0E\E6P\0Em`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00D=\CCC9\B4\C1<\BC\839\D0C\1B\98\03;\BCC8\D0\03`\0E\E1\C0\0E\F3P\0E\00\00\00\00\00I\18\00\00\02\00\00\00\13\82`B \00\00\00\89 \00\00\0E\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\108s\04H\1E\00E6\00\CD\1C\01\18\94\A0\C8\08\AAPH9\10@5\02\00\00\130|\C0\03;\F8\05;\A0\836\A8\07wX\07wx\87{p\876`\87tp\87z\C0\8768\07w\A8\87\0DeP\0Em\D0\0EzP\0Em\90\0Ev@\07z`\07t\D0\06\E6\80\07p\A0\07q \07x\D0\06\EE\80\07z\10\07v\A0\07s \07z`\07t\D0\06\B3\10\07r\80\07:\0FD\90!#EB\80\1DL0\14I\00\00@\00\00\C0\0Ef\18\8C$\00\00 \00\00`\C8c\00\00\10\00\00\00\00\00\00\00\C0\90'\01\02@\00\00\00\00\00\00\00\00\8D\10\865&B\9A|Ab\83@a'\01\00\80,\10\09\00\00\002\1E\98\0C\19\11L\90\8C\09&G\C6\04C\0A5\C2+q\AFD\A6Q\06]f\B3\DF\A0\FB[\CE&+\00\B1\18\00\00h\00\00\003\08\80\1C\C4\E1\1Cf\14\01=\88C8\84\C3\8CB\80\07yx\07s\98q\0C\E6\00\0F\ED\10\0E\F4\80\0E3\0CB\1E\C2\C1\1D\CE\A1\1Cf0\05=\88C8\84\83\1B\CC\03=\C8C=\8C\03=\CCx\8Ctp\07{\08\07yH\87pp\07zp\03vx\87p \87\19\CC\11\0E\EC\90\0E\E10\0Fn0\0F\E3\F0\0E\F0P\0E3\10\C4\1D\DE!\1C\D8!\1D\C2a\1Ef0\89;\BC\83;\D0C9\B4\03<\BC\83<\84\03;\CC\F0\14v`\07{h\077h\87rh\077\80\87p\90\87p`\07v(\07v\F8\05vx\87w\80\87_\08\87q\18\87r\98\87y\98\81,\EE\F0\0E\EE\E0\0E\F5\C0\0E\EC0\03b\C8\A1\1C\E4\A1\1C\CC\A1\1C\E4\A1\1C\DCa\1C\CA!\1C\C4\81\1D\CAa\06\D6\90C9\C8C9\98C9\C8C9\B8\C38\94C8\88\03;\94\C3/\BC\83<\FC\82;\D4\03;\B0\C3\0C\C7i\87pX\87rp\83th\07x`\87t\18\87t\A0\87\19\CES\0F\EE\00\0F\F2P\0E\E4\90\0E\E3@\0F\E1 \0E\ECP\0E3 (\1D\DC\C1\1E\C2A\1E\D2!\1C\DC\81\1E\DC\E0\1C\E4\E1\1D\EA\01\1Ef\18Q8\B0C:\9C\83;\CCP$v`\07{h\077`\87wx\07x\98QL\F4\90\0F\F0P\0E3\1Ej\1E\CAa\1C\E8!\1D\DE\C1\1D~\01\1E\E4\A1\1C\CC!\1D\F0a\06T\85\838\CC\C3;\B0C=\D0C9\FC\C2<\E4C;\88\C3;\B0\03\00y \00\00\22\00\00\00b\1EH C\88\0C\199\19$\90\91@\C6\C8\C8h\22P\08\142\9E\18\19!G\C8\90Q\0C\88T\00\00\A5\00\00\00Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)\00\00\003\04\81\8C\04&(\1566\BB6\974\B227\BAQ\82\00\00\00\00\A9\18\00\00\0B\00\00\00\0B\0Ar(\87w\80\07zXp\98C=\B8\C38\B0C9\D0\C3\82\E6\1C\C6\A1\0D\E8A\1E\C2\C1\1D\E6!\1D\E8!\1D\DE\C1\1D\00a \00\00\1E\00\00\00\13\04A,\10\00\00\00\06\00\00\00T%0\02P\08\A5@8\D4\11\08@q\14\C7P\C7@\04\C5Q\1C\003\11Ea\8C\C2LDQ\18\A30\13Q\14\C6(\0C\1B\10\032\00\C3\06\84p\0C\C0\B0\01\11\18\03@B\0D\12j\98\10\80`\C4\C0\00@\10\0C\92\07\09F\0C\0A\00\04\C1 \81\90lBb\00\00\00\00\02\00\00\00\0B\0E\A0\08\84\818\00\00\00\00\00q \00\00\0D\00\00\00R\0E\10\22d\82\A4\1C D\C8\E4H9@\88\90\A1\8C\05\84\08\D9\80\F1DH3\15*\E0J@0\00\D2X\80\E1KS\E4\D7\06@\F8\D2\14\01\00\00\00\00\00\00\00", section ".llvmbc"
      > @llvm.cmdline = private constant [663 x i8] c"-triple\00x86_64-unknown-linux-gnu\00-emit-llvm-bc\00-emit-llvm-uselists\00-fembed-bitcode=all\00-disable-llvm-passes\00-disable-free\00-disable-llvm-verifier\00-discard-value-names\00-main-file-name\00test.c\00-mrelocation-model\00static\00-mthread-model\00posix\00-mdisable-fp-elim\00-fmath-errno\00-masm-verbose\00-mconstructor-aliases\00-munwind-tables\00-target-cpu\00x86-64\00-dwarf-column-info\00-debugger-tuning=gdb\00-coverage-notes-file\00/home/wangyankun/ollvm/testOClang/test-bitcode.gcno\00-resource-dir\00/mnt/home/wangyankun/ollvm/obuild/bin/../lib/clang/4.0.1\00-fdebug-compilation-dir\00/home/wangyankun/ollvm/testOClang\00-ferror-limit\0019\00-fmessage-length\00114\00-fobjc-runtime=gcc\00-fdiagnostics-show-option\00", section ".llvmcmd"
      > @llvm.compiler.used = appending global [2 x i8*] [i8* getelementptr inbounds ([2424 x i8], [2424 x i8]* @llvm.embedded.module, i32 0, i32 0), i8* getelementptr inbounds ([663 x i8], [663 x i8]* @llvm.cmdline, i32 0, i32 0)], section "llvm.metadata"
      12c12
      < ; Function Attrs: noinline nounwind optnone uwtable
      ---
      > ; Function Attrs: noinline nounwind uwtable
      30c30
      < attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
      ---
      > attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
      33,34c33
      < !llvm.module.flags = !{!0}
      < !llvm.ident = !{!1}
      ---
      > !llvm.ident = !{!0}
      36,37c35
      < !0 = !{i32 1, !"wchar_size", i32 4}
      < !1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"}
      ---
      > !0 = !{!"Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)"}
      

      不同点:

      1. 附加的Bitcode 16进制编码不同
      2. 与不添加-fembed-bitcode编辑比较相同,即llvm.module.flags和llvm.ident不同。
  • Diff .o文件
    因为Diff文件不能比较二进制文件,我们只能比较一下Header和段的区别

    • 不添加-fembed-bitcode参数编译的.o文件比较
      两者具有相同的段和段大小,起始地址和偏移量(除.comment段外)。重要的.test段相同。.comment段为注释段。
    • 添加-fembed-bitcode参数编译的.o文件比较
      官方的clang编译出的.llvmbc段多14C,而.llvmcmd段小B。

五、Bitcode相关介绍

1.编码格式

在Diff使用不使用-fembed-bitcode产生的目标文件时,看到了新增的很多16进制信息,(__LLVM信息),而这些Bitcode信息的编码格式与Bytecode并不相同。Bitcode是按bit存取的,而不是byte(8bits),最大化的利用空间。具体可以参考官方文档;

2.Bitcode兼容性

bitcode的格式目前是一直在变化的,并且无法向前兼容,举例来说Xcode8的编译器无法读取并解析xcode9产生的bitcode。现在最新的编译器已经到了Xcode11。

另外苹果的bitcode格式与社区版LLVM的bitcode有一定差异,但苹果并不会及时开源Xcode最新版编译器的代码,所以如果你使用第三方基于社区版LLVM制作的编译器进行开发,不要尝试开启并提交bitcode到App Store Connect,否则会因为App Store Connect解析不了你的bitcode而被拒。
Xcode9之前通过添加ideplugin使用Ollvm,xcode10之后无法使用添加ideplugin的方法,但添加编译链跑的依然可行 ,但是最新的 Xcode10 通过非官方默认的 Toolchains 编译后的的 ipa 是拒绝提交审核的。因此对于Bitcode和Ollvm要进行鱼和熊掌一样的取舍。

3.Bitcode不是架构无关的代码

如果一个app同时要支持armv7和arm64两种架构,那么同一个源代码文件将会被编译出两份bitcode,也就是说,在一开始介绍LLVM的那张图中,并不是代表同一份bitcode代码可以直接被编译为不同目标机器的机器码。

LLVM只是统一了中间语言的结构和语法格式,但不能像Java那样,Compile Once & Run Everywhere.

4.判断是否开启Bitcode

可以通过otool检查二进制文件,网上有很多类似这样的方法:
otool -arch armv7 -l xxxx.a | grep __LLVM | wc -l

通过判断是否包含 __LLVM 或者关键字来判断是否支持bitcode,其实这种方式是完全错误的,通过前面的测试可以知道,这种方式区分不了bitcode和bitcode-marker,确定是否包含bitcode,还需要检查otool输出中__LLVM Segment 的长度,如果长度只有1个字节,则并不能代表真正开启了bitcode:

$ otool -l test_bitcode.o | grep -A 2  __LLVM | grep size
      size 0x0000000000000b10
      size 0x0000000000000042
$ otool -l test_bitcode_marker.o | grep -A 2  __LLVM | grep size
      size 0x0000000000000001
      size 0x0000000000000001

参考:ollvm快速学习
关于bitcode,知道这些就够了
别动我的代码!聊聊那些代码保护的艺术
[Xcode混淆实战]([https://github.com/huanglins/iOSObfuscator/blob/master/iOS%20%E9%A9%AC%E7%94%B2%E5%8C%85%E3%80%81%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86%E3%80%81%E7%BC%96%E8%AF%91%E6%B7%B7%E6%B7%86%E5%AE%9E%E8%B7%B5.md](https://github.com/huanglins/iOSObfuscator/blob/master/iOS 马甲包、代码混淆、编译混淆实践.md))

LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响LLVM与第三方OLLVM编译器中的Clang编译区别以及对Bitcode的影响 JXNUleo 发布了23 篇原创文章 · 获赞 7 · 访问量 8万+ 私信 关注
上一篇:ORA-01157: cannot identify/lock data file 6 - see DBWR trace file


下一篇:SQL Server AlwaysOn中的几个误区