当使用lli运行时,rustc产生的LLVM给出了有关main参数类型的错误 [英] LLVM produced by rustc gives error about argument type of main when run with lli

查看:215
本文介绍了当使用lli运行时,rustc产生的LLVM给出了有关main参数类型的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解一些有关LLVM IR的信息,尤其是确切的rustc输出.即使是一个非常简单的案例,我也遇到了一些麻烦.

I'm trying to learn a little about the LLVM IR, particularly what exactly rustc outputs. I'm having a little bit of trouble running even a very simple case.

我将以下内容放在源文件simple.rs中:

I put the following in a source file simple.rs:

fn main() {
    let x = 7u32;
    let y = x + 2;
}

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

and run rustc --emit llvm-ir simple.rs to get the file simple.ll, containing

; 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}

然后我尝试使用命令运行它

I then try to run this with the command

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的文件,其中包含

I'm able to make a minimal reproduction of this as follows: I make a file called s2.ll, containing

define i32 @main(i64, i8**) {
    ret i32 42
}

并运行lli-3.9 s2.ll会给出相同的错误消息. 但是,如果我将s2.ll的内容更改为

and running lli-3.9 s2.ll gives the same error message. But if I change the contents of s2.ll to

define i32 @main(i32, i8**) {
    ret i32 42
}

(即,我已经更改了main中argc的类型),然后lli-3.9 s2.ll运行,并且echo $?显示它确实返回了42.

(i.e. I've changed the type of argc in main) then lli-3.9 s2.ll runs, and echo $? reveals that it did indeed return 42.

我认为我不必显式地传递i64-我的参数列表或C字符串应放在某个地方的内存中,并且指针和长度会自动传递给main,对吗?因此,我假设我在调用lli时做错了事-但我​​不知道该怎么办.

I don't think I should have to pass in the i64 explicitly - my argument list or C strings should be put into memory somewhere and the pointer and length passed to main automatically, right? Therefore I assume that I'm doing something wrong in the way in invoke lli - but I have no idea what.

推荐答案

Rust将其入口点(标有#[start]属性的功能,默认情况下为标准库中的功能lang_start)标记为采用argc参数键入isize. 这是一个错误,因为它应该具有C int类型,因此在64位平台上,它应该是32位,但是isize是64位.但是,由于64位调用约定的工作方式,这碰巧仍然可以正常工作.返回类型也存在相同的问题.

Rust marks its entry point (the function marked with #[start] attribute, by default the function lang_start in the standard library) as taking an argc parameter of type isize. This is a bug because it should have the type of a C int, so it should be 32 bits on a 64-bit platform, but isize is 64 bits. However, due to the way 64-bit calling conventions work, this happens to still work correctly. The same issue also exists for the return type.

修复于2017年10月1日提交并且应该存在于Rust 1.22中.

A fix for this has been committed on 2017-10-01 and should be present in Rust 1.22.

lli显然在检查main的类型方面更加严格,这就是为什么会给出错误的原因.但是,如果改用llc,它应该可以正常工作.

lli is apparently more strict about checking the type of main which is why it gives the error. But if you use llc instead, it should work correctly.

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

To get the correct main signature, you can cancel the default main by putting #![no_main] at the top of the module, and provide your own main marked with #[no_mangle]. But note that this will skip the standard library's initialization.

#![no_main]

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

另请参阅:

  • documentation about lang_items and disabling main
  • Tracking issue for #[start] feature, where some people mention isize not being correct.

这篇关于当使用lli运行时,rustc产生的LLVM给出了有关main参数类型的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆