Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 33 additions & 34 deletions src/arch/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,28 @@ use {
rustix::thread::RawPid,
};

/// The program entry point.
///
/// # Safety
///
/// This function must never be called explicitly. It is the first thing
/// executed in the program, and it assumes that memory is laid out according
/// to the operating system convention for starting a new program.
#[cfg(feature = "origin-start")]
naked_fn!(
"
The program entry point.

# Safety

This function must never be called explicitly. It is the first thing
executed in the program, and it assumes that memory is laid out according
to the operating system convention for starting a new program.
";
pub(super) fn _start() -> !;

#[unsafe(naked)]
#[unsafe(no_mangle)]
pub(super) unsafe extern "C" fn _start() -> ! {
// Jump to `entry`, passing it the initial stack pointer value as an
// argument, a null return address, a null frame pointer, and an aligned
// stack pointer. On many architectures, the incoming frame pointer is
// already null.
"mov x0, sp", // Pass the incoming `sp` as the arg to `entry`.
"mov x30, xzr", // Set the return address to zero.
"b {entry}"; // Jump to `entry`.
entry = sym super::program::entry
);
core::arch::naked_asm!(
"mov x0, sp", // Pass the incoming `sp` as the arg to `entry`.
"mov x30, xzr", // Set the return address to zero.
"b {entry}", // Jump to `entry`.
entry = sym super::program::entry
)
}

/// Execute a trap instruction.
///
Expand Down Expand Up @@ -300,25 +300,24 @@ pub(super) unsafe fn munmap_and_exit_thread(map_addr: *mut c_void, map_len: usiz
}
}

/// Invoke the `__NR_rt_sigreturn` system call to return control from a signal
/// handler.
///
/// # Safety
///
/// This function must never be called other than by the `sa_restorer`
/// mechanism.
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
naked_fn!(
"
Invoke the `__NR_rt_sigreturn` system call to return control from a signal
handler.

# Safety

This function must never be called other than by the `sa_restorer`
mechanism.
";
pub(super) fn return_from_signal_handler() -> ();

"mov x8, {__NR_rt_sigreturn}",
"svc 0",
"udf #16";
__NR_rt_sigreturn = const __NR_rt_sigreturn
);
#[unsafe(naked)]
pub(super) unsafe extern "C" fn return_from_signal_handler() {
core::arch::naked_asm!(
"mov x8, {__NR_rt_sigreturn}",
"svc 0",
"udf #16",
__NR_rt_sigreturn = const __NR_rt_sigreturn
)
}

/// Invoke the appropriate system call to return control from a signal
/// handler that does not use `SA_SIGINFO`. On aarch64, this uses the same
Expand Down
100 changes: 49 additions & 51 deletions src/arch/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,28 @@ use {
rustix::thread::RawPid,
};

/// The program entry point.
///
/// # Safety
///
/// This function must never be called explicitly. It is the first thing
/// executed in the program, and it assumes that memory is laid out according
/// to the operating system convention for starting a new program.
#[cfg(feature = "origin-start")]
naked_fn!(
"
The program entry point.

# Safety

This function must never be called explicitly. It is the first thing
executed in the program, and it assumes that memory is laid out according
to the operating system convention for starting a new program.
";
pub(super) fn _start() -> !;

#[unsafe(naked)]
#[unsafe(no_mangle)]
pub(super) unsafe extern "C" fn _start() -> ! {
// Jump to `entry`, passing it the initial stack pointer value as an
// argument, a null return address, a null frame pointer, and an aligned
// stack pointer. On many architectures, the incoming frame pointer is
// already null.
"mov r0, sp", // Pass the incoming `sp` as the arg to `entry`.
"mov lr, #0", // Set the return address to zero.
"b {entry}"; // Jump to `entry`.
entry = sym super::program::entry
);
core::arch::naked_asm!(
"mov r0, sp", // Pass the incoming `sp` as the arg to `entry`.
"mov lr, #0", // Set the return address to zero.
"b {entry}", // Jump to `entry`.
entry = sym super::program::entry
)
}

/// Execute a trap instruction.
///
Expand Down Expand Up @@ -314,42 +314,40 @@ pub(super) unsafe fn munmap_and_exit_thread(map_addr: *mut c_void, map_len: usiz
}
}

/// Invoke the `__NR_rt_sigreturn` system call to return control from a signal
/// handler.
///
/// # Safety
///
/// This function must never be called other than by the `sa_restorer`
/// mechanism.
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
naked_fn!(
"
Invoke the `__NR_rt_sigreturn` system call to return control from a signal
handler.

# Safety

This function must never be called other than by the `sa_restorer`
mechanism.
";
pub(super) fn return_from_signal_handler() -> ();

"mov r7, {__NR_rt_sigreturn}",
"swi 0",
"udf #16";
__NR_rt_sigreturn = const __NR_rt_sigreturn
);
#[unsafe(naked)]
pub(super) unsafe extern "C" fn return_from_signal_handler() {
core::arch::naked_asm!(
"mov r7, {__NR_rt_sigreturn}",
"swi 0",
"udf #16",
__NR_rt_sigreturn = const __NR_rt_sigreturn
)
}

/// Invoke the appropriate system call to return control from a signal
/// handler that does not use `SA_SIGINFO`.
///
/// # Safety
///
/// This function must never be called other than by the `sa_restorer`
/// mechanism.
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
naked_fn!(
"
Invoke the appropriate system call to return control from a signal
handler that does not use `SA_SIGINFO`.

# Safety

This function must never be called other than by the `sa_restorer`
mechanism.
";
pub(super) fn return_from_signal_handler_noinfo() -> ();

"mov r7, {__NR_sigreturn}",
"swi 0",
"udf #16";
__NR_sigreturn = const __NR_sigreturn
);
#[unsafe(naked)]
pub(super) unsafe extern "C" fn return_from_signal_handler_noinfo() {
core::arch::naked_asm!(
"mov r7, {__NR_sigreturn}",
"swi 0",
"udf #16",
__NR_sigreturn = const __NR_sigreturn
)
}
36 changes: 18 additions & 18 deletions src/arch/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@ use {
rustix::thread::RawPid,
};

/// The program entry point.
///
/// # Safety
///
/// This function must never be called explicitly. It is the first thing
/// executed in the program, and it assumes that memory is laid out according
/// to the operating system convention for starting a new program.
#[cfg(feature = "origin-start")]
naked_fn!(
"
The program entry point.

# Safety

This function must never be called explicitly. It is the first thing
executed in the program, and it assumes that memory is laid out according
to the operating system convention for starting a new program.
";
pub(super) fn _start() -> !;

#[unsafe(naked)]
#[unsafe(no_mangle)]
pub(super) unsafe extern "C" fn _start() -> ! {
// Jump to `entry`, passing it the initial stack pointer value as an
// argument, a null return address, a null frame pointer, and an aligned
// stack pointer. On many architectures, the incoming frame pointer is
// already null.
"mv a0, sp", // Pass the incoming `sp` as the arg to `entry`.
"mv ra, zero", // Set the return address to zero.
"mv fp, zero", // Set the frame address to zero.
"tail {entry}"; // Jump to `entry`.
entry = sym super::program::entry
);
core::arch::naked_asm!(
"mv a0, sp", // Pass the incoming `sp` as the arg to `entry`.
"mv ra, zero", // Set the return address to zero.
"mv fp, zero", // Set the frame address to zero.
"tail {entry}", // Jump to `entry`.
entry = sym super::program::entry
)
}

/// Execute a trap instruction.
///
Expand Down
110 changes: 54 additions & 56 deletions src/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,32 @@ use {
rustix::thread::RawPid,
};

/// The program entry point.
///
/// # Safety
///
/// This function must never be called explicitly. It is the first thing
/// executed in the program, and it assumes that memory is laid out according
/// to the operating system convention for starting a new program.
#[cfg(feature = "origin-start")]
naked_fn!(
"
The program entry point.

# Safety

This function must never be called explicitly. It is the first thing
executed in the program, and it assumes that memory is laid out according
to the operating system convention for starting a new program.
";
pub(super) fn _start() -> !;

#[unsafe(naked)]
#[unsafe(no_mangle)]
pub(super) unsafe extern "C" fn _start() -> ! {
// Jump to `entry`, passing it the initial stack pointer value as an
// argument, a null return address, a null frame pointer, and an aligned
// stack pointer. On many architectures, the incoming frame pointer is
// already null.
"mov eax, esp", // Save the incoming `esp` value.
"push ebp", // Pad for stack pointer alignment.
"push ebp", // Pad for stack pointer alignment.
"push ebp", // Pad for stack pointer alignment.
"push eax", // Pass saved the incoming `esp` as the arg to `entry`.
"push ebp", // Set the return address to zero.
"jmp {entry}"; // Jump to `entry`.
entry = sym super::program::entry
);
core::arch::naked_asm!(
"mov eax, esp", // Save the incoming `esp` value.
"push ebp", // Pad for stack pointer alignment.
"push ebp", // Pad for stack pointer alignment.
"push ebp", // Pad for stack pointer alignment.
"push eax", // Pass saved the incoming `esp` as the arg to `entry`.
"push ebp", // Set the return address to zero.
"jmp {entry}", // Jump to `entry`.
entry = sym super::program::entry
)
}

/// Execute a trap instruction.
///
Expand Down Expand Up @@ -398,43 +398,41 @@ pub(super) unsafe fn munmap_and_exit_thread(map_addr: *mut c_void, map_len: usiz
}
}

/// Invoke the `__NR_rt_sigreturn` system call to return control from a signal
/// handler.
///
/// # Safety
///
/// This function must never be called other than by the `sa_restorer`
/// mechanism.
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
naked_fn!(
"
Invoke the `__NR_rt_sigreturn` system call to return control from a signal
handler.

# Safety

This function must never be called other than by the `sa_restorer`
mechanism.
";
pub(super) fn return_from_signal_handler() -> ();

"mov eax, {__NR_rt_sigreturn}",
"int 0x80",
"ud2";
__NR_rt_sigreturn = const __NR_rt_sigreturn
);
#[unsafe(naked)]
pub(super) unsafe extern "C" fn return_from_signal_handler() {
core::arch::naked_asm!(
"mov eax, {__NR_rt_sigreturn}",
"int 0x80",
"ud2",
__NR_rt_sigreturn = const __NR_rt_sigreturn
)
}

/// Invoke the appropriate system call to return control from a signal
/// handler that does not use `SA_SIGINFO`.
///
/// # Safety
///
/// This function must never be called other than by the `sa_restorer`
/// mechanism.
#[cfg(feature = "take-charge")]
#[cfg(feature = "signal")]
naked_fn!(
"
Invoke the appropriate system call to return control from a signal
handler that does not use `SA_SIGINFO`.

# Safety

This function must never be called other than by the `sa_restorer`
mechanism.
";
pub(super) fn return_from_signal_handler_noinfo() -> ();

"pop eax",
"mov eax, {__NR_sigreturn}",
"int 0x80",
"ud2";
__NR_sigreturn = const __NR_sigreturn
);
#[unsafe(naked)]
pub(super) unsafe extern "C" fn return_from_signal_handler_noinfo() {
core::arch::naked_asm!(
"pop eax",
"mov eax, {__NR_sigreturn}",
"int 0x80",
"ud2",
__NR_sigreturn = const __NR_sigreturn
)
}
Loading