【发布时间】:2017-08-24 06:09:27
【问题描述】:
我正在尝试了解一些有关 LLVM IR 的知识,尤其是 rustc 的输出。即使是一个非常简单的案例,我也遇到了一些麻烦。
我将以下内容放入源文件simple.rs:
fn main() {
let x = 7u32;
let y = x + 2;
}
并运行rustc --emit llvm-ir simple.rs 获取文件simple.ll,包含
; ModuleID = 'simple.cgu-0.rs'
source_filename = "simple.cgu-0.rs"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: uwtable
define internal void @_ZN6simple4main17h8ac50d7470339b75E() unnamed_addr #0 {
start:
br label %bb1
bb1: ; preds = %start
ret void
}
define i64 @main(i64, i8**) unnamed_addr {
top:
%2 = call i64 @_ZN3std2rt10lang_start17ha09816a4e25587eaE(void ()* @_ZN6simple4main17h8ac50d7470339b75E, i64 %0, i8** %1)
ret i64 %2
}
declare i64 @_ZN3std2rt10lang_start17ha09816a4e25587eaE(void ()*, i64, i8**) unnamed_addr
attributes #0 = { uwtable }
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"PIE Level", i32 2}
然后我尝试使用命令运行它
lli-3.9 -load ~/.multirust/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-35ad9950c7e5074b.so simple.ll
但我收到错误消息
LLVM ERROR: Invalid type for first argument of main() supplied
我可以对此进行最小复制,如下所示:我制作了一个名为 s2.ll 的文件,其中包含
define i32 @main(i64, i8**) {
ret i32 42
}
并运行lli-3.9 s2.ll 会给出相同的错误消息。 但是如果我把s2.ll的内容改成
define i32 @main(i32, i8**) {
ret i32 42
}
(即我在 main 中更改了 argc 的类型)然后运行 lli-3.9 s2.ll,echo $? 显示它确实返回了 42。
我认为我不应该显式传递i64 - 我的参数列表或C 字符串应该被放入内存中的某个地方,并且指针和长度自动传递给main,对吗?因此,我假设我在调用 lli 的方式上做错了 - 但我不知道是什么。
【问题讨论】: