首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rustc生成的LLVM在lli运行时给出了main参数类型的错误。

rustc生成的LLVM在lli运行时给出了main参数类型的错误。
EN

Stack Overflow用户
提问于 2017-08-24 06:09:27
回答 1查看 371关注 0票数 5

我试着学习一些关于LLVM IR的知识,特别是什么是rustc的输出。即使是一个很简单的案子我也有点麻烦。

我将以下内容放入源文件simple.rs

代码语言:javascript
复制
fn main() {
    let x = 7u32;
    let y = x + 2;
}

并运行rustc --emit llvm-ir simple.rs以获取文件simple.ll,其中包含

代码语言:javascript
复制
; 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}

然后,我尝试使用以下命令来运行这个

代码语言:javascript
复制
lli-3.9 -load ~/.multirust/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-35ad9950c7e5074b.so simple.ll

但是我得到了错误信息

代码语言:javascript
复制
LLVM ERROR: Invalid type for first argument of main() supplied

我能够按照以下方式进行最小复制:我创建了一个名为s2.ll的文件,其中包含

代码语言:javascript
复制
define i32 @main(i64, i8**) {
    ret i32 42
}

运行lli-3.9 s2.ll会提供相同的错误消息。但是如果我将s2.ll的内容更改为

代码语言:javascript
复制
define i32 @main(i32, i8**) {
    ret i32 42
}

(也就是说,我在main中更改了argc的类型),然后lli-3.9 s2.ll运行,echo $?显示它确实返回了42

我不认为我应该显式地传递i64 --我的参数列表或C字符串应该放在内存中,指针和长度自动传递给main,对吗?因此,我假设我在调用lli时做错了什么--但我不知道是什么。

EN

回答 1

Stack Overflow用户

发布于 2017-08-24 11:10:05

锈蚀将其入口点(标记为#[start]属性的函数,默认为标准库中的函数lang_start )标记为接受isize类型的argc参数。这是个小虫子,因为它应该具有bits的类型,所以在64位平台上应该是32位,但是isize是64位。然而,由于64位调用约定的工作方式,这碰巧仍然正确工作。返回类型也存在同样的问题。

固定物已于2017-10-01承诺,并应出现在锈菌1.22中.

lli显然更严格地检查main的类型,这就是为什么它会给出错误。但是,如果您使用的是llc,那么它应该可以正常工作。

要获得正确的main签名,可以取消默认的main,方法是将#![no_main]放在模块的顶部,并提供自己的带有#[no_mangle]标记的main。但是请注意,这将跳过标准库的初始化。

代码语言:javascript
复制
#![no_main]

#[no_mangle]
pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
    0
}

另请参阅:

  • main
  • 功能,有些人提到isize是不正确的。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45854134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档