From c9e178d16698b175c9d51bded1245e8b738d3ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 11:36:44 +0100 Subject: [PATCH 01/12] docs(switch): fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/arch/aarch64/kernel/switch.rs | 2 +- src/arch/x86_64/kernel/switch.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/aarch64/kernel/switch.rs b/src/arch/aarch64/kernel/switch.rs index b59dd87569..9c3102e111 100644 --- a/src/arch/aarch64/kernel/switch.rs +++ b/src/arch/aarch64/kernel/switch.rs @@ -14,7 +14,7 @@ macro_rules! kernel_function_impl { let $arg = { let mut reg = 0_usize; // SAFETY: $A is smaller than usize and directly fits in a register - // Since f takes $A as argument via C calling convention, any opper bytes do not matter. + // Since f takes $A as argument via C calling convention, any upper bytes do not matter. ptr::write(ptr::from_mut(&mut reg) as _, $arg); reg }; diff --git a/src/arch/x86_64/kernel/switch.rs b/src/arch/x86_64/kernel/switch.rs index 71c276de48..49368aeae2 100644 --- a/src/arch/x86_64/kernel/switch.rs +++ b/src/arch/x86_64/kernel/switch.rs @@ -229,7 +229,7 @@ macro_rules! kernel_function_impl { let $arg = { let mut reg = 0_usize; // SAFETY: $A is smaller than usize and directly fits in a register - // Since f takes $A as argument via C calling convention, any opper bytes do not matter. + // Since f takes $A as argument via C calling convention, any upper bytes do not matter. ptr::write(ptr::from_mut(&mut reg) as _, $arg); reg }; From dab361abd1bdd8273a9e1a49efee0a8550ab55f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 16:29:51 +0100 Subject: [PATCH 02/12] docs(lwip): remove unused doc comment from 0b5395e3728fadd9b0bc91d123835768c9a76ed3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/syscalls/lwip.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/syscalls/lwip.rs b/src/syscalls/lwip.rs index f41678c4a6..b905853d0e 100644 --- a/src/syscalls/lwip.rs +++ b/src/syscalls/lwip.rs @@ -4,9 +4,6 @@ use lock_api::MutexGuard; use crate::arch::core_local::core_scheduler; use crate::{arch, console}; -/// Enables lwIP's printf to print a whole string without being interrupted by -/// a message from the kernel. - extern "C" fn __sys_lwip_get_errno() -> i32 { core_scheduler().get_lwip_errno() } From dbded701b876ae0e04f23362d36518a47c3a608d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 18:14:34 +0100 Subject: [PATCH 03/12] fix(syscalls/socket): fix `sys_getsockopt` symbol name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/syscalls/socket.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/syscalls/socket.rs b/src/syscalls/socket.rs index ef785823fd..f49f30f5f6 100644 --- a/src/syscalls/socket.rs +++ b/src/syscalls/socket.rs @@ -703,7 +703,7 @@ pub extern "C" fn sys_setsockopt( } #[no_mangle] -pub extern "C" fn getsockopt( +pub extern "C" fn sys_getsockopt( s: i32, level: i32, optname: i32, From 3305623d6ad927dbaebacff4a979d76a33255547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 17:52:51 +0100 Subject: [PATCH 04/12] fix(macros): make `kernel_function` consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/macros.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/macros.rs b/src/macros.rs index 64a1b22d04..221b9475ff 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -80,6 +80,7 @@ macro_rules! dbg { macro_rules! kernel_function { ($f:ident()) => {{ use $crate::errno::ToErrno; + #[allow(unreachable_code)] $crate::arch::switch::kernel_function0($f).set_errno() }}; @@ -91,25 +92,31 @@ macro_rules! kernel_function { ($f:ident($arg1:expr, $arg2:expr)) => {{ use $crate::errno::ToErrno; + #[allow(unreachable_code)] $crate::arch::switch::kernel_function2($f, $arg1, $arg2).set_errno() }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr)) => {{ use $crate::errno::ToErrno; + #[allow(unreachable_code)] $crate::arch::switch::kernel_function3($f, $arg1, $arg2, $arg3).set_errno() }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr)) => {{ use $crate::errno::ToErrno; + #[allow(unreachable_code)] $crate::arch::switch::kernel_function4($f, $arg1, $arg2, $arg3, $arg4).set_errno() }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr)) => {{ + use $crate::errno::ToErrno; + #[allow(unreachable_code)] $crate::arch::switch::kernel_function5($f, $arg1, $arg2, $arg3, $arg4, $arg5).set_errno() }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr, $arg6:expr)) => {{ use $crate::errno::ToErrno; + #[allow(unreachable_code)] $crate::arch::switch::kernel_function6($f, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6) .set_errno() }}; From 8eec3c6ce97ec073d683a438075cb0784d568ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 16:42:40 +0100 Subject: [PATCH 05/12] refactor: move `__sys_{free,malloc,realloc}` to `syscalls` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/lib.rs | 120 -------------------------------------------- src/syscalls/mod.rs | 120 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 121 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a0a6df9227..c928a83b2f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,10 +51,6 @@ extern crate std; #[macro_use] extern crate num_derive; -#[cfg(not(feature = "common-os"))] -use alloc::alloc::Layout; -#[cfg(not(feature = "common-os"))] -use core::alloc::GlobalAlloc; #[cfg(feature = "smp")] use core::hint::spin_loop; #[cfg(feature = "smp")] @@ -132,122 +128,6 @@ fn trivial_test() { #[global_allocator] static ALLOCATOR: LockedAllocator = LockedAllocator::new(); -/// Interface to allocate memory from system heap -/// -/// # Errors -/// Returning a null pointer indicates that either memory is exhausted or -/// `size` and `align` do not meet this allocator's size or alignment constraints. -/// -#[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) extern "C" fn __sys_malloc(size: usize, align: usize) -> *mut u8 { - let layout_res = Layout::from_size_align(size, align); - if layout_res.is_err() || size == 0 { - warn!( - "__sys_malloc called with size {:#x}, align {:#x} is an invalid layout!", - size, align - ); - return core::ptr::null_mut(); - } - let layout = layout_res.unwrap(); - let ptr = unsafe { ALLOCATOR.alloc(layout) }; - - trace!( - "__sys_malloc: allocate memory at {:p} (size {:#x}, align {:#x})", - ptr, - size, - align - ); - - ptr -} - -/// Shrink or grow a block of memory to the given `new_size`. The block is described by the given -/// ptr pointer and layout. If this returns a non-null pointer, then ownership of the memory block -/// referenced by ptr has been transferred to this allocator. The memory may or may not have been -/// deallocated, and should be considered unusable (unless of course it was transferred back to the -/// caller again via the return value of this method). The new memory block is allocated with -/// layout, but with the size updated to new_size. -/// If this method returns null, then ownership of the memory block has not been transferred to this -/// allocator, and the contents of the memory block are unaltered. -/// -/// # Safety -/// This function is unsafe because undefined behavior can result if the caller does not ensure all -/// of the following: -/// - `ptr` must be currently allocated via this allocator, -/// - `size` and `align` must be the same layout that was used to allocate that block of memory. -/// ToDO: verify if the same values for size and align always lead to the same layout -/// -/// # Errors -/// Returns null if the new layout does not meet the size and alignment constraints of the -/// allocator, or if reallocation otherwise fails. -#[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) extern "C" fn __sys_realloc( - ptr: *mut u8, - size: usize, - align: usize, - new_size: usize, -) -> *mut u8 { - unsafe { - let layout_res = Layout::from_size_align(size, align); - if layout_res.is_err() || size == 0 || new_size == 0 { - warn!( - "__sys_realloc called with ptr {:p}, size {:#x}, align {:#x}, new_size {:#x} is an invalid layout!", - ptr, size, align, new_size - ); - return core::ptr::null_mut(); - } - let layout = layout_res.unwrap(); - let new_ptr = ALLOCATOR.realloc(ptr, layout, new_size); - - if new_ptr.is_null() { - debug!( - "__sys_realloc failed to resize ptr {:p} with size {:#x}, align {:#x}, new_size {:#x} !", - ptr, size, align, new_size - ); - } else { - trace!( - "__sys_realloc: resized memory at {:p}, new address {:p}", - ptr, - new_ptr - ); - } - new_ptr - } -} - -/// Interface to deallocate a memory region from the system heap -/// -/// # Safety -/// This function is unsafe because undefined behavior can result if the caller does not ensure all of the following: -/// - ptr must denote a block of memory currently allocated via this allocator, -/// - `size` and `align` must be the same values that were used to allocate that block of memory -/// ToDO: verify if the same values for size and align always lead to the same layout -/// -/// # Errors -/// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed. -#[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usize) { - unsafe { - let layout_res = Layout::from_size_align(size, align); - if layout_res.is_err() || size == 0 { - warn!( - "__sys_free called with size {:#x}, align {:#x} is an invalid layout!", - size, align - ); - debug_assert!(layout_res.is_err(), "__sys_free error: Invalid layout"); - debug_assert_ne!(size, 0, "__sys_free error: size cannot be 0"); - } else { - trace!( - "sys_free: deallocate memory at {:p} (size {:#x})", - ptr, - size - ); - } - let layout = layout_res.unwrap(); - ALLOCATOR.dealloc(ptr, layout); - } -} - /// Entry point of a kernel thread, which initialize the libos #[cfg(target_os = "none")] extern "C" fn initd(_arg: usize) { diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index f893150014..052e6139ec 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -1,5 +1,7 @@ #![allow(clippy::result_unit_err)] +#[cfg(all(target_os = "none", not(feature = "common-os")))] +use core::alloc::{GlobalAlloc, Layout}; use core::ffi::CStr; use core::marker::PhantomData; @@ -26,7 +28,7 @@ use crate::fd::{ use crate::fs::{self, FileAttr}; use crate::syscalls::interfaces::SyscallInterface; #[cfg(all(target_os = "none", not(feature = "common-os")))] -use crate::{__sys_free, __sys_malloc, __sys_realloc}; +use crate::ALLOCATOR; mod condvar; mod entropy; @@ -72,18 +74,134 @@ pub(crate) fn init() { sbrk_init(); } +/// Interface to allocate memory from system heap +/// +/// # Errors +/// Returning a null pointer indicates that either memory is exhausted or +/// `size` and `align` do not meet this allocator's size or alignment constraints. +/// +#[cfg(all(target_os = "none", not(feature = "common-os")))] +pub(crate) extern "C" fn __sys_malloc(size: usize, align: usize) -> *mut u8 { + let layout_res = Layout::from_size_align(size, align); + if layout_res.is_err() || size == 0 { + warn!( + "__sys_malloc called with size {:#x}, align {:#x} is an invalid layout!", + size, align + ); + return core::ptr::null_mut(); + } + let layout = layout_res.unwrap(); + let ptr = unsafe { ALLOCATOR.alloc(layout) }; + + trace!( + "__sys_malloc: allocate memory at {:p} (size {:#x}, align {:#x})", + ptr, + size, + align + ); + + ptr +} + #[cfg(all(target_os = "none", not(feature = "common-os")))] #[no_mangle] pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { kernel_function!(__sys_malloc(size, align)) } +/// Shrink or grow a block of memory to the given `new_size`. The block is described by the given +/// ptr pointer and layout. If this returns a non-null pointer, then ownership of the memory block +/// referenced by ptr has been transferred to this allocator. The memory may or may not have been +/// deallocated, and should be considered unusable (unless of course it was transferred back to the +/// caller again via the return value of this method). The new memory block is allocated with +/// layout, but with the size updated to new_size. +/// If this method returns null, then ownership of the memory block has not been transferred to this +/// allocator, and the contents of the memory block are unaltered. +/// +/// # Safety +/// This function is unsafe because undefined behavior can result if the caller does not ensure all +/// of the following: +/// - `ptr` must be currently allocated via this allocator, +/// - `size` and `align` must be the same layout that was used to allocate that block of memory. +/// ToDO: verify if the same values for size and align always lead to the same layout +/// +/// # Errors +/// Returns null if the new layout does not meet the size and alignment constraints of the +/// allocator, or if reallocation otherwise fails. +#[cfg(all(target_os = "none", not(feature = "common-os")))] +pub(crate) extern "C" fn __sys_realloc( + ptr: *mut u8, + size: usize, + align: usize, + new_size: usize, +) -> *mut u8 { + unsafe { + let layout_res = Layout::from_size_align(size, align); + if layout_res.is_err() || size == 0 || new_size == 0 { + warn!( + "__sys_realloc called with ptr {:p}, size {:#x}, align {:#x}, new_size {:#x} is an invalid layout!", + ptr, size, align, new_size + ); + return core::ptr::null_mut(); + } + let layout = layout_res.unwrap(); + let new_ptr = ALLOCATOR.realloc(ptr, layout, new_size); + + if new_ptr.is_null() { + debug!( + "__sys_realloc failed to resize ptr {:p} with size {:#x}, align {:#x}, new_size {:#x} !", + ptr, size, align, new_size + ); + } else { + trace!( + "__sys_realloc: resized memory at {:p}, new address {:p}", + ptr, + new_ptr + ); + } + new_ptr + } +} + #[cfg(all(target_os = "none", not(feature = "common-os")))] #[no_mangle] pub extern "C" fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8 { kernel_function!(__sys_realloc(ptr, size, align, new_size)) } +/// Interface to deallocate a memory region from the system heap +/// +/// # Safety +/// This function is unsafe because undefined behavior can result if the caller does not ensure all of the following: +/// - ptr must denote a block of memory currently allocated via this allocator, +/// - `size` and `align` must be the same values that were used to allocate that block of memory +/// ToDO: verify if the same values for size and align always lead to the same layout +/// +/// # Errors +/// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed. +#[cfg(all(target_os = "none", not(feature = "common-os")))] +pub(crate) extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usize) { + unsafe { + let layout_res = Layout::from_size_align(size, align); + if layout_res.is_err() || size == 0 { + warn!( + "__sys_free called with size {:#x}, align {:#x} is an invalid layout!", + size, align + ); + debug_assert!(layout_res.is_err(), "__sys_free error: Invalid layout"); + debug_assert_ne!(size, 0, "__sys_free error: size cannot be 0"); + } else { + trace!( + "sys_free: deallocate memory at {:p} (size {:#x})", + ptr, + size + ); + } + let layout = layout_res.unwrap(); + ALLOCATOR.dealloc(ptr, layout); + } +} + #[cfg(all(target_os = "none", not(feature = "common-os")))] #[no_mangle] pub extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { From e382a37234a3ab2459d113b7df65848c858978fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 16:47:59 +0100 Subject: [PATCH 06/12] refactor: move `ALLOCATOR` to `mm` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/lib.rs | 5 ----- src/mm/mod.rs | 9 +++++++-- src/syscalls/mod.rs | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c928a83b2f..da95c7c550 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,6 @@ use arch::core_local::*; // Used for integration test status. #[doc(hidden)] pub use env::is_uhyve as _is_uhyve; -use mm::allocator::LockedAllocator; pub(crate) use crate::arch::*; pub use crate::config::DEFAULT_STACK_SIZE; @@ -124,10 +123,6 @@ fn trivial_test() { panic!("Test called"); } -#[cfg(target_os = "none")] -#[global_allocator] -static ALLOCATOR: LockedAllocator = LockedAllocator::new(); - /// Entry point of a kernel thread, which initialize the libos #[cfg(target_os = "none")] extern "C" fn initd(_arg: usize) { diff --git a/src/mm/mod.rs b/src/mm/mod.rs index 815960c350..bc62d2a5a2 100644 --- a/src/mm/mod.rs +++ b/src/mm/mod.rs @@ -9,6 +9,7 @@ use hermit_sync::Lazy; #[cfg(feature = "newlib")] use hermit_sync::OnceCell; +use self::allocator::LockedAllocator; #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] use crate::arch::mm::paging::HugePageSize; #[cfg(target_arch = "x86_64")] @@ -22,6 +23,10 @@ use crate::arch::mm::PhysAddr; use crate::arch::mm::VirtAddr; use crate::{arch, env}; +#[cfg(target_os = "none")] +#[global_allocator] +pub static ALLOCATOR: LockedAllocator = LockedAllocator::new(); + /// Physical and virtual address range of the 2 MiB pages that map the kernel. static KERNEL_ADDR_RANGE: Lazy> = Lazy::new(|| { if cfg!(target_os = "none") { @@ -116,7 +121,7 @@ pub(crate) fn init() { unsafe { let start = allocate(kernel_heap_size, true); - crate::ALLOCATOR.init(start.as_mut_ptr(), kernel_heap_size); + ALLOCATOR.init(start.as_mut_ptr(), kernel_heap_size); info!("Kernel heap starts at {:#x}", start); } @@ -275,7 +280,7 @@ pub(crate) fn init() { #[cfg(not(feature = "newlib"))] unsafe { - crate::ALLOCATOR.init( + ALLOCATOR.init( heap_start_addr.as_mut_ptr(), (heap_end_addr - heap_start_addr).into(), ); diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 052e6139ec..bac0a774fe 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -26,9 +26,9 @@ use crate::fd::{ IoError, OpenOption, PollFd, }; use crate::fs::{self, FileAttr}; -use crate::syscalls::interfaces::SyscallInterface; #[cfg(all(target_os = "none", not(feature = "common-os")))] -use crate::ALLOCATOR; +use crate::mm::ALLOCATOR; +use crate::syscalls::interfaces::SyscallInterface; mod condvar; mod entropy; From 5f976e9ef72cd887821fe343533b7517d01deea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 18:19:52 +0100 Subject: [PATCH 07/12] refactor(syscalls/system): inline import with single use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/syscalls/system.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/syscalls/system.rs b/src/syscalls/system.rs index 2a58b05b89..85ecebc6ce 100644 --- a/src/syscalls/system.rs +++ b/src/syscalls/system.rs @@ -1,7 +1,5 @@ -use crate::arch; - extern "C" fn __sys_getpagesize() -> i32 { - arch::mm::paging::get_application_page_size() as i32 + crate::arch::mm::paging::get_application_page_size() as i32 } #[no_mangle] From d3b75168d19170573cb0126237e16eb39795f092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 17:15:54 +0100 Subject: [PATCH 08/12] fix(syscalls/semaphore): remove double stack switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/syscalls/semaphore.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/syscalls/semaphore.rs b/src/syscalls/semaphore.rs index 29599a2571..e493bb706d 100644 --- a/src/syscalls/semaphore.rs +++ b/src/syscalls/semaphore.rs @@ -124,11 +124,7 @@ pub extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { kernel_function!(__sys_sem_timedwait(sem, ms)) } -extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { - sys_sem_timedwait(sem, ms) -} - #[no_mangle] pub extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { - kernel_function!(__sys_sem_cancelablewait(sem, ms)) + kernel_function!(__sys_sem_timedwait(sem, ms)) } From 5716d40bdc7819e13e7b8e9615cdf50aa5c35349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 17:37:39 +0100 Subject: [PATCH 09/12] fix(syscalls): don't call foreign `__sys` functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/arch/x86_64/kernel/processor.rs | 2 +- src/lib.rs | 2 +- src/shell.rs | 2 +- src/syscalls/entropy.rs | 39 ++++++++++++++++------- src/syscalls/mod.rs | 12 +++++-- src/syscalls/semaphore.rs | 22 ++++++++----- src/syscalls/socket.rs | 32 ++++++++++--------- src/syscalls/tasks.rs | 49 ++++++++++++++++++++++------- src/syscalls/timer.rs | 4 +-- 9 files changed, 113 insertions(+), 51 deletions(-) diff --git a/src/arch/x86_64/kernel/processor.rs b/src/arch/x86_64/kernel/processor.rs index 526862a4e7..0691fdecc1 100644 --- a/src/arch/x86_64/kernel/processor.rs +++ b/src/arch/x86_64/kernel/processor.rs @@ -846,7 +846,7 @@ pub fn configure() { #[cfg(feature = "fsgsbase")] if !supports_fsgs() { error!("FSGSBASE support is enabled, but the processor doesn't support it!"); - crate::__sys_shutdown(1); + crate::shutdown(1); } debug!("Set CR4 to {:#x}", cr4); diff --git a/src/lib.rs b/src/lib.rs index da95c7c550..54aef2c46b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -267,5 +267,5 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! { let core_id = crate::arch::core_local::core_id(); println!("[{core_id}][PANIC] {info}"); - crate::__sys_shutdown(1); + crate::shutdown(1); } diff --git a/src/shell.rs b/src/shell.rs index 3d59ddfc31..52cab9ac17 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -39,7 +39,7 @@ static mut SHELL: Lazy> = Lazy::new(|| { ShellCommand { help: "Shutdown HermitOS", func: |_, shell| { - crate::__sys_shutdown(0); + crate::shutdown(0); Ok(()) }, aliases: &["s"], diff --git a/src/syscalls/entropy.rs b/src/syscalls/entropy.rs index e93ae6e564..8a8bc5dce4 100644 --- a/src/syscalls/entropy.rs +++ b/src/syscalls/entropy.rs @@ -17,7 +17,7 @@ fn generate_park_miller_lehmer_random_number() -> u32 { random } -unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize { +unsafe fn read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize { let Some(flags) = Flags::from_bits(flags) else { return -EINVAL as isize; }; @@ -44,6 +44,10 @@ unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> } } +unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize { + unsafe { read_entropy(buf, len, flags) } +} + /// Fill `len` bytes in `buf` with cryptographically secure random data. /// /// Returns either the number of bytes written to buf (a positive value) or @@ -51,21 +55,17 @@ unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> /// * `-ENOSYS` if the system does not support random data generation. #[allow(unsafe_op_in_unsafe_fn)] #[no_mangle] -#[cfg_attr(target_arch = "riscv64", allow(unsafe_op_in_unsafe_fn))] // FIXME pub unsafe extern "C" fn sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize { kernel_function!(__sys_read_entropy(buf, len, flags)) } -/// Create a cryptographicly secure 32bit random number with the support of -/// the underlying hardware. If the required hardware isn't available, -/// the function returns `-1`. #[cfg(not(feature = "newlib"))] #[no_mangle] -pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { +unsafe extern "C" fn __sys_secure_rand32(value: *mut u32) -> i32 { let mut buf = value.cast(); let mut len = size_of::(); while len != 0 { - let res = unsafe { sys_read_entropy(buf, len, 0) }; + let res = unsafe { read_entropy(buf, len, 0) }; if res < 0 { return -1; } @@ -77,16 +77,23 @@ pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { 0 } -/// Create a cryptographicly secure 64bit random number with the support of +/// Create a cryptographicly secure 32bit random number with the support of /// the underlying hardware. If the required hardware isn't available, -/// the function returns -1. +/// the function returns `-1`. #[cfg(not(feature = "newlib"))] +#[allow(unsafe_op_in_unsafe_fn)] #[no_mangle] -pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { +pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { + kernel_function!(__sys_secure_rand32(value)) +} + +#[cfg(not(feature = "newlib"))] +#[no_mangle] +unsafe extern "C" fn __sys_secure_rand64(value: *mut u64) -> i32 { let mut buf = value.cast(); let mut len = size_of::(); while len != 0 { - let res = unsafe { sys_read_entropy(buf, len, 0) }; + let res = unsafe { read_entropy(buf, len, 0) }; if res < 0 { return -1; } @@ -98,6 +105,16 @@ pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { 0 } +/// Create a cryptographicly secure 64bit random number with the support of +/// the underlying hardware. If the required hardware isn't available, +/// the function returns -1. +#[cfg(not(feature = "newlib"))] +#[allow(unsafe_op_in_unsafe_fn)] +#[no_mangle] +pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { + kernel_function!(__sys_secure_rand64(value)) +} + extern "C" fn __sys_rand() -> u32 { generate_park_miller_lehmer_random_number() } diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index bac0a774fe..4c052a02ec 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -212,13 +212,17 @@ pub(crate) fn get_application_parameters() -> (i32, *const *const u8, *const *co SYS.get_application_parameters() } -pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! { +pub(crate) fn shutdown(arg: i32) -> ! { // print some performance statistics crate::arch::kernel::print_statistics(); SYS.shutdown(arg) } +pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! { + shutdown(arg) +} + #[no_mangle] pub extern "C" fn sys_shutdown(arg: i32) -> ! { kernel_function!(__sys_shutdown(arg)) @@ -386,7 +390,7 @@ pub extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isiz kernel_function!(__sys_read(fd, buf, len)) } -extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { +fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { let slice = unsafe { core::slice::from_raw_parts(buf, len) }; crate::fd::write(fd, slice).map_or_else( |e| -num::ToPrimitive::to_isize(&e).unwrap(), @@ -394,6 +398,10 @@ extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isi ) } +extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { + write(fd, buf, len) +} + #[no_mangle] pub extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { kernel_function!(__sys_write(fd, buf, len)) diff --git a/src/syscalls/semaphore.rs b/src/syscalls/semaphore.rs index e493bb706d..03f1da86f3 100644 --- a/src/syscalls/semaphore.rs +++ b/src/syscalls/semaphore.rs @@ -98,12 +98,7 @@ pub extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 { kernel_function!(__sys_sem_trywait(sem)) } -/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds. -/// -/// Blocks until semaphore is acquired or until wake-up time has elapsed. -/// -/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout. -extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { +fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { if sem.is_null() { return -EINVAL; } @@ -119,12 +114,25 @@ extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { } } +/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds. +/// +/// Blocks until semaphore is acquired or until wake-up time has elapsed. +/// +/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout. +extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { + sem_timedwait(sem, ms) +} + #[no_mangle] pub extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { kernel_function!(__sys_sem_timedwait(sem, ms)) } +extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { + sem_timedwait(sem, ms) +} + #[no_mangle] pub extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { - kernel_function!(__sys_sem_timedwait(sem, ms)) + kernel_function!(__sys_sem_cancelablewait(sem, ms)) } diff --git a/src/syscalls/socket.rs b/src/syscalls/socket.rs index f49f30f5f6..513106196f 100644 --- a/src/syscalls/socket.rs +++ b/src/syscalls/socket.rs @@ -15,7 +15,7 @@ use crate::fd::socket::tcp; #[cfg(feature = "udp")] use crate::fd::socket::udp; use crate::fd::{get_object, insert_object, replace_object, ObjectInterface, SocketOption}; -use crate::syscalls::{IoCtl, __sys_write}; +use crate::syscalls::IoCtl; pub const AF_INET: i32 = 0; pub const AF_INET6: i32 = 1; @@ -565,6 +565,10 @@ extern "C" fn __sys_getaddrinfo( -EINVAL } +extern "C" fn __sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize { + super::write(s, mem.cast(), len) +} + extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 { let obj = get_object(fd); obj.map_or_else( @@ -576,12 +580,16 @@ extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 { ) } -extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize) -> isize { - let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) }; - crate::fd::read(fd, slice).map_or_else( - |e| -num::ToPrimitive::to_isize(&e).unwrap(), - |v| v.try_into().unwrap(), - ) +extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { + if flags == 0 { + let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) }; + crate::fd::read(fd, slice).map_or_else( + |e| -num::ToPrimitive::to_isize(&e).unwrap(), + |v| v.try_into().unwrap(), + ) + } else { + (-crate::errno::EINVAL).try_into().unwrap() + } } extern "C" fn __sys_sendto( @@ -734,8 +742,8 @@ pub extern "C" fn sys_getaddrinfo( } #[no_mangle] -pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize { - kernel_function!(__sys_write(s, mem as *const u8, len)) +pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, flags: i32) -> isize { + kernel_function!(__sys_send(s, mem, len, flags)) } #[no_mangle] @@ -745,11 +753,7 @@ pub extern "C" fn sys_shutdown_socket(s: i32, how: i32) -> i32 { #[no_mangle] pub extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { - if flags == 0 { - kernel_function!(__sys_recv(fd, buf, len)) - } else { - (-crate::errno::EINVAL).try_into().unwrap() - } + kernel_function!(__sys_recv(fd, buf, len, flags)) } #[no_mangle] diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index dfe07097d7..e5ce8bf02a 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -14,7 +14,7 @@ use crate::mm::{task_heap_end, task_heap_start}; use crate::scheduler::task::{Priority, TaskHandle, TaskId}; use crate::scheduler::PerCoreSchedulerExt; use crate::time::timespec; -use crate::{arch, scheduler, syscalls}; +use crate::{arch, scheduler}; #[cfg(feature = "newlib")] pub type SignalHandler = extern "C" fn(i32); @@ -52,9 +52,13 @@ pub extern "C" fn sys_setprio(_id: *const Tid, _prio: i32) -> i32 { -ENOSYS } -extern "C" fn __sys_exit(arg: i32) -> ! { +fn exit(arg: i32) -> ! { debug!("Exit program with error code {}!", arg); - syscalls::__sys_shutdown(arg) + super::shutdown(arg) +} + +extern "C" fn __sys_exit(arg: i32) -> ! { + exit(arg) } #[no_mangle] @@ -72,9 +76,13 @@ pub extern "C" fn sys_thread_exit(arg: i32) -> ! { kernel_function!(__sys_thread_exit(arg)) } +extern "C" fn __sys_abort() -> ! { + exit(-1) +} + #[no_mangle] pub extern "C" fn sys_abort() -> ! { - kernel_function!(__sys_exit(-1)) + kernel_function!(__sys_abort()) } #[cfg(feature = "newlib")] @@ -109,7 +117,7 @@ pub extern "C" fn sys_sbrk(incr: isize) -> usize { kernel_function!(__sys_sbrk(incr)) } -pub(crate) extern "C" fn __sys_usleep(usecs: u64) { +pub(super) fn usleep(usecs: u64) { if usecs >= 10_000 { // Enough time to set a wakeup timer and block the current task. debug!("sys_usleep blocking the task for {} microseconds", usecs); @@ -123,19 +131,27 @@ pub(crate) extern "C" fn __sys_usleep(usecs: u64) { // Not enough time to set a wakeup timer, so just do busy-waiting. let end = arch::processor::get_timestamp() + u64::from(get_frequency()) * usecs; while get_timestamp() < end { - __sys_yield(); + core_scheduler().reschedule(); } } } +pub(crate) extern "C" fn __sys_usleep(usecs: u64) { + usleep(usecs) +} + #[no_mangle] pub extern "C" fn sys_usleep(usecs: u64) { kernel_function!(__sys_usleep(usecs)) } +pub(crate) extern "C" fn __sys_msleep(ms: u32) { + usleep(u64::from(ms) * 1000) +} + #[no_mangle] pub extern "C" fn sys_msleep(ms: u32) { - kernel_function!(__sys_usleep(u64::from(ms) * 1000)) + kernel_function!(__sys_msleep(ms)) } extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 { @@ -154,7 +170,7 @@ extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i3 let microseconds = (requested_time.tv_sec as u64) * 1_000_000 + (requested_time.tv_nsec as u64) / 1_000; - __sys_usleep(microseconds); + usleep(microseconds); 0 } @@ -248,7 +264,8 @@ extern "C" fn __sys_spawn( prio: u8, selector: isize, ) -> i32 { - let new_id = __sys_spawn2(func, arg, prio, USER_STACK_SIZE, selector); + let new_id = + scheduler::spawn(func, arg, Priority::from(prio), USER_STACK_SIZE, selector).into(); if !id.is_null() { unsafe { @@ -286,7 +303,7 @@ pub extern "C" fn sys_join(id: Tid) -> i32 { static BLOCKED_TASKS: InterruptTicketMutex> = InterruptTicketMutex::new(BTreeMap::new()); -extern "C" fn __sys_block_current_task(timeout: &Option) { +fn block_current_task(timeout: &Option) { let wakeup_time = timeout.map(|t| arch::processor::get_timer_ticks() + t * 1000); let core_scheduler = core_scheduler(); let handle = core_scheduler.get_current_task_handle(); @@ -296,16 +313,24 @@ extern "C" fn __sys_block_current_task(timeout: &Option) { core_scheduler.block_current_task(wakeup_time); } +extern "C" fn __sys_block_current_task() { + block_current_task(&None) +} + /// Set the current task state to `blocked` #[no_mangle] pub extern "C" fn sys_block_current_task() { - kernel_function!(__sys_block_current_task(&None)) + kernel_function!(__sys_block_current_task()) +} + +extern "C" fn __sys_block_current_task_with_timeout(timeout: u64) { + block_current_task(&Some(timeout)) } /// Set the current task state to `blocked` #[no_mangle] pub extern "C" fn sys_block_current_task_with_timeout(timeout: u64) { - kernel_function!(__sys_block_current_task(&Some(timeout))) + kernel_function!(__sys_block_current_task_with_timeout(timeout)) } extern "C" fn __sys_wakeup_task(id: Tid) { diff --git a/src/syscalls/timer.rs b/src/syscalls/timer.rs index 2e63005c3d..b2dacbd747 100644 --- a/src/syscalls/timer.rs +++ b/src/syscalls/timer.rs @@ -1,6 +1,6 @@ use crate::arch; use crate::errno::*; -use crate::syscalls::__sys_usleep; +use crate::syscalls::usleep; use crate::time::{itimerval, timespec, timeval}; pub(crate) const CLOCK_REALTIME: u64 = 1; @@ -124,7 +124,7 @@ extern "C" fn __sys_clock_nanosleep( } } - __sys_usleep(microseconds); + usleep(microseconds); 0 } _ => -EINVAL, From 5187b10262f82b87f5df9c8b0b79dc58a0f3511f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Sat, 23 Mar 2024 12:16:54 +0100 Subject: [PATCH 10/12] fix(kernel_function): propagate unsafety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/arch/aarch64/kernel/scheduler.rs | 2 +- src/arch/aarch64/kernel/switch.rs | 2 +- src/arch/riscv64/kernel/scheduler.rs | 2 +- src/arch/x86_64/kernel/scheduler.rs | 2 +- src/arch/x86_64/kernel/switch.rs | 2 +- src/lib.rs | 10 ++- src/macros.rs | 80 +++++++++++++++++-- src/scheduler/mod.rs | 12 +-- src/scheduler/task.rs | 2 +- src/syscalls/condvar.rs | 20 ++--- src/syscalls/entropy.rs | 9 +-- src/syscalls/futex.rs | 12 +-- src/syscalls/lwip.rs | 6 +- src/syscalls/mod.rs | 115 ++++++++++++++++----------- src/syscalls/semaphore.rs | 42 +++++----- src/syscalls/socket.rs | 96 ++++++++++++---------- src/syscalls/spinlock.rs | 58 ++++++++------ src/syscalls/tasks.rs | 33 ++++---- src/syscalls/timer.rs | 36 ++++----- tests/thread.rs | 28 ++++--- 20 files changed, 344 insertions(+), 225 deletions(-) diff --git a/src/arch/aarch64/kernel/scheduler.rs b/src/arch/aarch64/kernel/scheduler.rs index 96e4d1f8aa..eb850c1800 100644 --- a/src/arch/aarch64/kernel/scheduler.rs +++ b/src/arch/aarch64/kernel/scheduler.rs @@ -338,7 +338,7 @@ extern "C" fn task_start(_f: extern "C" fn(usize), _arg: usize) -> ! { } impl TaskFrame for Task { - fn create_stack_frame(&mut self, func: extern "C" fn(usize), arg: usize) { + fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize) { // Check if TLS is allocated already and if the task uses thread-local storage. if self.tls.is_none() { self.tls = TaskTLS::from_environment(); diff --git a/src/arch/aarch64/kernel/switch.rs b/src/arch/aarch64/kernel/switch.rs index 9c3102e111..66c80573ae 100644 --- a/src/arch/aarch64/kernel/switch.rs +++ b/src/arch/aarch64/kernel/switch.rs @@ -5,7 +5,7 @@ macro_rules! kernel_function_impl { ($kernel_function:ident($($arg:ident: $A:ident),*) { $($operands:tt)* }) => { /// Executes `f` on the kernel stack. #[allow(dead_code)] - pub fn $kernel_function(f: unsafe extern "C" fn($($A),*) -> R, $($arg: $A),*) -> R { + pub unsafe fn $kernel_function(f: unsafe extern "C" fn($($A),*) -> R, $($arg: $A),*) -> R { unsafe { assert!(mem::size_of::() <= mem::size_of::()); diff --git a/src/arch/riscv64/kernel/scheduler.rs b/src/arch/riscv64/kernel/scheduler.rs index 611b9466fd..64bd1a5a94 100644 --- a/src/arch/riscv64/kernel/scheduler.rs +++ b/src/arch/riscv64/kernel/scheduler.rs @@ -379,7 +379,7 @@ extern "C" fn task_entry(func: extern "C" fn(usize), arg: usize) { } impl TaskFrame for Task { - fn create_stack_frame(&mut self, func: extern "C" fn(usize), arg: usize) { + fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize) { // Check if the task (process or thread) uses Thread-Local-Storage. // check is TLS is already allocated if self.tls.is_none() { diff --git a/src/arch/x86_64/kernel/scheduler.rs b/src/arch/x86_64/kernel/scheduler.rs index f6d39ea40d..80b38e006e 100644 --- a/src/arch/x86_64/kernel/scheduler.rs +++ b/src/arch/x86_64/kernel/scheduler.rs @@ -336,7 +336,7 @@ extern "C" fn task_entry(func: extern "C" fn(usize), arg: usize) -> ! { } impl TaskFrame for Task { - fn create_stack_frame(&mut self, func: extern "C" fn(usize), arg: usize) { + fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize) { // Check if TLS is allocated already and if the task uses thread-local storage. #[cfg(not(feature = "common-os"))] if self.tls.is_none() { diff --git a/src/arch/x86_64/kernel/switch.rs b/src/arch/x86_64/kernel/switch.rs index 49368aeae2..a970845cf8 100644 --- a/src/arch/x86_64/kernel/switch.rs +++ b/src/arch/x86_64/kernel/switch.rs @@ -220,7 +220,7 @@ macro_rules! kernel_function_impl { ($kernel_function:ident($($arg:ident: $A:ident),*) { $($operands:tt)* }) => { /// Executes `f` on the kernel stack. #[allow(dead_code)] - pub fn $kernel_function(f: unsafe extern "C" fn($($A),*) -> R, $($arg: $A),*) -> R { + pub unsafe fn $kernel_function(f: unsafe extern "C" fn($($A),*) -> R, $($arg: $A),*) -> R { unsafe { assert!(mem::size_of::() <= mem::size_of::()); diff --git a/src/lib.rs b/src/lib.rs index 54aef2c46b..0e8992a1ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -239,7 +239,15 @@ fn boot_processor_main() -> ! { } // Start the initd task. - scheduler::PerCoreScheduler::spawn(initd, 0, scheduler::task::NORMAL_PRIO, 0, USER_STACK_SIZE); + unsafe { + scheduler::PerCoreScheduler::spawn( + initd, + 0, + scheduler::task::NORMAL_PRIO, + 0, + USER_STACK_SIZE, + ) + }; // Run the scheduler loop. PerCoreScheduler::run(); diff --git a/src/macros.rs b/src/macros.rs index 221b9475ff..b63426156d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -80,45 +80,109 @@ macro_rules! dbg { macro_rules! kernel_function { ($f:ident()) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f(); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function0($f).set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function0($f).set_errno() + } }}; ($f:ident($arg1:expr)) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f($arg1); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function1($f, $arg1).set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function1($f, $arg1).set_errno() + } }}; ($f:ident($arg1:expr, $arg2:expr)) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f($arg1, $arg2); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function2($f, $arg1, $arg2).set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function2($f, $arg1, $arg2).set_errno() + } }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr)) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f($arg1, $arg2, $arg3); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function3($f, $arg1, $arg2, $arg3).set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function3($f, $arg1, $arg2, $arg3).set_errno() + } }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr)) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f($arg1, $arg2, $arg3, $arg4); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function4($f, $arg1, $arg2, $arg3, $arg4).set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function4($f, $arg1, $arg2, $arg3, $arg4).set_errno() + } }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr)) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f($arg1, $arg2, $arg3, $arg4, $arg5); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function5($f, $arg1, $arg2, $arg3, $arg4, $arg5).set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function5($f, $arg1, $arg2, $arg3, $arg4, $arg5) + .set_errno() + } }}; ($f:ident($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr, $arg6:expr)) => {{ use $crate::errno::ToErrno; + + // This propagates any unsafety requirements of `f` to the caller. + if false { + $f($arg1, $arg2, $arg3, $arg4, $arg5, $arg6); + } + #[allow(unreachable_code)] - $crate::arch::switch::kernel_function6($f, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6) - .set_errno() + #[allow(unused_unsafe)] + unsafe { + $crate::arch::switch::kernel_function6($f, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6) + .set_errno() + } }}; } diff --git a/src/scheduler/mod.rs b/src/scheduler/mod.rs index 0847db7f2c..fd2c774701 100644 --- a/src/scheduler/mod.rs +++ b/src/scheduler/mod.rs @@ -203,7 +203,7 @@ impl PerCoreSchedulerExt for &mut PerCoreScheduler { struct NewTask { tid: TaskId, - func: extern "C" fn(usize), + func: unsafe extern "C" fn(usize), arg: usize, prio: Priority, core_id: CoreId, @@ -231,8 +231,8 @@ impl From for Task { impl PerCoreScheduler { /// Spawn a new task. - pub fn spawn( - func: extern "C" fn(usize), + pub unsafe fn spawn( + func: unsafe extern "C" fn(usize), arg: usize, prio: Priority, core_id: CoreId, @@ -941,8 +941,8 @@ fn get_scheduler_input(core_id: CoreId) -> &'static InterruptTicketMutex TaskId { diff --git a/src/scheduler/task.rs b/src/scheduler/task.rs index 6b31a97956..d6ff54061c 100644 --- a/src/scheduler/task.rs +++ b/src/scheduler/task.rs @@ -406,7 +406,7 @@ pub(crate) struct Task { pub(crate) trait TaskFrame { /// Create the initial stack frame for a new task - fn create_stack_frame(&mut self, func: extern "C" fn(usize), arg: usize); + fn create_stack_frame(&mut self, func: unsafe extern "C" fn(usize), arg: usize); } impl Task { diff --git a/src/syscalls/condvar.rs b/src/syscalls/condvar.rs index 1ec6f6e994..0474a7e7bd 100644 --- a/src/syscalls/condvar.rs +++ b/src/syscalls/condvar.rs @@ -23,7 +23,7 @@ impl CondQueue { } } -extern "C" fn __sys_destroy_queue(ptr: usize) -> i32 { +unsafe extern "C" fn __sys_destroy_queue(ptr: usize) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -42,10 +42,10 @@ extern "C" fn __sys_destroy_queue(ptr: usize) -> i32 { #[no_mangle] pub unsafe extern "C" fn sys_destroy_queue(ptr: usize) -> i32 { - kernel_function!(__sys_destroy_queue(ptr)) + unsafe { kernel_function!(__sys_destroy_queue(ptr)) } } -extern "C" fn __sys_notify(ptr: usize, count: i32) -> i32 { +unsafe extern "C" fn __sys_notify(ptr: usize, count: i32) -> i32 { unsafe { let id = ptr::from_exposed_addr::(ptr); @@ -83,10 +83,10 @@ extern "C" fn __sys_notify(ptr: usize, count: i32) -> i32 { #[no_mangle] pub unsafe extern "C" fn sys_notify(ptr: usize, count: i32) -> i32 { - kernel_function!(__sys_notify(ptr, count)) + unsafe { kernel_function!(__sys_notify(ptr, count)) } } -extern "C" fn __sys_init_queue(ptr: usize) -> i32 { +unsafe extern "C" fn __sys_init_queue(ptr: usize) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -106,10 +106,10 @@ extern "C" fn __sys_init_queue(ptr: usize) -> i32 { #[no_mangle] pub unsafe extern "C" fn sys_init_queue(ptr: usize) -> i32 { - kernel_function!(__sys_init_queue(ptr)) + unsafe { kernel_function!(__sys_init_queue(ptr)) } } -extern "C" fn __sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { +unsafe extern "C" fn __sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -138,10 +138,10 @@ extern "C" fn __sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { #[no_mangle] pub unsafe extern "C" fn sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { - kernel_function!(__sys_add_queue(ptr, timeout_ns)) + unsafe { kernel_function!(__sys_add_queue(ptr, timeout_ns)) } } -extern "C" fn __sys_wait(ptr: usize) -> i32 { +unsafe extern "C" fn __sys_wait(ptr: usize) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -164,5 +164,5 @@ extern "C" fn __sys_wait(ptr: usize) -> i32 { #[no_mangle] pub unsafe extern "C" fn sys_wait(ptr: usize) -> i32 { - kernel_function!(__sys_wait(ptr)) + unsafe { kernel_function!(__sys_wait(ptr)) } } diff --git a/src/syscalls/entropy.rs b/src/syscalls/entropy.rs index 8a8bc5dce4..5d61f9b644 100644 --- a/src/syscalls/entropy.rs +++ b/src/syscalls/entropy.rs @@ -53,10 +53,9 @@ unsafe extern "C" fn __sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> /// Returns either the number of bytes written to buf (a positive value) or /// * `-EINVAL` if `flags` contains unknown flags. /// * `-ENOSYS` if the system does not support random data generation. -#[allow(unsafe_op_in_unsafe_fn)] #[no_mangle] pub unsafe extern "C" fn sys_read_entropy(buf: *mut u8, len: usize, flags: u32) -> isize { - kernel_function!(__sys_read_entropy(buf, len, flags)) + unsafe { kernel_function!(__sys_read_entropy(buf, len, flags)) } } #[cfg(not(feature = "newlib"))] @@ -81,10 +80,9 @@ unsafe extern "C" fn __sys_secure_rand32(value: *mut u32) -> i32 { /// the underlying hardware. If the required hardware isn't available, /// the function returns `-1`. #[cfg(not(feature = "newlib"))] -#[allow(unsafe_op_in_unsafe_fn)] #[no_mangle] pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { - kernel_function!(__sys_secure_rand32(value)) + unsafe { kernel_function!(__sys_secure_rand32(value)) } } #[cfg(not(feature = "newlib"))] @@ -109,10 +107,9 @@ unsafe extern "C" fn __sys_secure_rand64(value: *mut u64) -> i32 { /// the underlying hardware. If the required hardware isn't available, /// the function returns -1. #[cfg(not(feature = "newlib"))] -#[allow(unsafe_op_in_unsafe_fn)] #[no_mangle] pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { - kernel_function!(__sys_secure_rand64(value)) + unsafe { kernel_function!(__sys_secure_rand64(value)) } } extern "C" fn __sys_rand() -> u32 { diff --git a/src/syscalls/futex.rs b/src/syscalls/futex.rs index 649aa46750..fc942d756e 100644 --- a/src/syscalls/futex.rs +++ b/src/syscalls/futex.rs @@ -10,7 +10,7 @@ use crate::time::timespec; /// * `address` is null /// * `timeout` is negative /// * `flags` contains unknown flags -extern "C" fn __sys_futex_wait( +unsafe extern "C" fn __sys_futex_wait( address: *mut u32, expected: u32, timeout: *const timespec, @@ -38,19 +38,19 @@ extern "C" fn __sys_futex_wait( } #[no_mangle] -pub extern "C" fn sys_futex_wait( +pub unsafe extern "C" fn sys_futex_wait( address: *mut u32, expected: u32, timeout: *const timespec, flags: u32, ) -> i32 { - kernel_function!(__sys_futex_wait(address, expected, timeout, flags)) + unsafe { kernel_function!(__sys_futex_wait(address, expected, timeout, flags)) } } /// Like `synch::futex_wake`, but does extra sanity checks. /// /// Returns -EINVAL if `address` is null. -extern "C" fn __sys_futex_wake(address: *mut u32, count: i32) -> i32 { +unsafe extern "C" fn __sys_futex_wake(address: *mut u32, count: i32) -> i32 { if address.is_null() { return -EINVAL; } @@ -60,6 +60,6 @@ extern "C" fn __sys_futex_wake(address: *mut u32, count: i32) -> i32 { } #[no_mangle] -pub extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { - kernel_function!(__sys_futex_wake(address, count)) +pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { + unsafe { kernel_function!(__sys_futex_wake(address, count)) } } diff --git a/src/syscalls/lwip.rs b/src/syscalls/lwip.rs index b905853d0e..2747056115 100644 --- a/src/syscalls/lwip.rs +++ b/src/syscalls/lwip.rs @@ -42,13 +42,13 @@ pub extern "C" fn sys_putchar(character: u8) { kernel_function!(__sys_putchar(character)) } -extern "C" fn __sys_release_putchar_lock() { +unsafe extern "C" fn __sys_release_putchar_lock() { unsafe { console::CONSOLE.force_unlock(); } } #[no_mangle] -pub extern "C" fn sys_release_putchar_lock() { - kernel_function!(__sys_release_putchar_lock()) +pub unsafe extern "C" fn sys_release_putchar_lock() { + unsafe { kernel_function!(__sys_release_putchar_lock()) } } diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 4c052a02ec..07f7fe4f56 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -129,7 +129,7 @@ pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { /// Returns null if the new layout does not meet the size and alignment constraints of the /// allocator, or if reallocation otherwise fails. #[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) extern "C" fn __sys_realloc( +pub(crate) unsafe extern "C" fn __sys_realloc( ptr: *mut u8, size: usize, align: usize, @@ -165,8 +165,13 @@ pub(crate) extern "C" fn __sys_realloc( #[cfg(all(target_os = "none", not(feature = "common-os")))] #[no_mangle] -pub extern "C" fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8 { - kernel_function!(__sys_realloc(ptr, size, align, new_size)) +pub unsafe extern "C" fn sys_realloc( + ptr: *mut u8, + size: usize, + align: usize, + new_size: usize, +) -> *mut u8 { + unsafe { kernel_function!(__sys_realloc(ptr, size, align, new_size)) } } /// Interface to deallocate a memory region from the system heap @@ -180,7 +185,7 @@ pub extern "C" fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: /// # Errors /// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed. #[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usize) { +pub(crate) unsafe extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usize) { unsafe { let layout_res = Layout::from_size_align(size, align); if layout_res.is_err() || size == 0 { @@ -204,8 +209,8 @@ pub(crate) extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usize) { #[cfg(all(target_os = "none", not(feature = "common-os")))] #[no_mangle] -pub extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { - kernel_function!(__sys_free(ptr, size, align)) +pub unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { + unsafe { kernel_function!(__sys_free(ptr, size, align)) } } pub(crate) fn get_application_parameters() -> (i32, *const *const u8, *const *const u8) { @@ -228,7 +233,7 @@ pub extern "C" fn sys_shutdown(arg: i32) -> ! { kernel_function!(__sys_shutdown(arg)) } -extern "C" fn __sys_unlink(name: *const u8) -> i32 { +unsafe extern "C" fn __sys_unlink(name: *const u8) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); fs::FILESYSTEM @@ -239,11 +244,11 @@ extern "C" fn __sys_unlink(name: *const u8) -> i32 { } #[no_mangle] -pub extern "C" fn sys_unlink(name: *const u8) -> i32 { - kernel_function!(__sys_unlink(name)) +pub unsafe extern "C" fn sys_unlink(name: *const u8) -> i32 { + unsafe { kernel_function!(__sys_unlink(name)) } } -extern "C" fn __sys_mkdir(name: *const u8, mode: u32) -> i32 { +unsafe extern "C" fn __sys_mkdir(name: *const u8, mode: u32) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); let mode = if let Some(mode) = AccessPermission::from_bits(mode) { mode @@ -259,11 +264,11 @@ extern "C" fn __sys_mkdir(name: *const u8, mode: u32) -> i32 { } #[no_mangle] -pub extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 { - kernel_function!(__sys_mkdir(name, mode)) +pub unsafe extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 { + unsafe { kernel_function!(__sys_mkdir(name, mode)) } } -extern "C" fn __sys_rmdir(name: *const u8) -> i32 { +unsafe extern "C" fn __sys_rmdir(name: *const u8) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); fs::FILESYSTEM @@ -274,11 +279,11 @@ extern "C" fn __sys_rmdir(name: *const u8) -> i32 { } #[no_mangle] -pub extern "C" fn sys_rmdir(name: *const u8) -> i32 { - kernel_function!(__sys_rmdir(name)) +pub unsafe extern "C" fn sys_rmdir(name: *const u8) -> i32 { + unsafe { kernel_function!(__sys_rmdir(name)) } } -extern "C" fn __sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { +unsafe extern "C" fn __sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); match fs::FILESYSTEM.get().unwrap().stat(name) { @@ -291,11 +296,11 @@ extern "C" fn __sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { } #[no_mangle] -pub extern "C" fn sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { - kernel_function!(__sys_stat(name, stat)) +pub unsafe extern "C" fn sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { + unsafe { kernel_function!(__sys_stat(name, stat)) } } -extern "C" fn __sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { +unsafe extern "C" fn __sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); match fs::FILESYSTEM.get().unwrap().lstat(name) { @@ -308,11 +313,11 @@ extern "C" fn __sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { } #[no_mangle] -pub extern "C" fn sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { - kernel_function!(__sys_lstat(name, stat)) +pub unsafe extern "C" fn sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { + unsafe { kernel_function!(__sys_lstat(name, stat)) } } -extern "C" fn __sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { +unsafe extern "C" fn __sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { let stat = unsafe { &mut *stat }; let obj = get_object(fd); obj.map_or_else( @@ -325,11 +330,11 @@ extern "C" fn __sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { } #[no_mangle] -pub extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { - kernel_function!(__sys_fstat(fd, stat)) +pub unsafe extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { + unsafe { kernel_function!(__sys_fstat(fd, stat)) } } -extern "C" fn __sys_opendir(name: *const u8) -> FileDescriptor { +unsafe extern "C" fn __sys_opendir(name: *const u8) -> FileDescriptor { if let Ok(name) = unsafe { CStr::from_ptr(name as _) }.to_str() { crate::fs::opendir(name).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) } else { @@ -338,11 +343,11 @@ extern "C" fn __sys_opendir(name: *const u8) -> FileDescriptor { } #[no_mangle] -pub extern "C" fn sys_opendir(name: *const u8) -> FileDescriptor { - kernel_function!(__sys_opendir(name)) +pub unsafe extern "C" fn sys_opendir(name: *const u8) -> FileDescriptor { + unsafe { kernel_function!(__sys_opendir(name)) } } -extern "C" fn __sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { +unsafe extern "C" fn __sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { let flags = if let Some(flags) = OpenOption::from_bits(flags) { flags } else { @@ -363,8 +368,8 @@ extern "C" fn __sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescript } #[no_mangle] -pub extern "C" fn sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { - kernel_function!(__sys_open(name, flags, mode)) +pub unsafe extern "C" fn sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { + unsafe { kernel_function!(__sys_open(name, flags, mode)) } } extern "C" fn __sys_close(fd: FileDescriptor) -> i32 { @@ -377,7 +382,7 @@ pub extern "C" fn sys_close(fd: FileDescriptor) -> i32 { kernel_function!(__sys_close(fd)) } -extern "C" fn __sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { +unsafe extern "C" fn __sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) }; crate::fd::read(fd, slice).map_or_else( |e| -num::ToPrimitive::to_isize(&e).unwrap(), @@ -386,11 +391,11 @@ extern "C" fn __sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize } #[no_mangle] -pub extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { - kernel_function!(__sys_read(fd, buf, len)) +pub unsafe extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { + unsafe { kernel_function!(__sys_read(fd, buf, len)) } } -fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { +unsafe fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { let slice = unsafe { core::slice::from_raw_parts(buf, len) }; crate::fd::write(fd, slice).map_or_else( |e| -num::ToPrimitive::to_isize(&e).unwrap(), @@ -398,16 +403,20 @@ fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { ) } -extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { - write(fd, buf, len) +unsafe extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { + unsafe { write(fd, buf, len) } } #[no_mangle] -pub extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { - kernel_function!(__sys_write(fd, buf, len)) +pub unsafe extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { + unsafe { kernel_function!(__sys_write(fd, buf, len)) } } -extern "C" fn __sys_ioctl(fd: FileDescriptor, cmd: i32, argp: *mut core::ffi::c_void) -> i32 { +unsafe extern "C" fn __sys_ioctl( + fd: FileDescriptor, + cmd: i32, + argp: *mut core::ffi::c_void, +) -> i32 { const FIONBIO: i32 = 0x8008667eu32 as i32; if cmd == FIONBIO { @@ -427,8 +436,12 @@ extern "C" fn __sys_ioctl(fd: FileDescriptor, cmd: i32, argp: *mut core::ffi::c_ } #[no_mangle] -pub extern "C" fn sys_ioctl(fd: FileDescriptor, cmd: i32, argp: *mut core::ffi::c_void) -> i32 { - kernel_function!(__sys_ioctl(fd, cmd, argp)) +pub unsafe extern "C" fn sys_ioctl( + fd: FileDescriptor, + cmd: i32, + argp: *mut core::ffi::c_void, +) -> i32 { + unsafe { kernel_function!(__sys_ioctl(fd, cmd, argp)) } } extern "C" fn __sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { @@ -490,7 +503,11 @@ pub struct Dirent64 { pub d_name: PhantomData, } -extern "C" fn __sys_getdents64(fd: FileDescriptor, dirp: *mut Dirent64, count: usize) -> i64 { +unsafe extern "C" fn __sys_getdents64( + fd: FileDescriptor, + dirp: *mut Dirent64, + count: usize, +) -> i64 { if dirp.is_null() || count == 0 { return -crate::errno::EINVAL as i64; } @@ -541,8 +558,12 @@ extern "C" fn __sys_getdents64(fd: FileDescriptor, dirp: *mut Dirent64, count: u } #[no_mangle] -pub extern "C" fn sys_getdents64(fd: FileDescriptor, dirp: *mut Dirent64, count: usize) -> i64 { - kernel_function!(__sys_getdents64(fd, dirp, count)) +pub unsafe extern "C" fn sys_getdents64( + fd: FileDescriptor, + dirp: *mut Dirent64, + count: usize, +) -> i64 { + unsafe { kernel_function!(__sys_getdents64(fd, dirp, count)) } } extern "C" fn __sys_dup(fd: i32) -> i32 { @@ -554,7 +575,7 @@ pub extern "C" fn sys_dup(fd: i32) -> i32 { kernel_function!(__sys_dup(fd)) } -extern "C" fn __sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { +unsafe extern "C" fn __sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { let slice = unsafe { core::slice::from_raw_parts_mut(fds, nfds) }; let timeout = if timeout >= 0 { Some(core::time::Duration::from_millis( @@ -577,8 +598,8 @@ extern "C" fn __sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { } #[no_mangle] -pub extern "C" fn sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { - kernel_function!(__sys_poll(fds, nfds, timeout)) +pub unsafe extern "C" fn sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { + unsafe { kernel_function!(__sys_poll(fds, nfds, timeout)) } } extern "C" fn __sys_eventfd(initval: u64, flags: i16) -> i32 { diff --git a/src/syscalls/semaphore.rs b/src/syscalls/semaphore.rs index 03f1da86f3..16f3a748e4 100644 --- a/src/syscalls/semaphore.rs +++ b/src/syscalls/semaphore.rs @@ -9,7 +9,7 @@ use crate::synch::semaphore::Semaphore; /// /// Stores the raw memory location of the new semaphore in parameter `sem`. /// Returns `0` on success, `-EINVAL` if `sem` is null. -extern "C" fn __sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { +unsafe extern "C" fn __sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { if sem.is_null() { return -EINVAL; } @@ -23,8 +23,8 @@ extern "C" fn __sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { } #[no_mangle] -pub extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { - kernel_function!(__sys_sem_init(sem, value)) +pub unsafe extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { + unsafe { kernel_function!(__sys_sem_init(sem, value)) } } /// Destroy and deallocate a semaphore. @@ -32,7 +32,7 @@ pub extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { /// This function can be used to manually deallocate a semaphore via a reference. /// /// Returns `0` on success, `-EINVAL` if `sem` is null. -extern "C" fn __sys_sem_destroy(sem: *mut Semaphore) -> i32 { +unsafe extern "C" fn __sys_sem_destroy(sem: *mut Semaphore) -> i32 { if sem.is_null() { return -EINVAL; } @@ -46,8 +46,8 @@ extern "C" fn __sys_sem_destroy(sem: *mut Semaphore) -> i32 { } #[no_mangle] -pub extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { - kernel_function!(__sys_sem_destroy(sem)) +pub unsafe extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { + unsafe { kernel_function!(__sys_sem_destroy(sem)) } } /// Release a semaphore. @@ -57,7 +57,7 @@ pub extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { /// The semaphore is not deallocated after being released. /// /// Returns `0` on success, or `-EINVAL` if `sem` is null. -extern "C" fn __sys_sem_post(sem: *const Semaphore) -> i32 { +unsafe extern "C" fn __sys_sem_post(sem: *const Semaphore) -> i32 { if sem.is_null() { return -EINVAL; } @@ -69,8 +69,8 @@ extern "C" fn __sys_sem_post(sem: *const Semaphore) -> i32 { } #[no_mangle] -pub extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 { - kernel_function!(__sys_sem_post(sem)) +pub unsafe extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 { + unsafe { kernel_function!(__sys_sem_post(sem)) } } /// Try to acquire a lock on a semaphore. @@ -79,7 +79,7 @@ pub extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 { /// If the acquire fails (i.e. the semaphore's count is already 0), the function returns immediately. /// /// Returns `0` on lock acquire, `-EINVAL` if `sem` is null, or `-ECANCELED` if the decrement fails. -extern "C" fn __sys_sem_trywait(sem: *const Semaphore) -> i32 { +unsafe extern "C" fn __sys_sem_trywait(sem: *const Semaphore) -> i32 { if sem.is_null() { return -EINVAL; } @@ -94,11 +94,11 @@ extern "C" fn __sys_sem_trywait(sem: *const Semaphore) -> i32 { } #[no_mangle] -pub extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 { - kernel_function!(__sys_sem_trywait(sem)) +pub unsafe extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 { + unsafe { kernel_function!(__sys_sem_trywait(sem)) } } -fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { +unsafe fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { if sem.is_null() { return -EINVAL; } @@ -119,20 +119,20 @@ fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { /// Blocks until semaphore is acquired or until wake-up time has elapsed. /// /// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout. -extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { - sem_timedwait(sem, ms) +unsafe extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { + unsafe { sem_timedwait(sem, ms) } } #[no_mangle] -pub extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { - kernel_function!(__sys_sem_timedwait(sem, ms)) +pub unsafe extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { + unsafe { kernel_function!(__sys_sem_timedwait(sem, ms)) } } -extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { - sem_timedwait(sem, ms) +unsafe extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { + unsafe { sem_timedwait(sem, ms) } } #[no_mangle] -pub extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { - kernel_function!(__sys_sem_cancelablewait(sem, ms)) +pub unsafe extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { + unsafe { kernel_function!(__sys_sem_cancelablewait(sem, ms)) } } diff --git a/src/syscalls/socket.rs b/src/syscalls/socket.rs index 513106196f..8f9d7c8a68 100644 --- a/src/syscalls/socket.rs +++ b/src/syscalls/socket.rs @@ -308,7 +308,7 @@ extern "C" fn __sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 { } } -extern "C" fn __sys_accept(fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { +unsafe extern "C" fn __sys_accept(fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_i32(&e).unwrap(), @@ -359,7 +359,7 @@ extern "C" fn __sys_listen(fd: i32, backlog: i32) -> i32 { ) } -extern "C" fn __sys_bind(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { +unsafe extern "C" fn __sys_bind(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { let endpoint = if namelen == size_of::().try_into().unwrap() { IpListenEndpoint::from(unsafe { *(name as *const sockaddr_in) }) } else if namelen == size_of::().try_into().unwrap() { @@ -378,7 +378,7 @@ extern "C" fn __sys_bind(fd: i32, name: *const sockaddr, namelen: socklen_t) -> ) } -extern "C" fn __sys_connect(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { +unsafe extern "C" fn __sys_connect(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { let endpoint = if namelen == size_of::().try_into().unwrap() { IpEndpoint::from(unsafe { *(name as *const sockaddr_in) }) } else if namelen == size_of::().try_into().unwrap() { @@ -397,7 +397,11 @@ extern "C" fn __sys_connect(fd: i32, name: *const sockaddr, namelen: socklen_t) ) } -extern "C" fn __sys_getsockname(fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { +unsafe extern "C" fn __sys_getsockname( + fd: i32, + addr: *mut sockaddr, + addrlen: *mut socklen_t, +) -> i32 { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_i32(&e).unwrap(), @@ -436,7 +440,7 @@ extern "C" fn __sys_getsockname(fd: i32, addr: *mut sockaddr, addrlen: *mut sock ) } -extern "C" fn __sys_setsockopt( +unsafe extern "C" fn __sys_setsockopt( fd: i32, level: i32, optname: i32, @@ -472,7 +476,7 @@ extern "C" fn __sys_setsockopt( } } -extern "C" fn __sys_getsockopt( +unsafe extern "C" fn __sys_getsockopt( fd: i32, level: i32, optname: i32, @@ -515,7 +519,11 @@ extern "C" fn __sys_getsockopt( } } -extern "C" fn __sys_getpeername(fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { +unsafe extern "C" fn __sys_getpeername( + fd: i32, + addr: *mut sockaddr, + addrlen: *mut socklen_t, +) -> i32 { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_i32(&e).unwrap(), @@ -554,9 +562,9 @@ extern "C" fn __sys_getpeername(fd: i32, addr: *mut sockaddr, addrlen: *mut sock ) } -extern "C" fn __sys_freeaddrinfo(_ai: *mut addrinfo) {} +unsafe extern "C" fn __sys_freeaddrinfo(_ai: *mut addrinfo) {} -extern "C" fn __sys_getaddrinfo( +unsafe extern "C" fn __sys_getaddrinfo( _nodename: *const u8, _servname: *const u8, _hints: *const addrinfo, @@ -565,8 +573,8 @@ extern "C" fn __sys_getaddrinfo( -EINVAL } -extern "C" fn __sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize { - super::write(s, mem.cast(), len) +unsafe extern "C" fn __sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize { + unsafe { super::write(s, mem.cast(), len) } } extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 { @@ -580,7 +588,7 @@ extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 { ) } -extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { +unsafe extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { if flags == 0 { let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) }; crate::fd::read(fd, slice).map_or_else( @@ -592,7 +600,7 @@ extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize } } -extern "C" fn __sys_sendto( +unsafe extern "C" fn __sys_sendto( fd: i32, buf: *const u8, len: usize, @@ -621,7 +629,7 @@ extern "C" fn __sys_sendto( ) } -extern "C" fn __sys_recvfrom( +unsafe extern "C" fn __sys_recvfrom( fd: i32, buf: *mut u8, len: usize, @@ -675,8 +683,8 @@ pub extern "C" fn sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 } #[no_mangle] -pub extern "C" fn sys_accept(s: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { - kernel_function!(__sys_accept(s, addr, addrlen)) +pub unsafe extern "C" fn sys_accept(s: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { + unsafe { kernel_function!(__sys_accept(s, addr, addrlen)) } } #[no_mangle] @@ -685,65 +693,73 @@ pub extern "C" fn sys_listen(s: i32, backlog: i32) -> i32 { } #[no_mangle] -pub extern "C" fn sys_bind(s: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { - kernel_function!(__sys_bind(s, name, namelen)) +pub unsafe extern "C" fn sys_bind(s: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { + unsafe { kernel_function!(__sys_bind(s, name, namelen)) } } #[no_mangle] -pub extern "C" fn sys_connect(s: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { - kernel_function!(__sys_connect(s, name, namelen)) +pub unsafe extern "C" fn sys_connect(s: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { + unsafe { kernel_function!(__sys_connect(s, name, namelen)) } } #[no_mangle] -pub extern "C" fn sys_getsockname(s: i32, name: *mut sockaddr, namelen: *mut socklen_t) -> i32 { - kernel_function!(__sys_getsockname(s, name, namelen)) +pub unsafe extern "C" fn sys_getsockname( + s: i32, + name: *mut sockaddr, + namelen: *mut socklen_t, +) -> i32 { + unsafe { kernel_function!(__sys_getsockname(s, name, namelen)) } } #[no_mangle] -pub extern "C" fn sys_setsockopt( +pub unsafe extern "C" fn sys_setsockopt( s: i32, level: i32, optname: i32, optval: *const c_void, optlen: socklen_t, ) -> i32 { - kernel_function!(__sys_setsockopt(s, level, optname, optval, optlen)) + unsafe { kernel_function!(__sys_setsockopt(s, level, optname, optval, optlen)) } } #[no_mangle] -pub extern "C" fn sys_getsockopt( +pub unsafe extern "C" fn sys_getsockopt( s: i32, level: i32, optname: i32, optval: *mut c_void, optlen: *mut socklen_t, ) -> i32 { - kernel_function!(__sys_getsockopt(s, level, optname, optval, optlen)) + unsafe { kernel_function!(__sys_getsockopt(s, level, optname, optval, optlen)) } } #[no_mangle] -pub extern "C" fn sys_getpeername(s: i32, name: *mut sockaddr, namelen: *mut socklen_t) -> i32 { - kernel_function!(__sys_getpeername(s, name, namelen)) +pub unsafe extern "C" fn sys_getpeername( + s: i32, + name: *mut sockaddr, + namelen: *mut socklen_t, +) -> i32 { + unsafe { kernel_function!(__sys_getpeername(s, name, namelen)) } } #[no_mangle] -pub extern "C" fn sys_freeaddrinfo(ai: *mut addrinfo) { - kernel_function!(__sys_freeaddrinfo(ai)) +pub unsafe extern "C" fn sys_freeaddrinfo(ai: *mut addrinfo) { + unsafe { kernel_function!(__sys_freeaddrinfo(ai)) } } #[no_mangle] -pub extern "C" fn sys_getaddrinfo( +pub unsafe extern "C" fn sys_getaddrinfo( nodename: *const u8, servname: *const u8, hints: *const addrinfo, res: *mut *mut addrinfo, ) -> i32 { - kernel_function!(__sys_getaddrinfo(nodename, servname, hints, res)) + unsafe { kernel_function!(__sys_getaddrinfo(nodename, servname, hints, res)) } } #[no_mangle] -pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, flags: i32) -> isize { - kernel_function!(__sys_send(s, mem, len, flags)) +pub unsafe extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, flags: i32) -> isize { + unsafe { kernel_function!(__sys_send(s, mem, len, flags)) } } #[no_mangle] @@ -752,12 +768,12 @@ pub extern "C" fn sys_shutdown_socket(s: i32, how: i32) -> i32 { } #[no_mangle] -pub extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { - kernel_function!(__sys_recv(fd, buf, len, flags)) +pub unsafe extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { + unsafe { kernel_function!(__sys_recv(fd, buf, len, flags)) } } #[no_mangle] -pub extern "C" fn sys_sendto( +pub unsafe extern "C" fn sys_sendto( socket: i32, buf: *const u8, len: usize, @@ -765,11 +781,11 @@ pub extern "C" fn sys_sendto( addr: *const sockaddr, addrlen: socklen_t, ) -> isize { - kernel_function!(__sys_sendto(socket, buf, len, flags, addr, addrlen)) + unsafe { kernel_function!(__sys_sendto(socket, buf, len, flags, addr, addrlen)) } } #[no_mangle] -pub extern "C" fn sys_recvfrom( +pub unsafe extern "C" fn sys_recvfrom( socket: i32, buf: *mut u8, len: usize, @@ -777,5 +793,5 @@ pub extern "C" fn sys_recvfrom( addr: *mut sockaddr, addrlen: *mut socklen_t, ) -> isize { - kernel_function!(__sys_recvfrom(socket, buf, len, flags, addr, addrlen)) + unsafe { kernel_function!(__sys_recvfrom(socket, buf, len, flags, addr, addrlen)) } } diff --git a/src/syscalls/spinlock.rs b/src/syscalls/spinlock.rs index 9551c8de1a..515bc8bc6e 100644 --- a/src/syscalls/spinlock.rs +++ b/src/syscalls/spinlock.rs @@ -14,7 +14,7 @@ pub struct SpinlockIrqSaveContainer<'a> { guard: Option>, } -extern "C" fn __sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -30,11 +30,11 @@ extern "C" fn __sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 } #[no_mangle] -pub extern "C" fn sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_init(lock)) +pub unsafe extern "C" fn sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { + unsafe { kernel_function!(__sys_spinlock_init(lock)) } } -extern "C" fn __sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -47,11 +47,11 @@ extern "C" fn __sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { } #[no_mangle] -pub extern "C" fn sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_destroy(lock)) +pub unsafe extern "C" fn sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { + unsafe { kernel_function!(__sys_spinlock_destroy(lock)) } } -extern "C" fn __sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -66,11 +66,11 @@ extern "C" fn __sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { } #[no_mangle] -pub extern "C" fn sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_lock(lock)) +pub unsafe extern "C" fn sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { + unsafe { kernel_function!(__sys_spinlock_lock(lock)) } } -extern "C" fn __sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -85,11 +85,13 @@ extern "C" fn __sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { } #[no_mangle] -pub extern "C" fn sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_unlock(lock)) +pub unsafe extern "C" fn sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { + unsafe { kernel_function!(__sys_spinlock_unlock(lock)) } } -extern "C" fn __sys_spinlock_irqsave_init(lock: *mut *mut SpinlockIrqSaveContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_irqsave_init( + lock: *mut *mut SpinlockIrqSaveContainer<'_>, +) -> i32 { if lock.is_null() { return -EINVAL; } @@ -105,11 +107,15 @@ extern "C" fn __sys_spinlock_irqsave_init(lock: *mut *mut SpinlockIrqSaveContain } #[no_mangle] -pub extern "C" fn sys_spinlock_irqsave_init(lock: *mut *mut SpinlockIrqSaveContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_irqsave_init(lock)) +pub unsafe extern "C" fn sys_spinlock_irqsave_init( + lock: *mut *mut SpinlockIrqSaveContainer<'_>, +) -> i32 { + unsafe { kernel_function!(__sys_spinlock_irqsave_init(lock)) } } -extern "C" fn __sys_spinlock_irqsave_destroy(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_irqsave_destroy( + lock: *mut SpinlockIrqSaveContainer<'_>, +) -> i32 { if lock.is_null() { return -EINVAL; } @@ -122,11 +128,13 @@ extern "C" fn __sys_spinlock_irqsave_destroy(lock: *mut SpinlockIrqSaveContainer } #[no_mangle] -pub extern "C" fn sys_spinlock_irqsave_destroy(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_irqsave_destroy(lock)) +pub unsafe extern "C" fn sys_spinlock_irqsave_destroy( + lock: *mut SpinlockIrqSaveContainer<'_>, +) -> i32 { + unsafe { kernel_function!(__sys_spinlock_irqsave_destroy(lock)) } } -extern "C" fn __sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -141,11 +149,11 @@ extern "C" fn __sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_ } #[no_mangle] -pub extern "C" fn sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_irqsave_lock(lock)) +pub unsafe extern "C" fn sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { + unsafe { kernel_function!(__sys_spinlock_irqsave_lock(lock)) } } -extern "C" fn __sys_spinlock_irqsave_unlock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { +unsafe extern "C" fn __sys_spinlock_irqsave_unlock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -160,6 +168,8 @@ extern "C" fn __sys_spinlock_irqsave_unlock(lock: *mut SpinlockIrqSaveContainer< } #[no_mangle] -pub extern "C" fn sys_spinlock_irqsave_unlock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { - kernel_function!(__sys_spinlock_irqsave_unlock(lock)) +pub unsafe extern "C" fn sys_spinlock_irqsave_unlock( + lock: *mut SpinlockIrqSaveContainer<'_>, +) -> i32 { + unsafe { kernel_function!(__sys_spinlock_irqsave_unlock(lock)) } } diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index e5ce8bf02a..d02be3038c 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -154,7 +154,7 @@ pub extern "C" fn sys_msleep(ms: u32) { kernel_function!(__sys_msleep(ms)) } -extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 { +unsafe extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 { assert!( !rqtp.is_null(), "sys_nanosleep called with a zero rqtp parameter" @@ -176,8 +176,8 @@ extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i3 } #[no_mangle] -pub extern "C" fn sys_nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> i32 { - kernel_function!(__sys_nanosleep(rqtp, rmtp)) +pub unsafe extern "C" fn sys_nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> i32 { + unsafe { kernel_function!(__sys_nanosleep(rqtp, rmtp)) } } #[cfg(feature = "newlib")] @@ -236,36 +236,37 @@ pub extern "C" fn sys_signal(handler: SignalHandler) -> i32 { kernel_function!(__sys_signal(handler)) } -extern "C" fn __sys_spawn2( - func: extern "C" fn(usize), +unsafe extern "C" fn __sys_spawn2( + func: unsafe extern "C" fn(usize), arg: usize, prio: u8, stack_size: usize, selector: isize, ) -> Tid { - scheduler::spawn(func, arg, Priority::from(prio), stack_size, selector).into() + unsafe { scheduler::spawn(func, arg, Priority::from(prio), stack_size, selector).into() } } #[no_mangle] -pub extern "C" fn sys_spawn2( - func: extern "C" fn(usize), +pub unsafe extern "C" fn sys_spawn2( + func: unsafe extern "C" fn(usize), arg: usize, prio: u8, stack_size: usize, selector: isize, ) -> Tid { - kernel_function!(__sys_spawn2(func, arg, prio, stack_size, selector)) + unsafe { kernel_function!(__sys_spawn2(func, arg, prio, stack_size, selector)) } } -extern "C" fn __sys_spawn( +unsafe extern "C" fn __sys_spawn( id: *mut Tid, - func: extern "C" fn(usize), + func: unsafe extern "C" fn(usize), arg: usize, prio: u8, selector: isize, ) -> i32 { - let new_id = - scheduler::spawn(func, arg, Priority::from(prio), USER_STACK_SIZE, selector).into(); + let new_id = unsafe { + scheduler::spawn(func, arg, Priority::from(prio), USER_STACK_SIZE, selector).into() + }; if !id.is_null() { unsafe { @@ -277,14 +278,14 @@ extern "C" fn __sys_spawn( } #[no_mangle] -pub extern "C" fn sys_spawn( +pub unsafe extern "C" fn sys_spawn( id: *mut Tid, - func: extern "C" fn(usize), + func: unsafe extern "C" fn(usize), arg: usize, prio: u8, selector: isize, ) -> i32 { - kernel_function!(__sys_spawn(id, func, arg, prio, selector)) + unsafe { kernel_function!(__sys_spawn(id, func, arg, prio, selector)) } } extern "C" fn __sys_join(id: Tid) -> i32 { diff --git a/src/syscalls/timer.rs b/src/syscalls/timer.rs index b2dacbd747..7bee508e92 100644 --- a/src/syscalls/timer.rs +++ b/src/syscalls/timer.rs @@ -19,7 +19,7 @@ pub(crate) const TIMER_ABSTIME: i32 = 4; /// - `CLOCK_PROCESS_CPUTIME_ID` /// - `CLOCK_THREAD_CPUTIME_ID` /// - `CLOCK_MONOTONIC` -extern "C" fn __sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { +unsafe extern "C" fn __sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { assert!( !res.is_null(), "sys_clock_getres called with a zero res parameter" @@ -40,8 +40,8 @@ extern "C" fn __sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { } #[no_mangle] -pub extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { - kernel_function!(__sys_clock_getres(clock_id, res)) +pub unsafe extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { + unsafe { kernel_function!(__sys_clock_getres(clock_id, res)) } } /// Get the current time of a clock. @@ -52,7 +52,7 @@ pub extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { /// Supported clocks: /// - `CLOCK_REALTIME` /// - `CLOCK_MONOTONIC` -extern "C" fn __sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { +unsafe extern "C" fn __sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { assert!( !tp.is_null(), "sys_clock_gettime called with a zero tp parameter" @@ -79,8 +79,8 @@ extern "C" fn __sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { } #[no_mangle] -pub extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { - kernel_function!(__sys_clock_gettime(clock_id, tp)) +pub unsafe extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { + unsafe { kernel_function!(__sys_clock_gettime(clock_id, tp)) } } /// Sleep a clock for a specified number of nanoseconds. @@ -92,7 +92,7 @@ pub extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { /// Supported clocks: /// - `CLOCK_REALTIME` /// - `CLOCK_MONOTONIC` -extern "C" fn __sys_clock_nanosleep( +unsafe extern "C" fn __sys_clock_nanosleep( clock_id: u64, flags: i32, rqtp: *const timespec, @@ -132,24 +132,24 @@ extern "C" fn __sys_clock_nanosleep( } #[no_mangle] -pub extern "C" fn sys_clock_nanosleep( +pub unsafe extern "C" fn sys_clock_nanosleep( clock_id: u64, flags: i32, rqtp: *const timespec, rmtp: *mut timespec, ) -> i32 { - kernel_function!(__sys_clock_nanosleep(clock_id, flags, rqtp, rmtp)) + unsafe { kernel_function!(__sys_clock_nanosleep(clock_id, flags, rqtp, rmtp)) } } -extern "C" fn __sys_clock_settime(_clock_id: u64, _tp: *const timespec) -> i32 { +unsafe extern "C" fn __sys_clock_settime(_clock_id: u64, _tp: *const timespec) -> i32 { // We don't support setting any clocks yet. debug!("sys_clock_settime is unimplemented, returning -EINVAL"); -EINVAL } #[no_mangle] -pub extern "C" fn sys_clock_settime(clock_id: u64, tp: *const timespec) -> i32 { - kernel_function!(__sys_clock_settime(clock_id, tp)) +pub unsafe extern "C" fn sys_clock_settime(clock_id: u64, tp: *const timespec) -> i32 { + unsafe { kernel_function!(__sys_clock_settime(clock_id, tp)) } } /// Get the system's clock time. @@ -158,7 +158,7 @@ pub extern "C" fn sys_clock_settime(clock_id: u64, tp: *const timespec) -> i32 { /// Returns `0` on success, `-EINVAL` otherwise. /// /// **Parameter `tz` should be set to `0` since tz is obsolete.** -extern "C" fn __sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { +unsafe extern "C" fn __sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { if let Some(result) = unsafe { tp.as_mut() } { // Return the current time based on the wallclock time when we were booted up // plus the current timer ticks. @@ -175,12 +175,12 @@ extern "C" fn __sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { } #[no_mangle] -pub extern "C" fn sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { - kernel_function!(__sys_gettimeofday(tp, tz)) +pub unsafe extern "C" fn sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { + unsafe { kernel_function!(__sys_gettimeofday(tp, tz)) } } #[no_mangle] -extern "C" fn __sys_setitimer( +unsafe extern "C" fn __sys_setitimer( _which: i32, _value: *const itimerval, _ovalue: *mut itimerval, @@ -190,10 +190,10 @@ extern "C" fn __sys_setitimer( } #[no_mangle] -pub extern "C" fn sys_setitimer( +pub unsafe extern "C" fn sys_setitimer( which: i32, value: *const itimerval, ovalue: *mut itimerval, ) -> i32 { - kernel_function!(__sys_setitimer(which, value, ovalue)) + unsafe { kernel_function!(__sys_setitimer(which, value, ovalue)) } } diff --git a/tests/thread.rs b/tests/thread.rs index 9a624b1e9b..776bba5b97 100644 --- a/tests/thread.rs +++ b/tests/thread.rs @@ -37,7 +37,7 @@ pub fn thread_test() { let threadnum = 5; for i in 0..threadnum { println!("SPAWNING THREAD {}", i); - let id = sys_spawn2(thread_func, i, NORMAL_PRIO, USER_STACK_SIZE, -1); + let id = unsafe { sys_spawn2(thread_func, i, NORMAL_PRIO, USER_STACK_SIZE, -1) }; children.push(id); } println!("SPAWNED THREADS"); @@ -47,13 +47,13 @@ pub fn thread_test() { } } -extern "C" fn waker_func(futex: usize) { +unsafe extern "C" fn waker_func(futex: usize) { let futex = unsafe { &*(futex as *const AtomicU32) }; sys_usleep(100_000); futex.store(1, Relaxed); - let ret = sys_futex_wake(futex as *const AtomicU32 as *mut u32, i32::MAX); + let ret = unsafe { sys_futex_wake(futex as *const AtomicU32 as *mut u32, i32::MAX) }; assert_eq!(ret, 1); } @@ -62,26 +62,28 @@ pub fn test_futex() { let futex = AtomicU32::new(0); let futex_ptr = &futex as *const AtomicU32 as *mut u32; - let ret = sys_futex_wait(futex_ptr, 1, ptr::null(), 0); + let ret = unsafe { sys_futex_wait(futex_ptr, 1, ptr::null(), 0) }; assert_eq!(ret, -EAGAIN); let timeout = timespec { tv_sec: 0, tv_nsec: 100_000_000, }; - let ret = sys_futex_wait(futex_ptr, 0, &timeout, 1); + let ret = unsafe { sys_futex_wait(futex_ptr, 0, &timeout, 1) }; assert_eq!(ret, -ETIMEDOUT); - let waker = sys_spawn2( - waker_func, - futex_ptr as usize, - NORMAL_PRIO, - USER_STACK_SIZE, - -1, - ); + let waker = unsafe { + sys_spawn2( + waker_func, + futex_ptr as usize, + NORMAL_PRIO, + USER_STACK_SIZE, + -1, + ) + }; assert!(waker >= 0); - let ret = sys_futex_wait(futex_ptr, 0, ptr::null(), 0); + let ret = unsafe { sys_futex_wait(futex_ptr, 0, ptr::null(), 0) }; assert_eq!(ret, 0); assert_eq!(futex.load(Relaxed), 1); From f9500d7564dc18b5fcf21205da77b123fcfdd6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 22 Mar 2024 14:37:03 +0100 Subject: [PATCH 11/12] feat: add hermit-macro crate with system attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- .github/workflows/ci.yml | 2 + Cargo.lock | 10 ++ Cargo.toml | 2 + hermit-macro/Cargo.toml | 12 +++ hermit-macro/src/lib.rs | 22 +++++ hermit-macro/src/system.rs | 195 +++++++++++++++++++++++++++++++++++++ 6 files changed, 243 insertions(+) create mode 100644 hermit-macro/Cargo.toml create mode 100644 hermit-macro/src/lib.rs create mode 100644 hermit-macro/src/system.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7424697c2..499942f921 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,6 +109,8 @@ jobs: run: cargo test --lib env: RUSTFLAGS: -Awarnings + - name: Macro unit tests + run: cargo test --package hermit-macro - name: Download loader run: gh release download --repo hermit-os/loader --pattern hermit-loader-x86_64 - run: rustup target add x86_64-unknown-none diff --git a/Cargo.lock b/Cargo.lock index 431d5361c7..619285f10a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -556,6 +556,7 @@ dependencies = [ "hashbrown", "hermit-dtb", "hermit-entry", + "hermit-macro", "hermit-sync", "llvm-tools", "lock_api", @@ -585,6 +586,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hermit-macro" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "hermit-sync" version = "0.1.5" diff --git a/Cargo.toml b/Cargo.toml index 20a3e6f194..5fe06746ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,7 @@ semihosting = ["dep:semihosting"] shell = ["simple-shell"] [dependencies] +hermit-macro = { path = "hermit-macro" } ahash = { version = "0.8", default-features = false } align-address = "0.1" bit_field = "0.10" @@ -152,6 +153,7 @@ llvm-tools = "0.1" [workspace] members = [ + "hermit-macro", "xtask", ] exclude = [ diff --git a/hermit-macro/Cargo.toml b/hermit-macro/Cargo.toml new file mode 100644 index 0000000000..eb04386fb0 --- /dev/null +++ b/hermit-macro/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hermit-macro" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1" +quote = "1" +syn = { version = "2", features = ["full"] } diff --git a/hermit-macro/src/lib.rs b/hermit-macro/src/lib.rs new file mode 100644 index 0000000000..b33e62136d --- /dev/null +++ b/hermit-macro/src/lib.rs @@ -0,0 +1,22 @@ +use proc_macro::TokenStream; +use quote::ToTokens; +use syn::parse::Nothing; +use syn::parse_macro_input; + +macro_rules! bail { + ($span:expr, $($tt:tt)*) => { + return Err(syn::Error::new_spanned($span, format!($($tt)*))) + }; +} + +mod system; + +// The structure of this implementation is inspired by Amanieu's excellent naked-function crate. +#[proc_macro_attribute] +pub fn system(attr: TokenStream, item: TokenStream) -> TokenStream { + parse_macro_input!(attr as Nothing); + match system::system_attribute(parse_macro_input!(item)) { + Ok(item) => item.into_token_stream().into(), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/hermit-macro/src/system.rs b/hermit-macro/src/system.rs new file mode 100644 index 0000000000..ef9a91ec1a --- /dev/null +++ b/hermit-macro/src/system.rs @@ -0,0 +1,195 @@ +use proc_macro2::{Ident, Span}; +use quote::quote; +use syn::{Abi, Attribute, Item, ItemFn, Pat, Result, Signature, Visibility}; + +fn validate_vis(vis: &Visibility) -> Result<()> { + if !matches!(vis, Visibility::Public(_)) { + bail!(vis, "#[system] functions must be public"); + } + + Ok(()) +} + +struct ParsedSig { + args: Vec, +} + +fn parse_sig(sig: &Signature) -> Result { + if let Some(constness) = sig.constness { + bail!(constness, "#[system] is not supported on const functions"); + } + if let Some(asyncness) = sig.asyncness { + bail!(asyncness, "#[system] is not supported on async functions"); + } + match &sig.abi { + Some(Abi { + extern_token: _, + name: Some(name), + }) if matches!(&*name.value(), "C" | "C-unwind") => {} + _ => bail!( + &sig.abi, + "#[system] functions must be `extern \"C\"` or `extern \"C-unwind\"`" + ), + } + if !sig.generics.params.is_empty() { + bail!( + &sig.generics, + "#[system] cannot be used with generic functions" + ); + } + if !sig.ident.to_string().starts_with("sys_") { + bail!(&sig.ident, "#[system] functions must start with `sys_`"); + } + + let mut args = vec![]; + + for arg in &sig.inputs { + let pat = match arg { + syn::FnArg::Receiver(_) => bail!(arg, "#[system] functions cannot take `self`"), + syn::FnArg::Typed(pat) => pat, + }; + if let Pat::Ident(pat) = &*pat.pat { + args.push(pat.ident.clone()); + } else { + bail!(pat, "unsupported pattern in #[system] function argument"); + } + } + + Ok(ParsedSig { args }) +} + +fn validate_attrs(attrs: &[Attribute]) -> Result<()> { + for attr in attrs { + if !attr.path().is_ident("cfg") && !attr.path().is_ident("doc") { + bail!( + attr, + "#[system] functions may only have `#[doc]` and `#[cfg]` attributes" + ); + } + } + + Ok(()) +} + +fn emit_func(mut func: ItemFn, sig: &ParsedSig) -> Result { + let args = &sig.args; + let attrs = func.attrs.clone(); + let vis = func.vis.clone(); + let sig = func.sig.clone(); + + let ident = Ident::new(&format!("__{}", func.sig.ident), Span::call_site()); + func.sig.ident = ident.clone(); + func.vis = Visibility::Inherited; + func.attrs.clear(); + + let func_call = quote! { + kernel_function!(#ident(#(#args),*)) + }; + + let func_call = if func.sig.unsafety.is_some() { + quote! { + unsafe { #func_call } + } + } else { + func_call + }; + + let func = syn::parse2(quote! { + #(#attrs)* + #[no_mangle] + #vis #sig { + #func + + #func_call + } + })?; + + Ok(func) +} + +pub fn system_attribute(func: ItemFn) -> Result { + validate_vis(&func.vis)?; + let sig = parse_sig(&func.sig)?; + validate_attrs(&func.attrs)?; + let func = emit_func(func, &sig)?; + Ok(Item::Fn(func)) +} + +#[cfg(test)] +mod tests { + use quote::ToTokens; + + use super::*; + + #[test] + fn test_safe() -> Result<()> { + let input = syn::parse2(quote! { + /// Adds two numbers together. + /// + /// This is very important. + #[cfg(target_os = "none")] + pub extern "C" fn sys_test(a: i8, b: i16) -> i32 { + let c = i16::from(a) + b; + i32::from(c) + } + })?; + + let expected = quote! { + /// Adds two numbers together. + /// + /// This is very important. + #[cfg(target_os = "none")] + #[no_mangle] + pub extern "C" fn sys_test(a: i8, b: i16) -> i32 { + extern "C" fn __sys_test(a: i8, b: i16) -> i32 { + let c = i16::from(a) + b; + i32::from(c) + } + + kernel_function!(__sys_test(a, b)) + } + }; + + let result = system_attribute(input)?.into_token_stream(); + + assert_eq!(expected.to_string(), result.to_string()); + + Ok(()) + } + + #[test] + fn test_unsafe() -> Result<()> { + let input = syn::parse2(quote! { + /// Adds two numbers together. + /// + /// This is very important. + #[cfg(target_os = "none")] + pub unsafe extern "C" fn sys_test(a: i8, b: i16) -> i32 { + let c = i16::from(a) + b; + i32::from(c) + } + })?; + + let expected = quote! { + /// Adds two numbers together. + /// + /// This is very important. + #[cfg(target_os = "none")] + #[no_mangle] + pub unsafe extern "C" fn sys_test(a: i8, b: i16) -> i32 { + unsafe extern "C" fn __sys_test(a: i8, b: i16) -> i32 { + let c = i16::from(a) + b; + i32::from(c) + } + + unsafe { kernel_function!(__sys_test(a, b)) } + } + }; + + let result = system_attribute(input)?.into_token_stream(); + + assert_eq!(expected.to_string(), result.to_string()); + + Ok(()) + } +} From cb14c4b28e8052b57d31d76ec3b92b1cd8e06568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Sat, 23 Mar 2024 13:07:28 +0100 Subject: [PATCH 12/12] feat: implement system calls with attribute proc macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- src/syscalls/condvar.rs | 40 ++------ src/syscalls/entropy.rs | 46 +++------ src/syscalls/futex.rs | 21 +--- src/syscalls/lwip.rs | 40 ++------ src/syscalls/mod.rs | 202 +++++++++---------------------------- src/syscalls/processor.rs | 16 +-- src/syscalls/recmutex.rs | 32 ++---- src/syscalls/semaphore.rs | 46 +++------ src/syscalls/socket.rs | 167 ++++++------------------------- src/syscalls/spinlock.rs | 72 ++++---------- src/syscalls/system.rs | 8 +- src/syscalls/tasks.rs | 203 +++++++++----------------------------- src/syscalls/timer.rs | 58 +++-------- 13 files changed, 220 insertions(+), 731 deletions(-) diff --git a/src/syscalls/condvar.rs b/src/syscalls/condvar.rs index 0474a7e7bd..ef70b0c664 100644 --- a/src/syscalls/condvar.rs +++ b/src/syscalls/condvar.rs @@ -23,7 +23,8 @@ impl CondQueue { } } -unsafe extern "C" fn __sys_destroy_queue(ptr: usize) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_destroy_queue(ptr: usize) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -40,12 +41,8 @@ unsafe extern "C" fn __sys_destroy_queue(ptr: usize) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_destroy_queue(ptr: usize) -> i32 { - unsafe { kernel_function!(__sys_destroy_queue(ptr)) } -} - -unsafe extern "C" fn __sys_notify(ptr: usize, count: i32) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_notify(ptr: usize, count: i32) -> i32 { unsafe { let id = ptr::from_exposed_addr::(ptr); @@ -81,12 +78,8 @@ unsafe extern "C" fn __sys_notify(ptr: usize, count: i32) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_notify(ptr: usize, count: i32) -> i32 { - unsafe { kernel_function!(__sys_notify(ptr, count)) } -} - -unsafe extern "C" fn __sys_init_queue(ptr: usize) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_init_queue(ptr: usize) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -104,12 +97,8 @@ unsafe extern "C" fn __sys_init_queue(ptr: usize) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_init_queue(ptr: usize) -> i32 { - unsafe { kernel_function!(__sys_init_queue(ptr)) } -} - -unsafe extern "C" fn __sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -136,12 +125,8 @@ unsafe extern "C" fn __sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { - unsafe { kernel_function!(__sys_add_queue(ptr, timeout_ns)) } -} - -unsafe extern "C" fn __sys_wait(ptr: usize) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_wait(ptr: usize) -> i32 { unsafe { let id = ptr::from_exposed_addr_mut::(ptr); if id.is_null() { @@ -161,8 +146,3 @@ unsafe extern "C" fn __sys_wait(ptr: usize) -> i32 { 0 } } - -#[no_mangle] -pub unsafe extern "C" fn sys_wait(ptr: usize) -> i32 { - unsafe { kernel_function!(__sys_wait(ptr)) } -} diff --git a/src/syscalls/entropy.rs b/src/syscalls/entropy.rs index 5d61f9b644..365d69e513 100644 --- a/src/syscalls/entropy.rs +++ b/src/syscalls/entropy.rs @@ -58,9 +58,12 @@ pub unsafe extern "C" fn sys_read_entropy(buf: *mut u8, len: usize, flags: u32) unsafe { kernel_function!(__sys_read_entropy(buf, len, flags)) } } +/// Create a cryptographicly secure 32bit random number with the support of +/// the underlying hardware. If the required hardware isn't available, +/// the function returns `-1`. #[cfg(not(feature = "newlib"))] -#[no_mangle] -unsafe extern "C" fn __sys_secure_rand32(value: *mut u32) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { let mut buf = value.cast(); let mut len = size_of::(); while len != 0 { @@ -76,18 +79,12 @@ unsafe extern "C" fn __sys_secure_rand32(value: *mut u32) -> i32 { 0 } -/// Create a cryptographicly secure 32bit random number with the support of +/// Create a cryptographicly secure 64bit random number with the support of /// the underlying hardware. If the required hardware isn't available, -/// the function returns `-1`. -#[cfg(not(feature = "newlib"))] -#[no_mangle] -pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { - unsafe { kernel_function!(__sys_secure_rand32(value)) } -} - +/// the function returns -1. #[cfg(not(feature = "newlib"))] -#[no_mangle] -unsafe extern "C" fn __sys_secure_rand64(value: *mut u64) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { let mut buf = value.cast(); let mut len = size_of::(); while len != 0 { @@ -103,35 +100,18 @@ unsafe extern "C" fn __sys_secure_rand64(value: *mut u64) -> i32 { 0 } -/// Create a cryptographicly secure 64bit random number with the support of -/// the underlying hardware. If the required hardware isn't available, -/// the function returns -1. -#[cfg(not(feature = "newlib"))] -#[no_mangle] -pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { - unsafe { kernel_function!(__sys_secure_rand64(value)) } -} - -extern "C" fn __sys_rand() -> u32 { - generate_park_miller_lehmer_random_number() -} - /// The function computes a sequence of pseudo-random integers /// in the range of 0 to RAND_MAX -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_rand() -> u32 { - kernel_function!(__sys_rand()) -} - -extern "C" fn __sys_srand(seed: u32) { - *(PARK_MILLER_LEHMER_SEED.lock()) = seed; + generate_park_miller_lehmer_random_number() } /// The function sets its argument as the seed for a new sequence /// of pseudo-random numbers to be returned by rand() -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_srand(seed: u32) { - kernel_function!(__sys_srand(seed)) + *(PARK_MILLER_LEHMER_SEED.lock()) = seed; } pub(crate) fn init_entropy() { diff --git a/src/syscalls/futex.rs b/src/syscalls/futex.rs index fc942d756e..c2be9aac05 100644 --- a/src/syscalls/futex.rs +++ b/src/syscalls/futex.rs @@ -10,7 +10,8 @@ use crate::time::timespec; /// * `address` is null /// * `timeout` is negative /// * `flags` contains unknown flags -unsafe extern "C" fn __sys_futex_wait( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_futex_wait( address: *mut u32, expected: u32, timeout: *const timespec, @@ -37,20 +38,11 @@ unsafe extern "C" fn __sys_futex_wait( synch::futex_wait(address, expected, timeout, flags) } -#[no_mangle] -pub unsafe extern "C" fn sys_futex_wait( - address: *mut u32, - expected: u32, - timeout: *const timespec, - flags: u32, -) -> i32 { - unsafe { kernel_function!(__sys_futex_wait(address, expected, timeout, flags)) } -} - /// Like `synch::futex_wake`, but does extra sanity checks. /// /// Returns -EINVAL if `address` is null. -unsafe extern "C" fn __sys_futex_wake(address: *mut u32, count: i32) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { if address.is_null() { return -EINVAL; } @@ -58,8 +50,3 @@ unsafe extern "C" fn __sys_futex_wake(address: *mut u32, count: i32) -> i32 { let address = unsafe { &*(address as *const AtomicU32) }; synch::futex_wake(address, count) } - -#[no_mangle] -pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { - unsafe { kernel_function!(__sys_futex_wake(address, count)) } -} diff --git a/src/syscalls/lwip.rs b/src/syscalls/lwip.rs index 2747056115..812f8c6e82 100644 --- a/src/syscalls/lwip.rs +++ b/src/syscalls/lwip.rs @@ -4,51 +4,31 @@ use lock_api::MutexGuard; use crate::arch::core_local::core_scheduler; use crate::{arch, console}; -extern "C" fn __sys_lwip_get_errno() -> i32 { - core_scheduler().get_lwip_errno() -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_lwip_get_errno() -> i32 { - kernel_function!(__sys_lwip_get_errno()) -} - -extern "C" fn __sys_lwip_set_errno(errno: i32) { - core_scheduler().set_lwip_errno(errno); + core_scheduler().get_lwip_errno() } -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_lwip_set_errno(errno: i32) { - kernel_function!(__sys_lwip_set_errno(errno)) + core_scheduler().set_lwip_errno(errno); } -extern "C" fn __sys_acquire_putchar_lock() { +#[hermit_macro::system] +pub extern "C" fn sys_acquire_putchar_lock() { // FIXME: use core-local storage instead // better yet: remove and replace all of this MutexGuard::leak(console::CONSOLE.lock()); } -#[no_mangle] -pub extern "C" fn sys_acquire_putchar_lock() { - kernel_function!(__sys_acquire_putchar_lock()) -} - -extern "C" fn __sys_putchar(character: u8) { - arch::output_message_buf(&[character]); -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_putchar(character: u8) { - kernel_function!(__sys_putchar(character)) + arch::output_message_buf(&[character]); } -unsafe extern "C" fn __sys_release_putchar_lock() { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_release_putchar_lock() { unsafe { console::CONSOLE.force_unlock(); } } - -#[no_mangle] -pub unsafe extern "C" fn sys_release_putchar_lock() { - unsafe { kernel_function!(__sys_release_putchar_lock()) } -} diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 07f7fe4f56..c0e80ca64c 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -81,7 +81,8 @@ pub(crate) fn init() { /// `size` and `align` do not meet this allocator's size or alignment constraints. /// #[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) extern "C" fn __sys_malloc(size: usize, align: usize) -> *mut u8 { +#[hermit_macro::system] +pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { let layout_res = Layout::from_size_align(size, align); if layout_res.is_err() || size == 0 { warn!( @@ -103,12 +104,6 @@ pub(crate) extern "C" fn __sys_malloc(size: usize, align: usize) -> *mut u8 { ptr } -#[cfg(all(target_os = "none", not(feature = "common-os")))] -#[no_mangle] -pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { - kernel_function!(__sys_malloc(size, align)) -} - /// Shrink or grow a block of memory to the given `new_size`. The block is described by the given /// ptr pointer and layout. If this returns a non-null pointer, then ownership of the memory block /// referenced by ptr has been transferred to this allocator. The memory may or may not have been @@ -129,7 +124,8 @@ pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { /// Returns null if the new layout does not meet the size and alignment constraints of the /// allocator, or if reallocation otherwise fails. #[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) unsafe extern "C" fn __sys_realloc( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_realloc( ptr: *mut u8, size: usize, align: usize, @@ -163,17 +159,6 @@ pub(crate) unsafe extern "C" fn __sys_realloc( } } -#[cfg(all(target_os = "none", not(feature = "common-os")))] -#[no_mangle] -pub unsafe extern "C" fn sys_realloc( - ptr: *mut u8, - size: usize, - align: usize, - new_size: usize, -) -> *mut u8 { - unsafe { kernel_function!(__sys_realloc(ptr, size, align, new_size)) } -} - /// Interface to deallocate a memory region from the system heap /// /// # Safety @@ -185,7 +170,8 @@ pub unsafe extern "C" fn sys_realloc( /// # Errors /// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed. #[cfg(all(target_os = "none", not(feature = "common-os")))] -pub(crate) unsafe extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usize) { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { unsafe { let layout_res = Layout::from_size_align(size, align); if layout_res.is_err() || size == 0 { @@ -207,12 +193,6 @@ pub(crate) unsafe extern "C" fn __sys_free(ptr: *mut u8, size: usize, align: usi } } -#[cfg(all(target_os = "none", not(feature = "common-os")))] -#[no_mangle] -pub unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { - unsafe { kernel_function!(__sys_free(ptr, size, align)) } -} - pub(crate) fn get_application_parameters() -> (i32, *const *const u8, *const *const u8) { SYS.get_application_parameters() } @@ -224,16 +204,13 @@ pub(crate) fn shutdown(arg: i32) -> ! { SYS.shutdown(arg) } -pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! { - shutdown(arg) -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_shutdown(arg: i32) -> ! { - kernel_function!(__sys_shutdown(arg)) + shutdown(arg) } -unsafe extern "C" fn __sys_unlink(name: *const u8) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_unlink(name: *const u8) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); fs::FILESYSTEM @@ -243,12 +220,8 @@ unsafe extern "C" fn __sys_unlink(name: *const u8) -> i32 { .map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) } -#[no_mangle] -pub unsafe extern "C" fn sys_unlink(name: *const u8) -> i32 { - unsafe { kernel_function!(__sys_unlink(name)) } -} - -unsafe extern "C" fn __sys_mkdir(name: *const u8, mode: u32) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); let mode = if let Some(mode) = AccessPermission::from_bits(mode) { mode @@ -263,12 +236,8 @@ unsafe extern "C" fn __sys_mkdir(name: *const u8, mode: u32) -> i32 { .map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) } -#[no_mangle] -pub unsafe extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 { - unsafe { kernel_function!(__sys_mkdir(name, mode)) } -} - -unsafe extern "C" fn __sys_rmdir(name: *const u8) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_rmdir(name: *const u8) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); fs::FILESYSTEM @@ -278,12 +247,8 @@ unsafe extern "C" fn __sys_rmdir(name: *const u8) -> i32 { .map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) } -#[no_mangle] -pub unsafe extern "C" fn sys_rmdir(name: *const u8) -> i32 { - unsafe { kernel_function!(__sys_rmdir(name)) } -} - -unsafe extern "C" fn __sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); match fs::FILESYSTEM.get().unwrap().stat(name) { @@ -295,12 +260,8 @@ unsafe extern "C" fn __sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 { - unsafe { kernel_function!(__sys_stat(name, stat)) } -} - -unsafe extern "C" fn __sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); match fs::FILESYSTEM.get().unwrap().lstat(name) { @@ -312,12 +273,8 @@ unsafe extern "C" fn __sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 { - unsafe { kernel_function!(__sys_lstat(name, stat)) } -} - -unsafe extern "C" fn __sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { let stat = unsafe { &mut *stat }; let obj = get_object(fd); obj.map_or_else( @@ -329,12 +286,8 @@ unsafe extern "C" fn __sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 ) } -#[no_mangle] -pub unsafe extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { - unsafe { kernel_function!(__sys_fstat(fd, stat)) } -} - -unsafe extern "C" fn __sys_opendir(name: *const u8) -> FileDescriptor { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_opendir(name: *const u8) -> FileDescriptor { if let Ok(name) = unsafe { CStr::from_ptr(name as _) }.to_str() { crate::fs::opendir(name).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) } else { @@ -342,12 +295,8 @@ unsafe extern "C" fn __sys_opendir(name: *const u8) -> FileDescriptor { } } -#[no_mangle] -pub unsafe extern "C" fn sys_opendir(name: *const u8) -> FileDescriptor { - unsafe { kernel_function!(__sys_opendir(name)) } -} - -unsafe extern "C" fn __sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { let flags = if let Some(flags) = OpenOption::from_bits(flags) { flags } else { @@ -367,22 +316,14 @@ unsafe extern "C" fn __sys_open(name: *const u8, flags: i32, mode: u32) -> FileD } } -#[no_mangle] -pub unsafe extern "C" fn sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor { - unsafe { kernel_function!(__sys_open(name, flags, mode)) } -} - -extern "C" fn __sys_close(fd: FileDescriptor) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_close(fd: FileDescriptor) -> i32 { let obj = remove_object(fd); obj.map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) } -#[no_mangle] -pub extern "C" fn sys_close(fd: FileDescriptor) -> i32 { - kernel_function!(__sys_close(fd)) -} - -unsafe extern "C" fn __sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) }; crate::fd::read(fd, slice).map_or_else( |e| -num::ToPrimitive::to_isize(&e).unwrap(), @@ -390,11 +331,6 @@ unsafe extern "C" fn __sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> ) } -#[no_mangle] -pub unsafe extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize { - unsafe { kernel_function!(__sys_read(fd, buf, len)) } -} - unsafe fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { let slice = unsafe { core::slice::from_raw_parts(buf, len) }; crate::fd::write(fd, slice).map_or_else( @@ -403,16 +339,13 @@ unsafe fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { ) } -unsafe extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { - unsafe { write(fd, buf, len) } -} - -#[no_mangle] +#[hermit_macro::system] pub unsafe extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { - unsafe { kernel_function!(__sys_write(fd, buf, len)) } + unsafe { write(fd, buf, len) } } -unsafe extern "C" fn __sys_ioctl( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_ioctl( fd: FileDescriptor, cmd: i32, argp: *mut core::ffi::c_void, @@ -435,16 +368,9 @@ unsafe extern "C" fn __sys_ioctl( } } -#[no_mangle] -pub unsafe extern "C" fn sys_ioctl( - fd: FileDescriptor, - cmd: i32, - argp: *mut core::ffi::c_void, -) -> i32 { - unsafe { kernel_function!(__sys_ioctl(fd, cmd, argp)) } -} - -extern "C" fn __sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { +/// manipulate file descriptor +#[hermit_macro::system] +pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { const F_SETFD: i32 = 2; const F_SETFL: i32 = 4; const FD_CLOEXEC: i32 = 1; @@ -466,13 +392,8 @@ extern "C" fn __sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { } } -/// manipulate file descriptor -#[no_mangle] -pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { - kernel_function!(__sys_fcntl(fd, cmd, arg)) -} - -extern "C" fn __sys_lseek(fd: FileDescriptor, offset: isize, whence: i32) -> isize { +#[hermit_macro::system] +pub extern "C" fn sys_lseek(fd: FileDescriptor, offset: isize, whence: i32) -> isize { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_isize(&e).unwrap(), @@ -483,11 +404,6 @@ extern "C" fn __sys_lseek(fd: FileDescriptor, offset: isize, whence: i32) -> isi ) } -#[no_mangle] -pub extern "C" fn sys_lseek(fd: FileDescriptor, offset: isize, whence: i32) -> isize { - kernel_function!(__sys_lseek(fd, offset, whence)) -} - #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct Dirent64 { @@ -503,7 +419,8 @@ pub struct Dirent64 { pub d_name: PhantomData, } -unsafe extern "C" fn __sys_getdents64( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_getdents64( fd: FileDescriptor, dirp: *mut Dirent64, count: usize, @@ -557,25 +474,13 @@ unsafe extern "C" fn __sys_getdents64( ) } -#[no_mangle] -pub unsafe extern "C" fn sys_getdents64( - fd: FileDescriptor, - dirp: *mut Dirent64, - count: usize, -) -> i64 { - unsafe { kernel_function!(__sys_getdents64(fd, dirp, count)) } -} - -extern "C" fn __sys_dup(fd: i32) -> i32 { - dup_object(fd).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_dup(fd: i32) -> i32 { - kernel_function!(__sys_dup(fd)) + dup_object(fd).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) } -unsafe extern "C" fn __sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { let slice = unsafe { core::slice::from_raw_parts_mut(fds, nfds) }; let timeout = if timeout >= 0 { Some(core::time::Duration::from_millis( @@ -597,12 +502,8 @@ unsafe extern "C" fn __sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> ) } -#[no_mangle] -pub unsafe extern "C" fn sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) -> i32 { - unsafe { kernel_function!(__sys_poll(fds, nfds, timeout)) } -} - -extern "C" fn __sys_eventfd(initval: u64, flags: i16) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_eventfd(initval: u64, flags: i16) -> i32 { if let Some(flags) = EventFlags::from_bits(flags) { crate::fd::eventfd(initval, flags) .unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) @@ -611,16 +512,7 @@ extern "C" fn __sys_eventfd(initval: u64, flags: i16) -> i32 { } } -#[no_mangle] -pub extern "C" fn sys_eventfd(initval: u64, flags: i16) -> i32 { - kernel_function!(__sys_eventfd(initval, flags)) -} - -extern "C" fn __sys_image_start_addr() -> usize { - crate::mm::kernel_start_address().0.try_into().unwrap() -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_image_start_addr() -> usize { - kernel_function!(__sys_image_start_addr()) + crate::mm::kernel_start_address().0.try_into().unwrap() } diff --git a/src/syscalls/processor.rs b/src/syscalls/processor.rs index af94f5687d..c15e8ad527 100644 --- a/src/syscalls/processor.rs +++ b/src/syscalls/processor.rs @@ -1,21 +1,13 @@ use crate::arch::get_processor_count; -extern "C" fn __sys_get_processor_count() -> usize { - get_processor_count().try_into().unwrap() -} - /// Returns the number of processors currently online. -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_get_processor_count() -> usize { - kernel_function!(__sys_get_processor_count()) -} - -extern "C" fn __sys_get_processor_frequency() -> u16 { - crate::arch::processor::get_frequency() + get_processor_count().try_into().unwrap() } /// Returns the processor frequency in MHz. -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_get_processor_frequency() -> u16 { - kernel_function!(__sys_get_processor_frequency()) + crate::arch::processor::get_frequency() } diff --git a/src/syscalls/recmutex.rs b/src/syscalls/recmutex.rs index 639e2dd1ae..2b2021d9e9 100644 --- a/src/syscalls/recmutex.rs +++ b/src/syscalls/recmutex.rs @@ -3,7 +3,8 @@ use alloc::boxed::Box; use crate::errno::*; use crate::synch::recmutex::RecursiveMutex; -extern "C" fn __sys_recmutex_init(recmutex: *mut *mut RecursiveMutex) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_recmutex_init(recmutex: *mut *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; } @@ -17,12 +18,8 @@ extern "C" fn __sys_recmutex_init(recmutex: *mut *mut RecursiveMutex) -> i32 { 0 } -#[no_mangle] -pub extern "C" fn sys_recmutex_init(recmutex: *mut *mut RecursiveMutex) -> i32 { - kernel_function!(__sys_recmutex_init(recmutex)) -} - -extern "C" fn __sys_recmutex_destroy(recmutex: *mut RecursiveMutex) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_recmutex_destroy(recmutex: *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; } @@ -36,12 +33,8 @@ extern "C" fn __sys_recmutex_destroy(recmutex: *mut RecursiveMutex) -> i32 { 0 } -#[no_mangle] -pub extern "C" fn sys_recmutex_destroy(recmutex: *mut RecursiveMutex) -> i32 { - kernel_function!(__sys_recmutex_destroy(recmutex)) -} - -extern "C" fn __sys_recmutex_lock(recmutex: *mut RecursiveMutex) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_recmutex_lock(recmutex: *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; } @@ -52,12 +45,8 @@ extern "C" fn __sys_recmutex_lock(recmutex: *mut RecursiveMutex) -> i32 { 0 } -#[no_mangle] -pub extern "C" fn sys_recmutex_lock(recmutex: *mut RecursiveMutex) -> i32 { - kernel_function!(__sys_recmutex_lock(recmutex)) -} - -extern "C" fn __sys_recmutex_unlock(recmutex: *mut RecursiveMutex) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_recmutex_unlock(recmutex: *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; } @@ -67,8 +56,3 @@ extern "C" fn __sys_recmutex_unlock(recmutex: *mut RecursiveMutex) -> i32 { 0 } - -#[no_mangle] -pub extern "C" fn sys_recmutex_unlock(recmutex: *mut RecursiveMutex) -> i32 { - kernel_function!(__sys_recmutex_unlock(recmutex)) -} diff --git a/src/syscalls/semaphore.rs b/src/syscalls/semaphore.rs index 16f3a748e4..fcc66c57ab 100644 --- a/src/syscalls/semaphore.rs +++ b/src/syscalls/semaphore.rs @@ -9,7 +9,8 @@ use crate::synch::semaphore::Semaphore; /// /// Stores the raw memory location of the new semaphore in parameter `sem`. /// Returns `0` on success, `-EINVAL` if `sem` is null. -unsafe extern "C" fn __sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { if sem.is_null() { return -EINVAL; } @@ -22,17 +23,13 @@ unsafe extern "C" fn __sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { - unsafe { kernel_function!(__sys_sem_init(sem, value)) } -} - /// Destroy and deallocate a semaphore. /// /// This function can be used to manually deallocate a semaphore via a reference. /// /// Returns `0` on success, `-EINVAL` if `sem` is null. -unsafe extern "C" fn __sys_sem_destroy(sem: *mut Semaphore) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { if sem.is_null() { return -EINVAL; } @@ -45,11 +42,6 @@ unsafe extern "C" fn __sys_sem_destroy(sem: *mut Semaphore) -> i32 { 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { - unsafe { kernel_function!(__sys_sem_destroy(sem)) } -} - /// Release a semaphore. /// /// This function can be used to allow the next blocked waiter to access this semaphore. @@ -57,7 +49,8 @@ pub unsafe extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { /// The semaphore is not deallocated after being released. /// /// Returns `0` on success, or `-EINVAL` if `sem` is null. -unsafe extern "C" fn __sys_sem_post(sem: *const Semaphore) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 { if sem.is_null() { return -EINVAL; } @@ -68,18 +61,14 @@ unsafe extern "C" fn __sys_sem_post(sem: *const Semaphore) -> i32 { 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 { - unsafe { kernel_function!(__sys_sem_post(sem)) } -} - /// Try to acquire a lock on a semaphore. /// /// This function does not block if the acquire fails. /// If the acquire fails (i.e. the semaphore's count is already 0), the function returns immediately. /// /// Returns `0` on lock acquire, `-EINVAL` if `sem` is null, or `-ECANCELED` if the decrement fails. -unsafe extern "C" fn __sys_sem_trywait(sem: *const Semaphore) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 { if sem.is_null() { return -EINVAL; } @@ -93,11 +82,6 @@ unsafe extern "C" fn __sys_sem_trywait(sem: *const Semaphore) -> i32 { } } -#[no_mangle] -pub unsafe extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 { - unsafe { kernel_function!(__sys_sem_trywait(sem)) } -} - unsafe fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { if sem.is_null() { return -EINVAL; @@ -119,20 +103,12 @@ unsafe fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { /// Blocks until semaphore is acquired or until wake-up time has elapsed. /// /// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout. -unsafe extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { - unsafe { sem_timedwait(sem, ms) } -} - -#[no_mangle] +#[hermit_macro::system] pub unsafe extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { - unsafe { kernel_function!(__sys_sem_timedwait(sem, ms)) } -} - -unsafe extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { unsafe { sem_timedwait(sem, ms) } } -#[no_mangle] +#[hermit_macro::system] pub unsafe extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 { - unsafe { kernel_function!(__sys_sem_cancelablewait(sem, ms)) } + unsafe { sem_timedwait(sem, ms) } } diff --git a/src/syscalls/socket.rs b/src/syscalls/socket.rs index 8f9d7c8a68..2ba35ca085 100644 --- a/src/syscalls/socket.rs +++ b/src/syscalls/socket.rs @@ -256,7 +256,8 @@ pub struct linger { pub l_linger: i32, } -extern "C" fn __sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 { debug!( "sys_socket: domain {}, type {:?}, protocol {}", domain, type_, protocol @@ -308,7 +309,8 @@ extern "C" fn __sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 { } } -unsafe extern "C" fn __sys_accept(fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_accept(fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_i32(&e).unwrap(), @@ -348,7 +350,8 @@ unsafe extern "C" fn __sys_accept(fd: i32, addr: *mut sockaddr, addrlen: *mut so ) } -extern "C" fn __sys_listen(fd: i32, backlog: i32) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_listen(fd: i32, backlog: i32) -> i32 { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_i32(&e).unwrap(), @@ -359,7 +362,8 @@ extern "C" fn __sys_listen(fd: i32, backlog: i32) -> i32 { ) } -unsafe extern "C" fn __sys_bind(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_bind(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { let endpoint = if namelen == size_of::().try_into().unwrap() { IpListenEndpoint::from(unsafe { *(name as *const sockaddr_in) }) } else if namelen == size_of::().try_into().unwrap() { @@ -378,7 +382,8 @@ unsafe extern "C" fn __sys_bind(fd: i32, name: *const sockaddr, namelen: socklen ) } -unsafe extern "C" fn __sys_connect(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_connect(fd: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { let endpoint = if namelen == size_of::().try_into().unwrap() { IpEndpoint::from(unsafe { *(name as *const sockaddr_in) }) } else if namelen == size_of::().try_into().unwrap() { @@ -397,7 +402,8 @@ unsafe extern "C" fn __sys_connect(fd: i32, name: *const sockaddr, namelen: sock ) } -unsafe extern "C" fn __sys_getsockname( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_getsockname( fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t, @@ -440,7 +446,8 @@ unsafe extern "C" fn __sys_getsockname( ) } -unsafe extern "C" fn __sys_setsockopt( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_setsockopt( fd: i32, level: i32, optname: i32, @@ -476,7 +483,8 @@ unsafe extern "C" fn __sys_setsockopt( } } -unsafe extern "C" fn __sys_getsockopt( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_getsockopt( fd: i32, level: i32, optname: i32, @@ -519,7 +527,8 @@ unsafe extern "C" fn __sys_getsockopt( } } -unsafe extern "C" fn __sys_getpeername( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_getpeername( fd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t, @@ -562,9 +571,11 @@ unsafe extern "C" fn __sys_getpeername( ) } -unsafe extern "C" fn __sys_freeaddrinfo(_ai: *mut addrinfo) {} +#[hermit_macro::system] +pub unsafe extern "C" fn sys_freeaddrinfo(_ai: *mut addrinfo) {} -unsafe extern "C" fn __sys_getaddrinfo( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_getaddrinfo( _nodename: *const u8, _servname: *const u8, _hints: *const addrinfo, @@ -573,11 +584,13 @@ unsafe extern "C" fn __sys_getaddrinfo( -EINVAL } -unsafe extern "C" fn __sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize { unsafe { super::write(s, mem.cast(), len) } } -extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_shutdown_socket(fd: i32, how: i32) -> i32 { let obj = get_object(fd); obj.map_or_else( |e| -num::ToPrimitive::to_i32(&e).unwrap(), @@ -588,7 +601,8 @@ extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 { ) } -unsafe extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { if flags == 0 { let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) }; crate::fd::read(fd, slice).map_or_else( @@ -600,7 +614,8 @@ unsafe extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) - } } -unsafe extern "C" fn __sys_sendto( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_sendto( fd: i32, buf: *const u8, len: usize, @@ -629,7 +644,8 @@ unsafe extern "C" fn __sys_sendto( ) } -unsafe extern "C" fn __sys_recvfrom( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_recvfrom( fd: i32, buf: *mut u8, len: usize, @@ -676,122 +692,3 @@ unsafe extern "C" fn __sys_recvfrom( }, ) } - -#[no_mangle] -pub extern "C" fn sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 { - kernel_function!(__sys_socket(domain, type_, protocol)) -} - -#[no_mangle] -pub unsafe extern "C" fn sys_accept(s: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32 { - unsafe { kernel_function!(__sys_accept(s, addr, addrlen)) } -} - -#[no_mangle] -pub extern "C" fn sys_listen(s: i32, backlog: i32) -> i32 { - kernel_function!(__sys_listen(s, backlog)) -} - -#[no_mangle] -pub unsafe extern "C" fn sys_bind(s: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { - unsafe { kernel_function!(__sys_bind(s, name, namelen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_connect(s: i32, name: *const sockaddr, namelen: socklen_t) -> i32 { - unsafe { kernel_function!(__sys_connect(s, name, namelen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_getsockname( - s: i32, - name: *mut sockaddr, - namelen: *mut socklen_t, -) -> i32 { - unsafe { kernel_function!(__sys_getsockname(s, name, namelen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_setsockopt( - s: i32, - level: i32, - optname: i32, - optval: *const c_void, - optlen: socklen_t, -) -> i32 { - unsafe { kernel_function!(__sys_setsockopt(s, level, optname, optval, optlen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_getsockopt( - s: i32, - level: i32, - optname: i32, - optval: *mut c_void, - optlen: *mut socklen_t, -) -> i32 { - unsafe { kernel_function!(__sys_getsockopt(s, level, optname, optval, optlen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_getpeername( - s: i32, - name: *mut sockaddr, - namelen: *mut socklen_t, -) -> i32 { - unsafe { kernel_function!(__sys_getpeername(s, name, namelen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_freeaddrinfo(ai: *mut addrinfo) { - unsafe { kernel_function!(__sys_freeaddrinfo(ai)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_getaddrinfo( - nodename: *const u8, - servname: *const u8, - hints: *const addrinfo, - res: *mut *mut addrinfo, -) -> i32 { - unsafe { kernel_function!(__sys_getaddrinfo(nodename, servname, hints, res)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, flags: i32) -> isize { - unsafe { kernel_function!(__sys_send(s, mem, len, flags)) } -} - -#[no_mangle] -pub extern "C" fn sys_shutdown_socket(s: i32, how: i32) -> i32 { - kernel_function!(__sys_shutdown_socket(s, how)) -} - -#[no_mangle] -pub unsafe extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize { - unsafe { kernel_function!(__sys_recv(fd, buf, len, flags)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_sendto( - socket: i32, - buf: *const u8, - len: usize, - flags: i32, - addr: *const sockaddr, - addrlen: socklen_t, -) -> isize { - unsafe { kernel_function!(__sys_sendto(socket, buf, len, flags, addr, addrlen)) } -} - -#[no_mangle] -pub unsafe extern "C" fn sys_recvfrom( - socket: i32, - buf: *mut u8, - len: usize, - flags: i32, - addr: *mut sockaddr, - addrlen: *mut socklen_t, -) -> isize { - unsafe { kernel_function!(__sys_recvfrom(socket, buf, len, flags, addr, addrlen)) } -} diff --git a/src/syscalls/spinlock.rs b/src/syscalls/spinlock.rs index 515bc8bc6e..b398664bb0 100644 --- a/src/syscalls/spinlock.rs +++ b/src/syscalls/spinlock.rs @@ -14,7 +14,8 @@ pub struct SpinlockIrqSaveContainer<'a> { guard: Option>, } -unsafe extern "C" fn __sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -29,12 +30,8 @@ unsafe extern "C" fn __sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { - unsafe { kernel_function!(__sys_spinlock_init(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -46,12 +43,8 @@ unsafe extern "C" fn __sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { - unsafe { kernel_function!(__sys_spinlock_destroy(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -65,12 +58,8 @@ unsafe extern "C" fn __sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i3 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { - unsafe { kernel_function!(__sys_spinlock_lock(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -84,12 +73,8 @@ unsafe extern "C" fn __sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { - unsafe { kernel_function!(__sys_spinlock_unlock(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_irqsave_init( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_irqsave_init( lock: *mut *mut SpinlockIrqSaveContainer<'_>, ) -> i32 { if lock.is_null() { @@ -106,14 +91,8 @@ unsafe extern "C" fn __sys_spinlock_irqsave_init( 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_irqsave_init( - lock: *mut *mut SpinlockIrqSaveContainer<'_>, -) -> i32 { - unsafe { kernel_function!(__sys_spinlock_irqsave_init(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_irqsave_destroy( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_irqsave_destroy( lock: *mut SpinlockIrqSaveContainer<'_>, ) -> i32 { if lock.is_null() { @@ -127,14 +106,8 @@ unsafe extern "C" fn __sys_spinlock_irqsave_destroy( 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_irqsave_destroy( - lock: *mut SpinlockIrqSaveContainer<'_>, -) -> i32 { - unsafe { kernel_function!(__sys_spinlock_irqsave_destroy(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; } @@ -148,12 +121,10 @@ unsafe extern "C" fn __sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveConta 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { - unsafe { kernel_function!(__sys_spinlock_irqsave_lock(lock)) } -} - -unsafe extern "C" fn __sys_spinlock_irqsave_unlock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spinlock_irqsave_unlock( + lock: *mut SpinlockIrqSaveContainer<'_>, +) -> i32 { if lock.is_null() { return -EINVAL; } @@ -166,10 +137,3 @@ unsafe extern "C" fn __sys_spinlock_irqsave_unlock(lock: *mut SpinlockIrqSaveCon container.guard = None; 0 } - -#[no_mangle] -pub unsafe extern "C" fn sys_spinlock_irqsave_unlock( - lock: *mut SpinlockIrqSaveContainer<'_>, -) -> i32 { - unsafe { kernel_function!(__sys_spinlock_irqsave_unlock(lock)) } -} diff --git a/src/syscalls/system.rs b/src/syscalls/system.rs index 85ecebc6ce..36fee902a4 100644 --- a/src/syscalls/system.rs +++ b/src/syscalls/system.rs @@ -1,8 +1,4 @@ -extern "C" fn __sys_getpagesize() -> i32 { - crate::arch::mm::paging::get_application_page_size() as i32 -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_getpagesize() -> i32 { - kernel_function!(__sys_getpagesize()) + crate::arch::mm::paging::get_application_page_size() as i32 } diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index d02be3038c..20a859dad7 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -20,17 +20,14 @@ use crate::{arch, scheduler}; pub type SignalHandler = extern "C" fn(i32); pub type Tid = u32; -extern "C" fn __sys_getpid() -> Tid { - core_scheduler().get_current_task_id().into() -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_getpid() -> Tid { - kernel_function!(__sys_getpid()) + core_scheduler().get_current_task_id().into() } #[cfg(feature = "newlib")] -extern "C" fn __sys_getprio(id: *const Tid) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_getprio(id: *const Tid) -> i32 { let task = core_scheduler().get_current_task_handle(); if id.is_null() || unsafe { *id } == task.get_id().into() { @@ -41,13 +38,7 @@ extern "C" fn __sys_getprio(id: *const Tid) -> i32 { } #[cfg(feature = "newlib")] -#[no_mangle] -pub extern "C" fn sys_getprio(id: *const Tid) -> i32 { - kernel_function!(__sys_getprio(id)) -} - -#[cfg(feature = "newlib")] -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_setprio(_id: *const Tid, _prio: i32) -> i32 { -ENOSYS } @@ -57,32 +48,20 @@ fn exit(arg: i32) -> ! { super::shutdown(arg) } -extern "C" fn __sys_exit(arg: i32) -> ! { - exit(arg) -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_exit(arg: i32) -> ! { - kernel_function!(__sys_exit(arg)) + exit(arg) } -extern "C" fn __sys_thread_exit(arg: i32) -> ! { +#[hermit_macro::system] +pub extern "C" fn sys_thread_exit(arg: i32) -> ! { debug!("Exit thread with error code {}!", arg); core_scheduler().exit(arg) } -#[no_mangle] -pub extern "C" fn sys_thread_exit(arg: i32) -> ! { - kernel_function!(__sys_thread_exit(arg)) -} - -extern "C" fn __sys_abort() -> ! { - exit(-1) -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_abort() -> ! { - kernel_function!(__sys_abort()) + exit(-1) } #[cfg(feature = "newlib")] @@ -94,7 +73,8 @@ pub fn sbrk_init() { } #[cfg(feature = "newlib")] -extern "C" fn __sys_sbrk(incr: isize) -> usize { +#[hermit_macro::system] +pub extern "C" fn sys_sbrk(incr: isize) -> usize { // Get the boundaries of the task heap and verify that they are suitable for sbrk. let task_heap_start = task_heap_start(); let task_heap_end = task_heap_end(); @@ -111,12 +91,6 @@ extern "C" fn __sys_sbrk(incr: isize) -> usize { old_end } -#[cfg(feature = "newlib")] -#[no_mangle] -pub extern "C" fn sys_sbrk(incr: isize) -> usize { - kernel_function!(__sys_sbrk(incr)) -} - pub(super) fn usleep(usecs: u64) { if usecs >= 10_000 { // Enough time to set a wakeup timer and block the current task. @@ -136,25 +110,18 @@ pub(super) fn usleep(usecs: u64) { } } -pub(crate) extern "C" fn __sys_usleep(usecs: u64) { - usleep(usecs) -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_usleep(usecs: u64) { - kernel_function!(__sys_usleep(usecs)) -} - -pub(crate) extern "C" fn __sys_msleep(ms: u32) { - usleep(u64::from(ms) * 1000) + usleep(usecs) } -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_msleep(ms: u32) { - kernel_function!(__sys_msleep(ms)) + usleep(u64::from(ms) * 1000) } -unsafe extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 { assert!( !rqtp.is_null(), "sys_nanosleep called with a zero rqtp parameter" @@ -175,13 +142,10 @@ unsafe extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> i32 { - unsafe { kernel_function!(__sys_nanosleep(rqtp, rmtp)) } -} - +/// Creates a new thread based on the configuration of the current thread. #[cfg(feature = "newlib")] -extern "C" fn __sys_clone(id: *mut Tid, func: extern "C" fn(usize), arg: usize) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_clone(id: *mut Tid, func: extern "C" fn(usize), arg: usize) -> i32 { let task_id = core_scheduler().clone(func, arg); if !id.is_null() { @@ -193,24 +157,14 @@ extern "C" fn __sys_clone(id: *mut Tid, func: extern "C" fn(usize), arg: usize) 0 } -/// Creates a new thread based on the configuration of the current thread. -#[cfg(feature = "newlib")] -#[no_mangle] -pub extern "C" fn sys_clone(id: *mut Tid, func: extern "C" fn(usize), arg: usize) -> i32 { - kernel_function!(__sys_clone(id, func, arg)) -} - -extern "C" fn __sys_yield() { - core_scheduler().reschedule(); -} - -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_yield() { - kernel_function!(__sys_yield()) + core_scheduler().reschedule(); } #[cfg(feature = "newlib")] -extern "C" fn __sys_kill(dest: Tid, signum: i32) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_kill(dest: Tid, signum: i32) -> i32 { debug!( "sys_kill is unimplemented, returning -ENOSYS for killing {} with signal {}", dest, signum @@ -219,34 +173,13 @@ extern "C" fn __sys_kill(dest: Tid, signum: i32) -> i32 { } #[cfg(feature = "newlib")] -#[no_mangle] -pub extern "C" fn sys_kill(dest: Tid, signum: i32) -> i32 { - kernel_function!(__sys_kill(dest, signum)) -} - -#[cfg(feature = "newlib")] -extern "C" fn __sys_signal(_handler: SignalHandler) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_signal(_handler: SignalHandler) -> i32 { debug!("sys_signal is unimplemented"); 0 } -#[cfg(feature = "newlib")] -#[no_mangle] -pub extern "C" fn sys_signal(handler: SignalHandler) -> i32 { - kernel_function!(__sys_signal(handler)) -} - -unsafe extern "C" fn __sys_spawn2( - func: unsafe extern "C" fn(usize), - arg: usize, - prio: u8, - stack_size: usize, - selector: isize, -) -> Tid { - unsafe { scheduler::spawn(func, arg, Priority::from(prio), stack_size, selector).into() } -} - -#[no_mangle] +#[hermit_macro::system] pub unsafe extern "C" fn sys_spawn2( func: unsafe extern "C" fn(usize), arg: usize, @@ -254,10 +187,11 @@ pub unsafe extern "C" fn sys_spawn2( stack_size: usize, selector: isize, ) -> Tid { - unsafe { kernel_function!(__sys_spawn2(func, arg, prio, stack_size, selector)) } + unsafe { scheduler::spawn(func, arg, Priority::from(prio), stack_size, selector).into() } } -unsafe extern "C" fn __sys_spawn( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_spawn( id: *mut Tid, func: unsafe extern "C" fn(usize), arg: usize, @@ -277,29 +211,14 @@ unsafe extern "C" fn __sys_spawn( 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_spawn( - id: *mut Tid, - func: unsafe extern "C" fn(usize), - arg: usize, - prio: u8, - selector: isize, -) -> i32 { - unsafe { kernel_function!(__sys_spawn(id, func, arg, prio, selector)) } -} - -extern "C" fn __sys_join(id: Tid) -> i32 { +#[hermit_macro::system] +pub extern "C" fn sys_join(id: Tid) -> i32 { match scheduler::join(TaskId::from(id)) { Ok(()) => 0, _ => -EINVAL, } } -#[no_mangle] -pub extern "C" fn sys_join(id: Tid) -> i32 { - kernel_function!(__sys_join(id)) -} - /// Mapping between blocked tasks and their TaskHandle static BLOCKED_TASKS: InterruptTicketMutex> = InterruptTicketMutex::new(BTreeMap::new()); @@ -314,27 +233,21 @@ fn block_current_task(timeout: &Option) { core_scheduler.block_current_task(wakeup_time); } -extern "C" fn __sys_block_current_task() { - block_current_task(&None) -} - /// Set the current task state to `blocked` -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_block_current_task() { - kernel_function!(__sys_block_current_task()) -} - -extern "C" fn __sys_block_current_task_with_timeout(timeout: u64) { - block_current_task(&Some(timeout)) + block_current_task(&None) } /// Set the current task state to `blocked` -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_block_current_task_with_timeout(timeout: u64) { - kernel_function!(__sys_block_current_task_with_timeout(timeout)) + block_current_task(&Some(timeout)) } -extern "C" fn __sys_wakeup_task(id: Tid) { +/// Wake up the task with the identifier `id` +#[hermit_macro::system] +pub extern "C" fn sys_wakeup_task(id: Tid) { let task_id = TaskId::from(id); if let Some(handle) = BLOCKED_TASKS.lock().remove(&task_id) { @@ -342,23 +255,15 @@ extern "C" fn __sys_wakeup_task(id: Tid) { } } -/// Wake up the task with the identifier `id` -#[no_mangle] -pub extern "C" fn sys_wakeup_task(id: Tid) { - kernel_function!(__sys_wakeup_task(id)) -} - -extern "C" fn __sys_get_priority() -> u8 { - core_scheduler().get_current_task_prio().into() -} - /// Determine the priority of the current thread -#[no_mangle] +#[hermit_macro::system] pub extern "C" fn sys_get_priority() -> u8 { - kernel_function!(__sys_get_priority()) + core_scheduler().get_current_task_prio().into() } -extern "C" fn __sys_set_priority(id: Tid, prio: u8) { +/// Set priority of the thread with the identifier `id` +#[hermit_macro::system] +pub extern "C" fn sys_set_priority(id: Tid, prio: u8) { if prio > 0 { core_scheduler() .set_priority(TaskId::from(id), Priority::from(prio)) @@ -368,22 +273,12 @@ extern "C" fn __sys_set_priority(id: Tid, prio: u8) { } } -/// Set priority of the thread with the identifier `id` -#[no_mangle] -pub extern "C" fn sys_set_priority(id: Tid, prio: u8) { - kernel_function!(__sys_set_priority(id, prio)) -} - -extern "C" fn __sys_set_current_task_priority(prio: u8) { +/// Set priority of the current thread +#[hermit_macro::system] +pub extern "C" fn sys_set_current_task_priority(prio: u8) { if prio > 0 { core_scheduler().set_current_task_priority(Priority::from(prio)); } else { panic!("Invalid priority {}", prio); } } - -/// Set priority of the current thread -#[no_mangle] -pub extern "C" fn sys_set_current_task_priority(prio: u8) { - kernel_function!(__sys_set_current_task_priority(prio)) -} diff --git a/src/syscalls/timer.rs b/src/syscalls/timer.rs index 7bee508e92..56603665b7 100644 --- a/src/syscalls/timer.rs +++ b/src/syscalls/timer.rs @@ -19,7 +19,8 @@ pub(crate) const TIMER_ABSTIME: i32 = 4; /// - `CLOCK_PROCESS_CPUTIME_ID` /// - `CLOCK_THREAD_CPUTIME_ID` /// - `CLOCK_MONOTONIC` -unsafe extern "C" fn __sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { assert!( !res.is_null(), "sys_clock_getres called with a zero res parameter" @@ -39,11 +40,6 @@ unsafe extern "C" fn __sys_clock_getres(clock_id: u64, res: *mut timespec) -> i3 } } -#[no_mangle] -pub unsafe extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { - unsafe { kernel_function!(__sys_clock_getres(clock_id, res)) } -} - /// Get the current time of a clock. /// /// Get the current time of the clock with `clock_id` and stores result in parameter `res`. @@ -52,7 +48,8 @@ pub unsafe extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> /// Supported clocks: /// - `CLOCK_REALTIME` /// - `CLOCK_MONOTONIC` -unsafe extern "C" fn __sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { assert!( !tp.is_null(), "sys_clock_gettime called with a zero tp parameter" @@ -78,11 +75,6 @@ unsafe extern "C" fn __sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i3 } } -#[no_mangle] -pub unsafe extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { - unsafe { kernel_function!(__sys_clock_gettime(clock_id, tp)) } -} - /// Sleep a clock for a specified number of nanoseconds. /// /// The requested time (in nanoseconds) must be greater than 0 and less than 1,000,000. @@ -92,7 +84,8 @@ pub unsafe extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> /// Supported clocks: /// - `CLOCK_REALTIME` /// - `CLOCK_MONOTONIC` -unsafe extern "C" fn __sys_clock_nanosleep( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_clock_nanosleep( clock_id: u64, flags: i32, rqtp: *const timespec, @@ -131,34 +124,21 @@ unsafe extern "C" fn __sys_clock_nanosleep( } } -#[no_mangle] -pub unsafe extern "C" fn sys_clock_nanosleep( - clock_id: u64, - flags: i32, - rqtp: *const timespec, - rmtp: *mut timespec, -) -> i32 { - unsafe { kernel_function!(__sys_clock_nanosleep(clock_id, flags, rqtp, rmtp)) } -} - -unsafe extern "C" fn __sys_clock_settime(_clock_id: u64, _tp: *const timespec) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_clock_settime(_clock_id: u64, _tp: *const timespec) -> i32 { // We don't support setting any clocks yet. debug!("sys_clock_settime is unimplemented, returning -EINVAL"); -EINVAL } -#[no_mangle] -pub unsafe extern "C" fn sys_clock_settime(clock_id: u64, tp: *const timespec) -> i32 { - unsafe { kernel_function!(__sys_clock_settime(clock_id, tp)) } -} - /// Get the system's clock time. /// /// This function gets the current time based on the wallclock time when booted up, plus current timer ticks. /// Returns `0` on success, `-EINVAL` otherwise. /// /// **Parameter `tz` should be set to `0` since tz is obsolete.** -unsafe extern "C" fn __sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { +#[hermit_macro::system] +pub unsafe extern "C" fn sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { if let Some(result) = unsafe { tp.as_mut() } { // Return the current time based on the wallclock time when we were booted up // plus the current timer ticks. @@ -174,13 +154,8 @@ unsafe extern "C" fn __sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { 0 } -#[no_mangle] -pub unsafe extern "C" fn sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { - unsafe { kernel_function!(__sys_gettimeofday(tp, tz)) } -} - -#[no_mangle] -unsafe extern "C" fn __sys_setitimer( +#[hermit_macro::system] +pub unsafe extern "C" fn sys_setitimer( _which: i32, _value: *const itimerval, _ovalue: *mut itimerval, @@ -188,12 +163,3 @@ unsafe extern "C" fn __sys_setitimer( debug!("Called sys_setitimer, which is unimplemented and always returns 0"); 0 } - -#[no_mangle] -pub unsafe extern "C" fn sys_setitimer( - which: i32, - value: *const itimerval, - ovalue: *mut itimerval, -) -> i32 { - unsafe { kernel_function!(__sys_setitimer(which, value, ovalue)) } -}