I have the following (simplified) function using inline assembly, targeting mips:
#[naked]
pub unsafe extern "C" fn test() {
asm!(
".set noreorder",
"jr $ra",
"li $v0, 0x123",
options(noreturn),
)
}
I expected this to compile into just the 2 specified instructions (in release mode), as it's a naked function, but a break
instruction gets appended at the end:
00000000 <test>:
0: 03e00008 jr ra
4: 24020123 li v0,291
8: 0000000d break
I assume this is a countermeasure against undefined behavior by either rustc or llvm, but I need to product the exact assembly I specify in the function.
Is there any way to prevent either rustc, llvm or the assembler from generating this extra instruction generally?
I tested it on existing targets such as mipsel-unknown-none
and it also produced a break
instruction, but I am compiling on the following custom target, if it matters:
{
"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
}
I'm also using a #![no_std]
and #![no_core]
staticlib
crate with the required lang items implemented and simply compiling using cargo build --release --target=my-target.json
Edit: After Peter Cordes's suggestion, I tried the same in C with
__attribute__((naked)) void test() {
__asm__(
".set noreorder\n"
"jr $ra\n"
"li $v0, 0x123\n"
);
}
Compiled using
clang -O3 test.c -c -o test.o -target mips-unknown-none
And the result is
00000000 <test>:
0: 03e00008 jr ra
4: 24020123 li v0,291
Without a break
, so it seems it was included by the rust compiler.
Yes! Do one of:
"trap_unreachable": false
to your target.jsonRUSTFLAGS=-Ztrap-unreachable=no
. (nightly-only though)Unfortunately it's not very well documented. Further reading: PR where the trap instruction generation was added PR where trap-unreachable=no was added