Skip to content

Commit 8c70312

Browse files
committed
Use stable #[naked] instead of global_asm!() fallback
#[naked] is stable since Rust 1.79, and origin already requires 1.88. This removes the global_asm!() fallback and the naked_fn! macro entirely, inlining #[naked] directly at each call site. Signal handlers don't need #[no_mangle] since they're passed by address.
1 parent 10258f1 commit 8c70312

File tree

7 files changed

+187
-275
lines changed

7 files changed

+187
-275
lines changed

src/arch/aarch64.rs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,28 @@ use {
2222
rustix::thread::RawPid,
2323
};
2424

25+
/// The program entry point.
26+
///
27+
/// # Safety
28+
///
29+
/// This function must never be called explicitly. It is the first thing
30+
/// executed in the program, and it assumes that memory is laid out according
31+
/// to the operating system convention for starting a new program.
2532
#[cfg(feature = "origin-start")]
26-
naked_fn!(
27-
"
28-
The program entry point.
29-
30-
# Safety
31-
32-
This function must never be called explicitly. It is the first thing
33-
executed in the program, and it assumes that memory is laid out according
34-
to the operating system convention for starting a new program.
35-
";
36-
pub(super) fn _start() -> !;
37-
33+
#[unsafe(naked)]
34+
#[unsafe(no_mangle)]
35+
pub(super) unsafe extern "C" fn _start() -> ! {
3836
// Jump to `entry`, passing it the initial stack pointer value as an
3937
// argument, a null return address, a null frame pointer, and an aligned
4038
// stack pointer. On many architectures, the incoming frame pointer is
4139
// already null.
42-
"mov x0, sp", // Pass the incoming `sp` as the arg to `entry`.
43-
"mov x30, xzr", // Set the return address to zero.
44-
"b {entry}"; // Jump to `entry`.
45-
entry = sym super::program::entry
46-
);
40+
core::arch::naked_asm!(
41+
"mov x0, sp", // Pass the incoming `sp` as the arg to `entry`.
42+
"mov x30, xzr", // Set the return address to zero.
43+
"b {entry}", // Jump to `entry`.
44+
entry = sym super::program::entry
45+
)
46+
}
4747

4848
/// Execute a trap instruction.
4949
///
@@ -300,25 +300,24 @@ pub(super) unsafe fn munmap_and_exit_thread(map_addr: *mut c_void, map_len: usiz
300300
}
301301
}
302302

303+
/// Invoke the `__NR_rt_sigreturn` system call to return control from a signal
304+
/// handler.
305+
///
306+
/// # Safety
307+
///
308+
/// This function must never be called other than by the `sa_restorer`
309+
/// mechanism.
303310
#[cfg(feature = "take-charge")]
304311
#[cfg(feature = "signal")]
305-
naked_fn!(
306-
"
307-
Invoke the `__NR_rt_sigreturn` system call to return control from a signal
308-
handler.
309-
310-
# Safety
311-
312-
This function must never be called other than by the `sa_restorer`
313-
mechanism.
314-
";
315-
pub(super) fn return_from_signal_handler() -> ();
316-
317-
"mov x8, {__NR_rt_sigreturn}",
318-
"svc 0",
319-
"udf #16";
320-
__NR_rt_sigreturn = const __NR_rt_sigreturn
321-
);
312+
#[unsafe(naked)]
313+
pub(super) unsafe extern "C" fn return_from_signal_handler() {
314+
core::arch::naked_asm!(
315+
"mov x8, {__NR_rt_sigreturn}",
316+
"svc 0",
317+
"udf #16",
318+
__NR_rt_sigreturn = const __NR_rt_sigreturn
319+
)
320+
}
322321

323322
/// Invoke the appropriate system call to return control from a signal
324323
/// handler that does not use `SA_SIGINFO`. On aarch64, this uses the same

src/arch/arm.rs

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,28 @@ use {
2222
rustix::thread::RawPid,
2323
};
2424

25+
/// The program entry point.
26+
///
27+
/// # Safety
28+
///
29+
/// This function must never be called explicitly. It is the first thing
30+
/// executed in the program, and it assumes that memory is laid out according
31+
/// to the operating system convention for starting a new program.
2532
#[cfg(feature = "origin-start")]
26-
naked_fn!(
27-
"
28-
The program entry point.
29-
30-
# Safety
31-
32-
This function must never be called explicitly. It is the first thing
33-
executed in the program, and it assumes that memory is laid out according
34-
to the operating system convention for starting a new program.
35-
";
36-
pub(super) fn _start() -> !;
37-
33+
#[unsafe(naked)]
34+
#[unsafe(no_mangle)]
35+
pub(super) unsafe extern "C" fn _start() -> ! {
3836
// Jump to `entry`, passing it the initial stack pointer value as an
3937
// argument, a null return address, a null frame pointer, and an aligned
4038
// stack pointer. On many architectures, the incoming frame pointer is
4139
// already null.
42-
"mov r0, sp", // Pass the incoming `sp` as the arg to `entry`.
43-
"mov lr, #0", // Set the return address to zero.
44-
"b {entry}"; // Jump to `entry`.
45-
entry = sym super::program::entry
46-
);
40+
core::arch::naked_asm!(
41+
"mov r0, sp", // Pass the incoming `sp` as the arg to `entry`.
42+
"mov lr, #0", // Set the return address to zero.
43+
"b {entry}", // Jump to `entry`.
44+
entry = sym super::program::entry
45+
)
46+
}
4747

4848
/// Execute a trap instruction.
4949
///
@@ -314,42 +314,40 @@ pub(super) unsafe fn munmap_and_exit_thread(map_addr: *mut c_void, map_len: usiz
314314
}
315315
}
316316

317+
/// Invoke the `__NR_rt_sigreturn` system call to return control from a signal
318+
/// handler.
319+
///
320+
/// # Safety
321+
///
322+
/// This function must never be called other than by the `sa_restorer`
323+
/// mechanism.
317324
#[cfg(feature = "take-charge")]
318325
#[cfg(feature = "signal")]
319-
naked_fn!(
320-
"
321-
Invoke the `__NR_rt_sigreturn` system call to return control from a signal
322-
handler.
323-
324-
# Safety
325-
326-
This function must never be called other than by the `sa_restorer`
327-
mechanism.
328-
";
329-
pub(super) fn return_from_signal_handler() -> ();
330-
331-
"mov r7, {__NR_rt_sigreturn}",
332-
"swi 0",
333-
"udf #16";
334-
__NR_rt_sigreturn = const __NR_rt_sigreturn
335-
);
326+
#[unsafe(naked)]
327+
pub(super) unsafe extern "C" fn return_from_signal_handler() {
328+
core::arch::naked_asm!(
329+
"mov r7, {__NR_rt_sigreturn}",
330+
"swi 0",
331+
"udf #16",
332+
__NR_rt_sigreturn = const __NR_rt_sigreturn
333+
)
334+
}
336335

336+
/// Invoke the appropriate system call to return control from a signal
337+
/// handler that does not use `SA_SIGINFO`.
338+
///
339+
/// # Safety
340+
///
341+
/// This function must never be called other than by the `sa_restorer`
342+
/// mechanism.
337343
#[cfg(feature = "take-charge")]
338344
#[cfg(feature = "signal")]
339-
naked_fn!(
340-
"
341-
Invoke the appropriate system call to return control from a signal
342-
handler that does not use `SA_SIGINFO`.
343-
344-
# Safety
345-
346-
This function must never be called other than by the `sa_restorer`
347-
mechanism.
348-
";
349-
pub(super) fn return_from_signal_handler_noinfo() -> ();
350-
351-
"mov r7, {__NR_sigreturn}",
352-
"swi 0",
353-
"udf #16";
354-
__NR_sigreturn = const __NR_sigreturn
355-
);
345+
#[unsafe(naked)]
346+
pub(super) unsafe extern "C" fn return_from_signal_handler_noinfo() {
347+
core::arch::naked_asm!(
348+
"mov r7, {__NR_sigreturn}",
349+
"swi 0",
350+
"udf #16",
351+
__NR_sigreturn = const __NR_sigreturn
352+
)
353+
}

src/arch/riscv64.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,29 @@ use {
1919
rustix::thread::RawPid,
2020
};
2121

22+
/// The program entry point.
23+
///
24+
/// # Safety
25+
///
26+
/// This function must never be called explicitly. It is the first thing
27+
/// executed in the program, and it assumes that memory is laid out according
28+
/// to the operating system convention for starting a new program.
2229
#[cfg(feature = "origin-start")]
23-
naked_fn!(
24-
"
25-
The program entry point.
26-
27-
# Safety
28-
29-
This function must never be called explicitly. It is the first thing
30-
executed in the program, and it assumes that memory is laid out according
31-
to the operating system convention for starting a new program.
32-
";
33-
pub(super) fn _start() -> !;
34-
30+
#[unsafe(naked)]
31+
#[unsafe(no_mangle)]
32+
pub(super) unsafe extern "C" fn _start() -> ! {
3533
// Jump to `entry`, passing it the initial stack pointer value as an
3634
// argument, a null return address, a null frame pointer, and an aligned
3735
// stack pointer. On many architectures, the incoming frame pointer is
3836
// already null.
39-
"mv a0, sp", // Pass the incoming `sp` as the arg to `entry`.
40-
"mv ra, zero", // Set the return address to zero.
41-
"mv fp, zero", // Set the frame address to zero.
42-
"tail {entry}"; // Jump to `entry`.
43-
entry = sym super::program::entry
44-
);
37+
core::arch::naked_asm!(
38+
"mv a0, sp", // Pass the incoming `sp` as the arg to `entry`.
39+
"mv ra, zero", // Set the return address to zero.
40+
"mv fp, zero", // Set the frame address to zero.
41+
"tail {entry}", // Jump to `entry`.
42+
entry = sym super::program::entry
43+
)
44+
}
4545

4646
/// Execute a trap instruction.
4747
///

src/arch/x86.rs

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,32 @@ use {
2525
rustix::thread::RawPid,
2626
};
2727

28+
/// The program entry point.
29+
///
30+
/// # Safety
31+
///
32+
/// This function must never be called explicitly. It is the first thing
33+
/// executed in the program, and it assumes that memory is laid out according
34+
/// to the operating system convention for starting a new program.
2835
#[cfg(feature = "origin-start")]
29-
naked_fn!(
30-
"
31-
The program entry point.
32-
33-
# Safety
34-
35-
This function must never be called explicitly. It is the first thing
36-
executed in the program, and it assumes that memory is laid out according
37-
to the operating system convention for starting a new program.
38-
";
39-
pub(super) fn _start() -> !;
40-
36+
#[unsafe(naked)]
37+
#[unsafe(no_mangle)]
38+
pub(super) unsafe extern "C" fn _start() -> ! {
4139
// Jump to `entry`, passing it the initial stack pointer value as an
4240
// argument, a null return address, a null frame pointer, and an aligned
4341
// stack pointer. On many architectures, the incoming frame pointer is
4442
// already null.
45-
"mov eax, esp", // Save the incoming `esp` value.
46-
"push ebp", // Pad for stack pointer alignment.
47-
"push ebp", // Pad for stack pointer alignment.
48-
"push ebp", // Pad for stack pointer alignment.
49-
"push eax", // Pass saved the incoming `esp` as the arg to `entry`.
50-
"push ebp", // Set the return address to zero.
51-
"jmp {entry}"; // Jump to `entry`.
52-
entry = sym super::program::entry
53-
);
43+
core::arch::naked_asm!(
44+
"mov eax, esp", // Save the incoming `esp` value.
45+
"push ebp", // Pad for stack pointer alignment.
46+
"push ebp", // Pad for stack pointer alignment.
47+
"push ebp", // Pad for stack pointer alignment.
48+
"push eax", // Pass saved the incoming `esp` as the arg to `entry`.
49+
"push ebp", // Set the return address to zero.
50+
"jmp {entry}", // Jump to `entry`.
51+
entry = sym super::program::entry
52+
)
53+
}
5454

5555
/// Execute a trap instruction.
5656
///
@@ -398,43 +398,41 @@ pub(super) unsafe fn munmap_and_exit_thread(map_addr: *mut c_void, map_len: usiz
398398
}
399399
}
400400

401+
/// Invoke the `__NR_rt_sigreturn` system call to return control from a signal
402+
/// handler.
403+
///
404+
/// # Safety
405+
///
406+
/// This function must never be called other than by the `sa_restorer`
407+
/// mechanism.
401408
#[cfg(feature = "take-charge")]
402409
#[cfg(feature = "signal")]
403-
naked_fn!(
404-
"
405-
Invoke the `__NR_rt_sigreturn` system call to return control from a signal
406-
handler.
407-
408-
# Safety
409-
410-
This function must never be called other than by the `sa_restorer`
411-
mechanism.
412-
";
413-
pub(super) fn return_from_signal_handler() -> ();
414-
415-
"mov eax, {__NR_rt_sigreturn}",
416-
"int 0x80",
417-
"ud2";
418-
__NR_rt_sigreturn = const __NR_rt_sigreturn
419-
);
410+
#[unsafe(naked)]
411+
pub(super) unsafe extern "C" fn return_from_signal_handler() {
412+
core::arch::naked_asm!(
413+
"mov eax, {__NR_rt_sigreturn}",
414+
"int 0x80",
415+
"ud2",
416+
__NR_rt_sigreturn = const __NR_rt_sigreturn
417+
)
418+
}
420419

420+
/// Invoke the appropriate system call to return control from a signal
421+
/// handler that does not use `SA_SIGINFO`.
422+
///
423+
/// # Safety
424+
///
425+
/// This function must never be called other than by the `sa_restorer`
426+
/// mechanism.
421427
#[cfg(feature = "take-charge")]
422428
#[cfg(feature = "signal")]
423-
naked_fn!(
424-
"
425-
Invoke the appropriate system call to return control from a signal
426-
handler that does not use `SA_SIGINFO`.
427-
428-
# Safety
429-
430-
This function must never be called other than by the `sa_restorer`
431-
mechanism.
432-
";
433-
pub(super) fn return_from_signal_handler_noinfo() -> ();
434-
435-
"pop eax",
436-
"mov eax, {__NR_sigreturn}",
437-
"int 0x80",
438-
"ud2";
439-
__NR_sigreturn = const __NR_sigreturn
440-
);
429+
#[unsafe(naked)]
430+
pub(super) unsafe extern "C" fn return_from_signal_handler_noinfo() {
431+
core::arch::naked_asm!(
432+
"pop eax",
433+
"mov eax, {__NR_sigreturn}",
434+
"int 0x80",
435+
"ud2",
436+
__NR_sigreturn = const __NR_sigreturn
437+
)
438+
}

0 commit comments

Comments
 (0)