我正在玩LLVM IR,并且我无法解决(在google和doc的帮助下)LLVM解释器lli
正在寻找外部函数(没有明确定义的函数。意味着基本的系统功能)。例如,如果我想写出没有依赖简单的程序,在Linux上,这将写在屏幕上的东西,我可以做这样的事情:LLVM解释器在寻找外部函数(库?)
@message = private constant [12 x i8] c"hello world\0A"
define i32 @puts(i8* %s) {
call i32 asm sideeffect "movl $$0x2, %edi\0Amovl $$0xC, %edx\0Amovl$$1, %eax\0Asyscall\0A", "=A,{si}"(i8* %s) #1
ret i32 %1
}
define void @exit(i32 %c) {
call i32 asm sideeffect "movl $$60, %eax\0Asyscall\0A", "=A,{di}"(i32 %c) #1
ret void
}
define void @main() {
getelementptr [12 x i8], [12 x i8]* @message, i64 0, i64 0
call i32 @puts(i8* %1)
call void @exit(i32 0)
ret void
}
define void @_start() {
call void @main()
ret void
}
main
和_start
是与ld
和lli
交叉兼容性。所以上面的代码在两者中都是一样的我可以lli
这个,并且代码将从main
或llc
然后ld
开始,它也会工作,因此代码将从_start
按预期开始。现在,如果我写的代码:
@formatString = private constant [4 x i8] c"%d\0A\00"
declare i32 @printf(i8*, ...)
define i32 @main() {
%d = shl i32 2, 3
%s = getelementptr [4 x i8], [4 x i8]* @formatString, i64 0, i64 0
%call = call i32 (i8*, ...) @printf(i8* %s, i32 %d)
ret i32 0
}
它也适用于lli
,但我不能ld
,因为ld
不知道参考printf
这也在意料之中。我可以包括准备ld
参数以使代码也起作用,或者干脆使用gcc file.o -o file
,但这不是我的观点。我的意思是如何让lli
不包含任何外部库(如libc),只运行我的代码,并可能定义我自己的入口点,所以我可以随意包含任何准备好的libc
或任何其他库,我知道我可以覆盖功能的名称,并应该工作,但后来我不知道什么被重写,所以我会很高兴,如果lli
抛出错误,如果printf
被使用但未定义。或者,也许我错了,lli
无法在这样的环境中执行。
我发现'lli -entry-function = _start file.ll'可以选择任何入口点。但仍不知道如何去除预装代码的解释器。有选项'-extra-object =