我试图打电话printf
给从LLVM打印一个浮点数。虽然可以正常使用int
,但在使用时会出现段错误double
。
这是代码(从clang生成,但稍作修改,使其可以与一起正常工作llc
):
@.str = private unnamed_addr constant [3 x i8] c"%f\00", align 1
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
store i32 0, i32* %1
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), double 3.140000e+00)
ret i32 0
}
declare i32 @printf(i8*, ...) #1
attributes #0 = { nounwind uwtable "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" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "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" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
这是我生成可执行文件的方式:
llc main.ll --filetype=obj
ld -lc -e main -dynamic-linker /lib64/ld-linux-x86-64.so.2 main.o -o main
当我运行main
中valgrind
,我得到:
Process terminating with default action of signal 11 (SIGSEGV): dumping core
General Protection Fault
我在该站点的某处读到了需要对齐堆栈才能使用的信息printf
。如果这是问题,我该如何在LLVM中做到这一点。
否则,造成此段错误的原因是什么?
我运行Linux 64位。
这不是llvm问题。你跑的时候
llc main.ll --filetype=obj
ld -lc -e main -dynamic-linker /lib64/ld-linux-x86-64.so.2 main.o -o main
在创建objact文件main.o之后,您要尝试链接它,说main是其执行的入口点,这是不正确的。
从c程序员的角度来看,main是执行程序时的入口点,而没有执行,编译器添加了一些额外的启动代码_start,这是先执行的函数,然后interns调用main函数。
启动代码是可重定位的对象,并且它们由编译器传递给链接器。搜索crti.o crtn.o和crt1.o,printf函数也位于库libc.so/libc.a中,您需要在链接时提供它。
如果您想要简单的解决方案,请使用gcc将目标文件转换为可执行文件
gcc main.o -o main
您也可以在这里查看更多说明,请参见http://blog.techveda.org/building-executables-with-gnu-linker/
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句