带有 LLVM 段错误的 Printf 浮动

Printf float with LLVM segfaults

我正在尝试调用 printf 从 LLVM 打印一个浮点数。虽然它与 int 一起工作正常,但在使用 double.

时会出现段错误

这是代码(从 clang 生成但稍作修改,以便它可以与 llc 一起正常工作):

@.str = private unnamed_addr constant [3 x i8] c"%f[=10=]", 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

当我 运行 mainvalgrind 内时,我得到:

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

这里在创建目标文件后 main.o 你试图 link 它说 main 是它的执行入口点,这是不正确的。

从c程序员的角度来看,main是我们程序的入口点,而执行不是,编译器添加了一些额外的启动代码,即_start,这是先执行然后实习生调用的函数主要功能。

启动代码是可重定位对象,由编译器传递给 linker。搜索 crti.o crtn.o 和 crt1.o,printf 函数也在库 libc.so/libc.a 中,您需要在 linking.

如果您想要简单的解决方案,请使用 gcc 将目标文件转换为可执行文件

gcc main.o -o main

您也可以在这里查看更多说明, 参考 http://blog.techveda.org/building-executables-with-gnu-linker/