From 2860c0bdfbd5844a4236fb3ac7a2142d3580cbe1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:39:11 +0100 Subject: [PATCH 1/4] Remove usage of naked functions --- src/aarch64.rs | 66 +++++++++++++++++++++----------------------- src/i686.rs | 75 +++++++++++++++++++++++--------------------------- src/lib.rs | 1 - src/x86_64.rs | 75 +++++++++++++++++++++++--------------------------- 4 files changed, 100 insertions(+), 117 deletions(-) diff --git a/src/aarch64.rs b/src/aarch64.rs index 3726cdc41e..964c2c46e7 100644 --- a/src/aarch64.rs +++ b/src/aarch64.rs @@ -18,42 +18,40 @@ static MAP: Map = Map { address: STACK_START, // highest possible user address }; -#[naked] -#[no_mangle] -pub unsafe extern "C" fn ustart() { - core::arch::asm!( - " - // Setup a stack. - ldr x8, ={number} - ldr x0, ={fd} - ldr x1, ={map} // pointer to Map struct - ldr x2, ={map_size} // size of Map struct - svc 0 +core::arch::global_asm!( + " + .globl ustart + ustart: + // Setup a stack. + ldr x8, ={number} + ldr x0, ={fd} + ldr x1, ={map} // pointer to Map struct + ldr x2, ={map_size} // size of Map struct + svc 0 - // Failure if return value is zero - cbz x0, 1f + // Failure if return value is zero + cbz x0, 1f - // Failure if return value is negative - tbnz x0, 63, 1f + // Failure if return value is negative + tbnz x0, 63, 1f - // Set up stack frame - mov sp, x0 - add sp, sp, #{stack_size} - mov fp, sp + // Set up stack frame + mov sp, x0 + add sp, sp, #{stack_size} + mov fp, sp - // Stack has the same alignment as `size`. - bl start - // `start` must never return. + // Stack has the same alignment as `size`. + bl start + // `start` must never return. - // failure, emit undefined instruction - 1: - udf #0 - ", - fd = const usize::MAX, // dummy fd indicates anonymous map - map = sym MAP, - map_size = const mem::size_of::(), - number = const SYS_FMAP, - stack_size = const STACK_SIZE, - options(noreturn), - ); -} + // failure, emit undefined instruction + 1: + udf #0 + ", + fd = const usize::MAX, // dummy fd indicates anonymous map + map = sym MAP, + map_size = const mem::size_of::(), + number = const SYS_FMAP, + stack_size = const STACK_SIZE, + options(noreturn), +); diff --git a/src/i686.rs b/src/i686.rs index f5b46c9b7d..2a0beac59b 100644 --- a/src/i686.rs +++ b/src/i686.rs @@ -1,9 +1,5 @@ use core::mem; -use syscall::{ - data::Map, - flag::MapFlags, - number::SYS_FMAP, -}; +use syscall::{data::Map, flag::MapFlags, number::SYS_FMAP}; const STACK_SIZE: usize = 64 * 1024; // 64 KiB pub const STACK_START: usize = 0x8000_0000 - STACK_SIZE; @@ -12,44 +8,41 @@ static MAP: Map = Map { offset: 0, size: STACK_SIZE, flags: MapFlags::PROT_READ - .union(MapFlags::PROT_WRITE) - .union(MapFlags::MAP_PRIVATE) - .union(MapFlags::MAP_FIXED_NOREPLACE), + .union(MapFlags::PROT_WRITE) + .union(MapFlags::MAP_PRIVATE) + .union(MapFlags::MAP_FIXED_NOREPLACE), address: STACK_START, // highest possible user address }; -#[naked] -#[no_mangle] -pub unsafe extern "C" fn ustart() { - core::arch::asm!( - " - # Setup a stack. - mov eax, {number} - mov ebx, {fd} - mov ecx, offset {map} # pointer to Map struct - mov edx, {map_size} # size of Map struct - int 0x80 +core::arch::global_asm!( +" + .globl ustart + ustart: + # Setup a stack. + mov eax, {number} + mov ebx, {fd} + mov ecx, offset {map} # pointer to Map struct + mov edx, {map_size} # size of Map struct + int 0x80 - # Test for success (nonzero value). - cmp eax, 0 - jg 1f - # (failure) - ud2 - 1: - # Subtract 16 since all instructions seem to hate non-canonical ESP values :) - lea esp, [eax+{stack_size}-16] - mov ebp, esp + # Test for success (nonzero value). + cmp eax, 0 + jg 1f + # (failure) + ud2 + 1: + # Subtract 16 since all instructions seem to hate non-canonical ESP values :) + lea esp, [eax+{stack_size}-16] + mov ebp, esp - # Stack has the same alignment as `size`. - call start - # `start` must never return. - ud2 - ", - fd = const usize::MAX, // dummy fd indicates anonymous map - map = sym MAP, - map_size = const mem::size_of::(), - number = const SYS_FMAP, - stack_size = const STACK_SIZE, - options(noreturn), - ); -} + # Stack has the same alignment as `size`. + call start + # `start` must never return. + ud2 + ", + fd = const usize::MAX, // dummy fd indicates anonymous map + map = sym MAP, + map_size = const mem::size_of::(), + number = const SYS_FMAP, + stack_size = const STACK_SIZE, +); diff --git a/src/lib.rs b/src/lib.rs index da57f084ba..ad6eca8d5f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ alloc_error_handler, core_intrinsics, lang_items, - naked_functions, panic_info_message )] diff --git a/src/x86_64.rs b/src/x86_64.rs index cb6cef71c0..b1e7343e53 100644 --- a/src/x86_64.rs +++ b/src/x86_64.rs @@ -1,9 +1,5 @@ use core::mem; -use syscall::{ - data::Map, - flag::MapFlags, - number::SYS_FMAP, -}; +use syscall::{data::Map, flag::MapFlags, number::SYS_FMAP}; const STACK_SIZE: usize = 64 * 1024; // 64 KiB @@ -13,44 +9,41 @@ static MAP: Map = Map { offset: 0, size: STACK_SIZE, flags: MapFlags::PROT_READ - .union(MapFlags::PROT_WRITE) - .union(MapFlags::MAP_PRIVATE) - .union(MapFlags::MAP_FIXED_NOREPLACE), + .union(MapFlags::PROT_WRITE) + .union(MapFlags::MAP_PRIVATE) + .union(MapFlags::MAP_FIXED_NOREPLACE), address: STACK_START, // highest possible user address }; -#[naked] -#[no_mangle] -pub unsafe extern "C" fn ustart() { - core::arch::asm!( - " - # Setup a stack. - mov rax, {number} - mov rdi, {fd} - mov rsi, offset {map} # pointer to Map struct - mov rdx, {map_size} # size of Map struct - syscall +core::arch::global_asm!( + " + .globl ustart + ustart: + # Setup a stack. + mov rax, {number} + mov rdi, {fd} + mov rsi, offset {map} # pointer to Map struct + mov rdx, {map_size} # size of Map struct + syscall - # Test for success (nonzero value). - cmp rax, 0 - jg 1f - # (failure) - ud2 - 1: - # Subtract 16 since all instructions seem to hate non-canonical RSP values :) - lea rsp, [rax+{stack_size}-16] - mov rbp, rsp + # Test for success (nonzero value). + cmp rax, 0 + jg 1f + # (failure) + ud2 + 1: + # Subtract 16 since all instructions seem to hate non-canonical RSP values :) + lea rsp, [rax+{stack_size}-16] + mov rbp, rsp - # Stack has the same alignment as `size`. - call start - # `start` must never return. - ud2 - ", - fd = const usize::MAX, // dummy fd indicates anonymous map - map = sym MAP, - map_size = const mem::size_of::(), - number = const SYS_FMAP, - stack_size = const STACK_SIZE, - options(noreturn), - ); -} + # Stack has the same alignment as `size`. + call start + # `start` must never return. + ud2 + ", + fd = const usize::MAX, // dummy fd indicates anonymous map + map = sym MAP, + map_size = const mem::size_of::(), + number = const SYS_FMAP, + stack_size = const STACK_SIZE, +); From 89e0a71d10bb529150d46a55964955a0739387ba Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:40:47 +0100 Subject: [PATCH 2/4] Remove unnecessary definition of eh_personality All crates are compiled with panic=abort and no extern "C-unwind" is used, so the personality function is referenced by rustc. --- src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ad6eca8d5f..5a850066c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ asm_const, alloc_error_handler, core_intrinsics, - lang_items, panic_info_message )] @@ -53,8 +52,6 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! { fn alloc_error_handler(_: core::alloc::Layout) -> ! { core::intrinsics::abort(); } -#[lang = "eh_personality"] -extern "C" fn rust_eh_personality() {} #[cfg(target_pointer_width = "32")] const HEAP_OFF: usize = 0x4000_0000; From c15c6e1dd29ed7a293d8816e793e762ff7163b7b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:41:53 +0100 Subject: [PATCH 3/4] Use the Display impl of PanicInfo --- src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5a850066c0..d6bb9b1234 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ asm_const, alloc_error_handler, core_intrinsics, - panic_info_message )] #[cfg(target_arch = "aarch64")] @@ -39,12 +38,7 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! { } } - let _ = syscall::write(1, b"panic: "); - if let Some(message) = info.message() { - writeln!(&mut Writer, "{}", message).unwrap(); - } else { - let _ = syscall::write(1, b"(explicit panic)\n"); - } + let _ = writeln!(&mut Writer, "{}", info); core::intrinsics::abort(); } From 57c1bf94b67c96195e61233acd2ecdec9487231f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:46:43 +0100 Subject: [PATCH 4/4] Use default alloc error handler in liballoc --- src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d6bb9b1234..4b70f73c1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] #![feature( asm_const, - alloc_error_handler, core_intrinsics, )] @@ -42,11 +41,6 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! { core::intrinsics::abort(); } -#[alloc_error_handler] -fn alloc_error_handler(_: core::alloc::Layout) -> ! { - core::intrinsics::abort(); -} - #[cfg(target_pointer_width = "32")] const HEAP_OFF: usize = 0x4000_0000;