【发布时间】:2015-05-05 06:36:42
【问题描述】:
我正在尝试在 VS 2013 编译的 Windows 8.1 上运行斐波那契演示。 到目前为止,我解决了几个问题: 1. 不兼容的目标文件格式 - 我在 windows 的函数 getDefaultFormat(const Triple &T) 中将 Triple::COFF 更改为 Triple::ELF 2. 缺少 asm 打印机 - 我添加了 InitializeNativeTargetAsmPrinter() 3. 内存保护 - 我手动将 VirtualProtect 设置为 PAGE_EXECUTE(它没有设置,我不知道它应该如何工作)
现在我可以运行生成的代码,但是它崩溃了,这里是反汇编代码:
000000EC4B890000 推送 rsi
000000EC4B890001 推 rdi
000000EC4B890002 推送 rbx
000000EC4B890003 sub rsp,20h
000000EC4B890007 mov esi,ecx
000000EC4B890009 cmp esi,2
000000EC4B89000C jg 000000EC4B890015
000000EC4B89000E mov eax,1
000000EC4B890013 跳转 000000EC4B89002F
000000EC4B890015 lea ecx,[rsi-1]
000000EC4B890018 mov rbx,0
000000EC4B890022 调用 rbx
000000EC4B890024 mov edi,eax
000000EC4B890026 添加 esi,0FFFFFFFEh
000000EC4B890029 mov ecx,esi
000000EC4B89002B 调用 rbx
000000EC4B89002D 添加 eax,edi
000000EC4B89002F 添加 rsp,20h
000000EC4B890033 弹出 rbx
000000EC4B890034 弹出 rdi
000000EC4B890035 弹出 rsi
000000EC4B890036 ret
在地址 000000EC4B890018 上是指令 mov rbx,0 并在调用 rbx 之后立即导致崩溃。还有一个奇怪的事情,调用堆栈似乎被破坏了,在prologue之后调试器调用堆栈中有没有被调用的函数。
这里是红外:
define i32 @fib(i32 %AnArg) {
EntryBlock:
%cond = icmp sle i32 %AnArg, 2
br i1 %cond, label %return, label %recurse
return: ; preds = %EntryBlock
ret i32 1
recurse: ; preds = %EntryBlock
%arg = sub i32 %AnArg, 1
%fibx1 = tail call i32 @fib(i32 %arg)
%arg1 = sub i32 %AnArg, 2
%fibx2 = tail call i32 @fib(i32 %arg1)
%addresult = add i32 %fibx1, %fibx2
ret i32 %addresult
}
我正在运行 Windows 8.1 专业版 LLVM 使用 VS 2013 社区版在 x64 配置中编译 我正在使用 LLVM 3.6.0
注意:x86 配置有效(发布时解释器除外,它会崩溃)
我错过了什么吗?我应该将 ELF 用于 x64 还是 COFF(我认为它没有在 JIT 中实现)?
我正在开始一个大项目。性能很关键,我想在其中使用一个脚本,但它必须是 jitted。最重要的平台是 Windows、Android 和 iOS。我担心 llvm 对这些平台的 JIT 支持。我知道 llvm 和 clang 在所有这些平台上都被广泛使用,但由于我目前遇到的问题,我对 JIT 不太确定。
【问题讨论】:
-
那么,该函数的 LLVM IR 是什么?