我正在尝试学习一些关于LLVM IR的知识,特别是什么是rustc输出.即使是一个非常简单的案例,我也遇到了一些麻烦.
我将以下内容放在源文件中simple.rs:
fn main() {
let x = 7u32;
let y = x + 2;
}
Run Code Online (Sandbox Code Playgroud)
并运行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}
Run Code Online (Sandbox Code Playgroud)
然后我尝试用命令运行它
lli-3.9 -load ~/.multirust/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-35ad9950c7e5074b.so simple.ll
Run Code Online (Sandbox Code Playgroud)
但我收到错误信息
LLVM ERROR: Invalid type for first argument of main() supplied
Run Code Online (Sandbox Code Playgroud)
我可以按如下方式对其进行最小化的再现:我创建一个名为的文件s2.ll,包含
define i32 @main(i64, i8**) {
ret i32 42
}
Run Code Online (Sandbox Code Playgroud)
并且运行lli-3.9 s2.ll给出相同的错误消息.但是,如果我将内容更改s2.ll为
define i32 @main(i32, i8**) {
ret i32 42
}
Run Code Online (Sandbox Code Playgroud)
(即我改变了argc主要的类型)然后lli-3.9 s2.ll运行,并echo $?揭示它确实返回42.
我不认为我应该i64明确传入- 我的参数列表或C字符串应该放在内存中,指针和长度main自动传递给对,对吗?因此我假设我在调用方式上做错了lli- 但我不知道是什么.
Rust将其入口点(标记为#[start]属性的函数,默认情况下lang_start标准库中的函数)标记为采用类型的argc参数isize.这是一个错误,因为它应该具有C int类型,因此它应该是64位平台上的32位,但是isize64位.但是,由于64位调用约定的工作方式,这种情况仍然可以正常工作.返回类型也存在同样的问题.
修复此问题已在2017-10-01进行,并且应该出现在Rust 1.22中.
lli显然更严格的是检查它的类型main是它给出错误的原因.但是如果你使用llc它,它应该正常工作.
要获得正确的main签名,您可以main通过放置#![no_main]在模块的顶部来取消默认签名,并提供您自己的main标记#[no_mangle].但请注意,这将跳过标准库的初始化.
#![no_main]
#[no_mangle]
pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
0
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
lang_items和禁用的文档main#[start]功能的问题,有些人提到isize不正确.