首先先贴一个LLVM安装的教程:
原文地址:
http://thread.gmane.org/gmane.comp.compilers.llvm.klee/923
打不开就用:
http://blog.csdn.net/happygogf/article/details/17528059
这个文章整合了klee和llvm的安装,由于这两个软件都要用到,所以这样装上之后问题比较少。如果直接安装llvm,会造成一大堆乱七八糟的错误,特别是找不到一些lib,也有可能是我安装的方法不对?
使用的帖子:
虽然是个台湾的帖子,但是是我看到的llvm使用分析的最全面的了。也有可能因为墙的原因,没有看到国外的一些帖子。其中稍微有点区别,文章里使用的clang,但是我一般使用llvm-gcc,在高版本的llvm里已经没有llvm-gcc了,因为要使用klee,klee限制了llvm的版本,所以还能使用llvm-gcc。
下面的命令用了有一段时日了,下次试一下确认一下如果有错再来编辑原文吧(果然有更新,修改一次)。
利用llvm-gcc很容易得到中间码IR:
llvm-gcc -emit-llvm -c hello.c -o hello.bc (先编译二进制码)
llvm-dis hello.bc (llvm-dis出来的就是IR)
好像llvm-gcc -S -emit-llvm test.c -o test.ll 也是中间码。 .ll的后缀是中间码
利用objdump可以得到机器码:
objdump -S test.o (这里的-S一定是大写)
更新:以上命令其实都在绕弯子,果然当时没有吃透。但是也能用。
生成二进制(汇编): llvm-gcc -S test.c -o test 可以增加参数用于生成INTEL格式的汇编。
llvm-dis 可以将llvm二进制码转换为中间码,而llvm-as则是相反的。
当利用 llvm-gcc -c -emit-llvm test.c -o test生成test之后,可以利用llvm-dis转换为中间码。
下面放一个例子:
源代码test2.c:
int func(int a,int b){ char var[128]="A"; a=0x4455; b=0x6677; return a+b; } int main(){ func(0x8899,0x1100); return 0; }
中间码IR:
; ModuleID = 'test2.bc' target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-f128:128:128-n8:16:32" target triple = "i386-pc-linux-gnu" @.str = private unnamed_addr constant [128 x i8] c"A\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 1 define i32 @func(i32 %a, i32 %b) nounwind { entry: %a_addr = alloca i32, align 4 %b_addr = alloca i32, align 4 %retval = alloca i32 %0 = alloca i32 %var = alloca [128 x i8] %"alloca point" = bitcast i32 0 to i32 store i32 %a, i32* %a_addr store i32 %b, i32* %b_addr %var1 = bitcast [128 x i8]* %var to i8* call void @llvm.memcpy.p0i8.p0i8.i32(i8* %var1, i8* getelementptr inbounds ([128 x i8]* @.str, i32 0, i32 0), i32 128, i32 1, i1 false) store i32 17493, i32* %a_addr, align 4 store i32 26231, i32* %b_addr, align 4 %1 = load i32* %a_addr, align 4 %2 = load i32* %b_addr, align 4 %3 = add nsw i32 %1, %2 store i32 %3, i32* %0, align 4 %4 = load i32* %0, align 4 store i32 %4, i32* %retval, align 4 br label %return return: ; preds = %entry %retval2 = load i32* %retval ret i32 %retval2 } declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind define i32 @main() nounwind { entry: %retval = alloca i32 %0 = alloca i32 %"alloca point" = bitcast i32 0 to i32 %1 = call i32 @func(i32 34969, i32 4352) nounwind store i32 0, i32* %0, align 4 %2 = load i32* %0, align 4 store i32 %2, i32* %retval, align 4 br label %return return: ; preds = %entry %retval1 = load i32* %retval ret i32 %retval1 }