LLVM生成中间码以及汇编代码
首先先贴一个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 }
汇编码:
test2.o: 文件格式 elf32-i386 Disassembly of section .text: 00000000 <func>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 81 ec a8 00 00 00 sub $0xa8,%esp 9: 8b 45 0c mov 0xc(%ebp),%eax c: 8b 4d 08 mov 0x8(%ebp),%ecx f: 8d 95 70 ff ff ff lea -0x90(%ebp),%edx 15: 89 4d fc mov %ecx,-0x4(%ebp) 18: 89 45 f8 mov %eax,-0x8(%ebp) 1b: 89 e0 mov %esp,%eax 1d: 89 10 mov %edx,(%eax) 1f: c7 40 08 80 00 00 00 movl $0x80,0x8(%eax) 26: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) 2d: e8 fc ff ff ff call 2e <func+0x2e> 32: c7 45 fc 55 44 00 00 movl $0x4455,-0x4(%ebp) 39: c7 45 f8 77 66 00 00 movl $0x6677,-0x8(%ebp) 40: 8b 45 fc mov -0x4(%ebp),%eax 43: 03 45 f8 add -0x8(%ebp),%eax 46: 89 45 f0 mov %eax,-0x10(%ebp) 49: 8b 45 f0 mov -0x10(%ebp),%eax 4c: 89 45 f4 mov %eax,-0xc(%ebp) 4f: 8b 45 f4 mov -0xc(%ebp),%eax 52: 81 c4 a8 00 00 00 add $0xa8,%esp 58: 5d pop %ebp 59: c3 ret 5a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 00000060 <main>: 60: 55 push %ebp 61: 89 e5 mov %esp,%ebp 63: 83 ec 28 sub $0x28,%esp 66: b8 99 88 00 00 mov $0x8899,%eax 6b: b9 00 11 00 00 mov $0x1100,%ecx 70: c7 04 24 99 88 00 00 movl $0x8899,(%esp) 77: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) 7e: 00 7f: 89 45 f4 mov %eax,-0xc(%ebp) 82: 89 4d f0 mov %ecx,-0x10(%ebp) 85: e8 fc ff ff ff call 86 <main+0x26> 8a: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) 91: 8b 4d f8 mov -0x8(%ebp),%ecx 94: 89 4d fc mov %ecx,-0x4(%ebp) 97: 89 45 ec mov %eax,-0x14(%ebp) 9a: 8b 45 fc mov -0x4(%ebp),%eax 9d: 83 c4 28 add $0x28,%esp a0: 5d pop %ebp a1: c3 ret