LLVM代码生成导致seg错误?

时间:2010-08-09 12:50:24

标签: llvm

我对语言创建和编译器构造很感兴趣,并且已经在这里通过示例进行了研究:http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/。作者使用的是LLVM 2.6,在对LLVM 2.7进行了一些更改后,我得到了所有代码生成代码进行编译。当给编译器输入测试代码时,

int do_math( int a ) {
  int x = a * 5 + 3
}

do_math( 10 )

程序正常工作,直到它尝试运行代码,此时它会出现段错误。我正在我的系统上构建LLDB,但与此同时,任何人都会在此LLVM中看到明显的seg错误?

; ModuleID = 'main'

define internal void @main() {
entry:
  %0 = call i64 @do_math(i64 10)                  ; <i64> [#uses=0]
  ret void
}

define internal i64 @do_math(i64) {
entry:
  %a = alloca i64                                 ; <i64*> [#uses=1]
  %x = alloca i64                                 ; <i64*> [#uses=1]
  %1 = add i64 5, 3                               ; <i64> [#uses=1]
  %2 = load i64* %a                               ; <i64> [#uses=1]
  %3 = mul i64 %2, %1                             ; <i64> [#uses=1]
  store i64 %3, i64* %x
  ret void
}

输出只是:

Segmentation fault

我的主题是OS X x86_64。

感谢。

2 个答案:

答案 0 :(得分:16)

我遇到了同样的问题。我删除了Loren的编译器,除了执行之外,一切正常。

分段错误是由以下事实引起的:

  

ExecutionEngine * ee = EngineBuilder(module).create();

返回NULL。要查看实际错误,您需要获取错误字符串:

  

std :: string错误;   ExecutionEngine * ee = EngineBuilder(module).setErrorStr(&amp; error).create();

在你的情况下你应该看到:

  

“无法找到此三联的目标(未注册任何目标)

要解决此问题,您需要致电

  

InitializeNativeTarget();

但如果你得到:

  

JIT尚未被链接。

你应该包括:

  

LLVM / ExecutionEngine / MCJIT.h

将链接JIT引擎。

答案 1 :(得分:0)

您发布的LLVM ASM不是您提供的C代码的正确翻译。您将%a分配为堆栈变量,然后从中加载未初始化的数据并使用它。您想要做的是命名您的参数%a并使用该值。请尝试使用此代码:

define internal i64 @do_math(i64 %a) {
entry:
  %x = alloca i64                                 ; <i64*> [#uses=1]
  %1 = add i64 5, 3                               ; <i64> [#uses=1]
  %2 = mul i64 %a, %1                             ; <i64> [#uses=1]
  store i64 %2, i64* %x
  ret void
}

此外,您的main()原型可能与C运行时库所期望的不匹配。而且,除此之外,您确实意识到您没有从do_math()返回结果,对吧?