删除内联 mips 程序集中附加的 "break" 指令
Removing appended "break" instruction in inline mips assembly
我有以下(简化的)函数,使用内联汇编,针对 mips:
#[naked]
pub unsafe extern "C" fn test() {
asm!(
".set noreorder",
"jr $ra",
"li $v0, 0x123",
options(noreturn),
)
}
我希望它只编译成 2 条指定的指令(在发布模式下),因为它是一个裸函数,但最后附加了一条 break
指令:
00000000 <test>:
0: 03e00008 jr ra
4: 24020123 li v0,291
8: 0000000d break
我假设这是针对 rustc 或 llvm 未定义行为的对策,但我需要生成我在函数中指定的确切程序集。
有什么方法可以防止 rustc、llvm 或汇编器生成这条额外指令吗?
我在 mipsel-unknown-none
等现有目标上对其进行了测试,它还生成了 break
指令,但如果重要的话,我正在对以下自定义目标进行编译:
{
"arch": "mips",
"cpu": "mips1",
"data-layout": "e-m:m-p:32:32-i8:8:32-i16:16:32-i32:32-n32-S32",
"emit-debug-gdb-scripts": false,
"executables": false,
"features": "+mips32,+soft-float,+noabicalls",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-target": "mipsel-unknown-linux-gnu",
"relocation-model": "static",
"target-pointer-width": "32",
"panic-strategy": "abort",
"singlethread": true,
"dynamic-linking": false,
"function-sections": true
}
我还使用了 #![no_std]
和 #![no_core]
staticlib
箱子,实现了所需的 lang 项,并使用 cargo build --release --target=my-target.json
进行简单编译
编辑:根据 Peter Cordes 的建议,我在 C 中尝试了同样的方法
__attribute__((naked)) void test() {
__asm__(
".set noreorder\n"
"jr $ra\n"
"li $v0, 0x123\n"
);
}
编译使用
clang -O3 test.c -c -o test.o -target mips-unknown-none
结果是
00000000 <test>:
0: 03e00008 jr ra
4: 24020123 li v0,291
没有 break
,所以它似乎被 rust 编译器包含了。
是的!执行以下操作之一:
- 将
"trap_unreachable": false
添加到您的 target.json
- 使用
RUSTFLAGS=-Ztrap-unreachable=no
构建。 (但仅限夜间)
不幸的是,它没有很好的记录。延伸阅读:PR where the trap instruction generation was added PR where trap-unreachable=no was added
我有以下(简化的)函数,使用内联汇编,针对 mips:
#[naked]
pub unsafe extern "C" fn test() {
asm!(
".set noreorder",
"jr $ra",
"li $v0, 0x123",
options(noreturn),
)
}
我希望它只编译成 2 条指定的指令(在发布模式下),因为它是一个裸函数,但最后附加了一条 break
指令:
00000000 <test>:
0: 03e00008 jr ra
4: 24020123 li v0,291
8: 0000000d break
我假设这是针对 rustc 或 llvm 未定义行为的对策,但我需要生成我在函数中指定的确切程序集。
有什么方法可以防止 rustc、llvm 或汇编器生成这条额外指令吗?
我在 mipsel-unknown-none
等现有目标上对其进行了测试,它还生成了 break
指令,但如果重要的话,我正在对以下自定义目标进行编译:
{
"arch": "mips",
"cpu": "mips1",
"data-layout": "e-m:m-p:32:32-i8:8:32-i16:16:32-i32:32-n32-S32",
"emit-debug-gdb-scripts": false,
"executables": false,
"features": "+mips32,+soft-float,+noabicalls",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-target": "mipsel-unknown-linux-gnu",
"relocation-model": "static",
"target-pointer-width": "32",
"panic-strategy": "abort",
"singlethread": true,
"dynamic-linking": false,
"function-sections": true
}
我还使用了 #![no_std]
和 #![no_core]
staticlib
箱子,实现了所需的 lang 项,并使用 cargo build --release --target=my-target.json
编辑:根据 Peter Cordes 的建议,我在 C 中尝试了同样的方法
__attribute__((naked)) void test() {
__asm__(
".set noreorder\n"
"jr $ra\n"
"li $v0, 0x123\n"
);
}
编译使用
clang -O3 test.c -c -o test.o -target mips-unknown-none
结果是
00000000 <test>:
0: 03e00008 jr ra
4: 24020123 li v0,291
没有 break
,所以它似乎被 rust 编译器包含了。
是的!执行以下操作之一:
- 将
"trap_unreachable": false
添加到您的 target.json - 使用
RUSTFLAGS=-Ztrap-unreachable=no
构建。 (但仅限夜间)
不幸的是,它没有很好的记录。延伸阅读:PR where the trap instruction generation was added PR where trap-unreachable=no was added