From df197d254d95d0cfbc9c27a1c01250115e51a5bf Mon Sep 17 00:00:00 2001 From: CarlWachter Date: Tue, 21 May 2024 11:53:29 +0200 Subject: [PATCH 1/2] Added no_mangle to all extern C functions --- hermit-macro/src/system.rs | 21 ++++++++++++++++++--- src/syscalls/condvar.rs | 5 +++++ src/syscalls/entropy.rs | 4 ++++ src/syscalls/futex.rs | 2 ++ src/syscalls/lwip.rs | 5 +++++ src/syscalls/mod.rs | 26 ++++++++++++++++++++++++++ src/syscalls/processor.rs | 3 +++ src/syscalls/recmutex.rs | 4 ++++ src/syscalls/semaphore.rs | 5 +++++ src/syscalls/socket.rs | 16 ++++++++++++++++ src/syscalls/spinlock.rs | 8 ++++++++ src/syscalls/system.rs | 1 + src/syscalls/tasks.rs | 23 +++++++++++++++++++++++ src/syscalls/timer.rs | 6 ++++++ 14 files changed, 126 insertions(+), 3 deletions(-) diff --git a/hermit-macro/src/system.rs b/hermit-macro/src/system.rs index 72d352548b..c8c257f81c 100644 --- a/hermit-macro/src/system.rs +++ b/hermit-macro/src/system.rs @@ -59,13 +59,27 @@ fn parse_sig(sig: &Signature) -> Result { } fn validate_attrs(attrs: &[Attribute]) -> Result<()> { + let mut no_mangle_found = false; for attr in attrs { - if !attr.path().is_ident("cfg") && !attr.path().is_ident("doc") { + if !attr.path().is_ident("cfg") + && !attr.path().is_ident("doc") + && !attr.path().is_ident("no_mangle") + { bail!( attr, - "#[system] functions may only have `#[doc]` and `#[cfg]` attributes" + "#[system] functions may only have `#[doc]`, `#[no_mangle]` and `#[cfg]` attributes" ); } + if attr.path().is_ident("no_mangle") { + no_mangle_found = true; + } + } + + if !no_mangle_found { + bail!( + attrs.first(), + "#[system] functions must have `#[no_mangle]` attribute" + ); } Ok(()) @@ -96,7 +110,6 @@ fn emit_func(mut func: ItemFn, sig: &ParsedSig) -> Result { let func = parse_quote! { #(#attrs)* - #[no_mangle] #vis #sig { #func @@ -128,6 +141,7 @@ mod tests { /// /// This is very important. #[cfg(target_os = "none")] + #[no_mangle] pub extern "C" fn sys_test(a: i8, b: i16) -> i32 { let c = i16::from(a) + b; i32::from(c) @@ -164,6 +178,7 @@ mod tests { /// /// This is very important. #[cfg(target_os = "none")] + #[no_mangle] pub unsafe extern "C" fn sys_test(a: i8, b: i16) -> i32 { let c = i16::from(a) + b; i32::from(c) diff --git a/src/syscalls/condvar.rs b/src/syscalls/condvar.rs index 95e1d72ba8..1c0049b255 100644 --- a/src/syscalls/condvar.rs +++ b/src/syscalls/condvar.rs @@ -24,6 +24,7 @@ impl CondQueue { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_destroy_queue(ptr: usize) -> i32 { unsafe { let id = ptr::with_exposed_provenance_mut::(ptr); @@ -42,6 +43,7 @@ pub unsafe extern "C" fn sys_destroy_queue(ptr: usize) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_notify(ptr: usize, count: i32) -> i32 { unsafe { let id = ptr::with_exposed_provenance::(ptr); @@ -79,6 +81,7 @@ pub unsafe extern "C" fn sys_notify(ptr: usize, count: i32) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_init_queue(ptr: usize) -> i32 { unsafe { let id = ptr::with_exposed_provenance_mut::(ptr); @@ -98,6 +101,7 @@ pub unsafe extern "C" fn sys_init_queue(ptr: usize) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { unsafe { let id = ptr::with_exposed_provenance_mut::(ptr); @@ -126,6 +130,7 @@ pub unsafe extern "C" fn sys_add_queue(ptr: usize, timeout_ns: i64) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_wait(ptr: usize) -> i32 { unsafe { let id = ptr::with_exposed_provenance_mut::(ptr); diff --git a/src/syscalls/entropy.rs b/src/syscalls/entropy.rs index 365d69e513..a841e8c473 100644 --- a/src/syscalls/entropy.rs +++ b/src/syscalls/entropy.rs @@ -63,6 +63,7 @@ pub unsafe extern "C" fn sys_read_entropy(buf: *mut u8, len: usize, flags: u32) /// the function returns `-1`. #[cfg(not(feature = "newlib"))] #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { let mut buf = value.cast(); let mut len = size_of::(); @@ -84,6 +85,7 @@ pub unsafe extern "C" fn sys_secure_rand32(value: *mut u32) -> i32 { /// the function returns -1. #[cfg(not(feature = "newlib"))] #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { let mut buf = value.cast(); let mut len = size_of::(); @@ -103,6 +105,7 @@ pub unsafe extern "C" fn sys_secure_rand64(value: *mut u64) -> i32 { /// The function computes a sequence of pseudo-random integers /// in the range of 0 to RAND_MAX #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_rand() -> u32 { generate_park_miller_lehmer_random_number() } @@ -110,6 +113,7 @@ pub extern "C" fn sys_rand() -> u32 { /// The function sets its argument as the seed for a new sequence /// of pseudo-random numbers to be returned by rand() #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_srand(seed: u32) { *(PARK_MILLER_LEHMER_SEED.lock()) = seed; } diff --git a/src/syscalls/futex.rs b/src/syscalls/futex.rs index 558aab53f3..3bd0cf952f 100644 --- a/src/syscalls/futex.rs +++ b/src/syscalls/futex.rs @@ -11,6 +11,7 @@ use crate::time::timespec; /// * `timeout` is negative /// * `flags` contains unknown flags #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_futex_wait( address: *mut u32, expected: u32, @@ -42,6 +43,7 @@ pub unsafe extern "C" fn sys_futex_wait( /// /// Returns -EINVAL if `address` is null. #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { if address.is_null() { return -EINVAL; diff --git a/src/syscalls/lwip.rs b/src/syscalls/lwip.rs index 812f8c6e82..74677e42b3 100644 --- a/src/syscalls/lwip.rs +++ b/src/syscalls/lwip.rs @@ -5,16 +5,19 @@ use crate::arch::core_local::core_scheduler; use crate::{arch, console}; #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_lwip_get_errno() -> i32 { core_scheduler().get_lwip_errno() } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_lwip_set_errno(errno: i32) { core_scheduler().set_lwip_errno(errno); } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_acquire_putchar_lock() { // FIXME: use core-local storage instead // better yet: remove and replace all of this @@ -22,11 +25,13 @@ pub extern "C" fn sys_acquire_putchar_lock() { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_putchar(character: u8) { arch::output_message_buf(&[character]); } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_release_putchar_lock() { unsafe { console::CONSOLE.force_unlock(); diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index f51636885b..21ece2cbea 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -82,6 +82,7 @@ pub(crate) fn init() { /// #[cfg(all(target_os = "none", not(feature = "common-os")))] #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_alloc(size: usize, align: usize) -> *mut u8 { let layout_res = Layout::from_size_align(size, align); if layout_res.is_err() || size == 0 { @@ -106,6 +107,7 @@ pub extern "C" fn sys_alloc(size: usize, align: usize) -> *mut u8 { #[cfg(all(target_os = "none", not(feature = "common-os")))] #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_alloc_zeroed(size: usize, align: usize) -> *mut u8 { let layout_res = Layout::from_size_align(size, align); if layout_res.is_err() || size == 0 { @@ -130,6 +132,7 @@ pub extern "C" fn sys_alloc_zeroed(size: usize, align: usize) -> *mut u8 { #[cfg(all(target_os = "none", not(feature = "common-os")))] #[hermit_macro::system] +#[no_mangle] 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 { @@ -173,6 +176,7 @@ pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 { /// allocator, or if reallocation otherwise fails. #[cfg(all(target_os = "none", not(feature = "common-os")))] #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_realloc( ptr: *mut u8, size: usize, @@ -219,6 +223,7 @@ pub unsafe extern "C" fn sys_realloc( /// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed. #[cfg(all(target_os = "none", not(feature = "common-os")))] #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_dealloc(ptr: *mut u8, size: usize, align: usize) { unsafe { let layout_res = Layout::from_size_align(size, align); @@ -243,6 +248,7 @@ pub unsafe extern "C" fn sys_dealloc(ptr: *mut u8, size: usize, align: usize) { #[cfg(all(target_os = "none", not(feature = "common-os")))] #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) { unsafe { let layout_res = Layout::from_size_align(size, align); @@ -278,11 +284,13 @@ pub(crate) fn shutdown(arg: i32) -> ! { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_shutdown(arg: i32) -> ! { shutdown(arg) } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_unlink(name: *const u8) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); @@ -294,6 +302,7 @@ pub unsafe extern "C" fn sys_unlink(name: *const u8) -> i32 { } #[hermit_macro::system] +#[no_mangle] 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) { @@ -310,6 +319,7 @@ pub unsafe extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_rmdir(name: *const c_char) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); @@ -321,6 +331,7 @@ pub unsafe extern "C" fn sys_rmdir(name: *const c_char) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_stat(name: *const c_char, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); @@ -334,6 +345,7 @@ pub unsafe extern "C" fn sys_stat(name: *const c_char, stat: *mut FileAttr) -> i } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_lstat(name: *const c_char, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); @@ -347,6 +359,7 @@ pub unsafe extern "C" fn sys_lstat(name: *const c_char, stat: *mut FileAttr) -> } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i32 { let stat = unsafe { &mut *stat }; let obj = get_object(fd); @@ -360,6 +373,7 @@ pub unsafe extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_opendir(name: *const c_char) -> 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()) @@ -369,6 +383,7 @@ pub unsafe extern "C" fn sys_opendir(name: *const c_char) -> FileDescriptor { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_open(name: *const c_char, flags: i32, mode: u32) -> FileDescriptor { let flags = if let Some(flags) = OpenOption::from_bits(flags) { flags @@ -390,12 +405,14 @@ pub unsafe extern "C" fn sys_open(name: *const c_char, flags: i32, mode: u32) -> } #[hermit_macro::system] +#[no_mangle] 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) } #[hermit_macro::system] +#[no_mangle] 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( @@ -413,11 +430,13 @@ unsafe fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize { unsafe { write(fd, buf, len) } } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_ioctl( fd: FileDescriptor, cmd: i32, @@ -443,6 +462,7 @@ pub unsafe extern "C" fn sys_ioctl( /// manipulate file descriptor #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { const F_SETFD: i32 = 2; const F_SETFL: i32 = 4; @@ -466,6 +486,7 @@ pub extern "C" fn sys_fcntl(fd: i32, cmd: i32, arg: i32) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_lseek(fd: FileDescriptor, offset: isize, whence: i32) -> isize { let obj = get_object(fd); obj.map_or_else( @@ -493,6 +514,7 @@ pub struct Dirent64 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_getdents64( fd: FileDescriptor, dirp: *mut Dirent64, @@ -546,11 +568,13 @@ pub unsafe extern "C" fn sys_getdents64( } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_dup(fd: i32) -> i32 { dup_object(fd).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) } #[hermit_macro::system] +#[no_mangle] 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 { @@ -574,6 +598,7 @@ pub unsafe extern "C" fn sys_poll(fds: *mut PollFd, nfds: usize, timeout: i32) - } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_eventfd(initval: u64, flags: i16) -> i32 { if let Some(flags) = EventFlags::from_bits(flags) { crate::fd::eventfd(initval, flags) @@ -584,6 +609,7 @@ pub extern "C" fn sys_eventfd(initval: u64, flags: i16) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_image_start_addr() -> usize { crate::mm::kernel_start_address().0.try_into().unwrap() } diff --git a/src/syscalls/processor.rs b/src/syscalls/processor.rs index 3eeb2a0b78..d462e87128 100644 --- a/src/syscalls/processor.rs +++ b/src/syscalls/processor.rs @@ -2,17 +2,20 @@ use crate::arch::get_processor_count; /// Returns the number of processors currently online. #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_get_processor_count() -> usize { get_processor_count().try_into().unwrap() } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_available_parallelism() -> usize { get_processor_count().try_into().unwrap() } /// Returns the processor frequency in MHz. #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_get_processor_frequency() -> u16 { crate::arch::processor::get_frequency() } diff --git a/src/syscalls/recmutex.rs b/src/syscalls/recmutex.rs index 2b2021d9e9..93a0331b07 100644 --- a/src/syscalls/recmutex.rs +++ b/src/syscalls/recmutex.rs @@ -4,6 +4,7 @@ use crate::errno::*; use crate::synch::recmutex::RecursiveMutex; #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_recmutex_init(recmutex: *mut *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; @@ -19,6 +20,7 @@ pub extern "C" fn sys_recmutex_init(recmutex: *mut *mut RecursiveMutex) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_recmutex_destroy(recmutex: *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; @@ -34,6 +36,7 @@ pub extern "C" fn sys_recmutex_destroy(recmutex: *mut RecursiveMutex) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_recmutex_lock(recmutex: *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; @@ -46,6 +49,7 @@ pub extern "C" fn sys_recmutex_lock(recmutex: *mut RecursiveMutex) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_recmutex_unlock(recmutex: *mut RecursiveMutex) -> i32 { if recmutex.is_null() { return -EINVAL; diff --git a/src/syscalls/semaphore.rs b/src/syscalls/semaphore.rs index 8aef93d3f9..98fc0336bc 100644 --- a/src/syscalls/semaphore.rs +++ b/src/syscalls/semaphore.rs @@ -14,6 +14,7 @@ pub type sem_t = *const Semaphore; /// Stores the raw memory location of the new semaphore in parameter `sem`. /// Returns `0` on success, `-EINVAL` if `sem` is null. #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_sem_init(sem: *mut sem_t, pshared: i32, value: u32) -> i32 { if sem.is_null() || pshared != 0 { return -EINVAL; @@ -33,6 +34,7 @@ pub unsafe extern "C" fn sys_sem_init(sem: *mut sem_t, pshared: i32, value: u32) /// /// Returns `0` on success, `-EINVAL` if `sem` is null. #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_sem_destroy(sem: *mut sem_t) -> i32 { if sem.is_null() { return -EINVAL; @@ -54,6 +56,7 @@ pub unsafe extern "C" fn sys_sem_destroy(sem: *mut sem_t) -> i32 { /// /// Returns `0` on success, or `-EINVAL` if `sem` is null. #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_sem_post(sem: *mut sem_t) -> i32 { if sem.is_null() { return -EINVAL; @@ -72,6 +75,7 @@ pub unsafe extern "C" fn sys_sem_post(sem: *mut sem_t) -> i32 { /// /// Returns `0` on lock acquire, `-EINVAL` if `sem` is null, or `-ECANCELED` if the decrement fails. #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_sem_trywait(sem: *mut sem_t) -> i32 { if sem.is_null() { return -EINVAL; @@ -108,6 +112,7 @@ unsafe fn sem_timedwait(sem: *mut sem_t, ms: u32) -> i32 { /// /// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout. #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_sem_timedwait(sem: *mut sem_t, ts: *const timespec) -> i32 { if ts.is_null() { unsafe { sem_timedwait(sem, 0) } diff --git a/src/syscalls/socket.rs b/src/syscalls/socket.rs index 47a38ea012..818f43023b 100644 --- a/src/syscalls/socket.rs +++ b/src/syscalls/socket.rs @@ -252,6 +252,7 @@ pub struct linger { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 { debug!( "sys_socket: domain {}, type {:?}, protocol {}", @@ -305,6 +306,7 @@ pub extern "C" fn sys_socket(domain: i32, type_: SockType, protocol: i32) -> i32 } #[hermit_macro::system] +#[no_mangle] 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( @@ -346,6 +348,7 @@ pub unsafe extern "C" fn sys_accept(fd: i32, addr: *mut sockaddr, addrlen: *mut } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_listen(fd: i32, backlog: i32) -> i32 { let obj = get_object(fd); obj.map_or_else( @@ -358,6 +361,7 @@ pub extern "C" fn sys_listen(fd: i32, backlog: i32) -> i32 { } #[hermit_macro::system] +#[no_mangle] 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) }) @@ -378,6 +382,7 @@ pub unsafe extern "C" fn sys_bind(fd: i32, name: *const sockaddr, namelen: sockl } #[hermit_macro::system] +#[no_mangle] 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) }) @@ -398,6 +403,7 @@ pub unsafe extern "C" fn sys_connect(fd: i32, name: *const sockaddr, namelen: so } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_getsockname( fd: i32, addr: *mut sockaddr, @@ -442,6 +448,7 @@ pub unsafe extern "C" fn sys_getsockname( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_setsockopt( fd: i32, level: i32, @@ -479,6 +486,7 @@ pub unsafe extern "C" fn sys_setsockopt( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_getsockopt( fd: i32, level: i32, @@ -523,6 +531,7 @@ pub unsafe extern "C" fn sys_getsockopt( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_getpeername( fd: i32, addr: *mut sockaddr, @@ -567,9 +576,11 @@ pub unsafe extern "C" fn sys_getpeername( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_freeaddrinfo(_ai: *mut addrinfo) {} #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_getaddrinfo( _nodename: *const c_char, _servname: *const c_char, @@ -580,11 +591,13 @@ pub unsafe extern "C" fn sys_getaddrinfo( } #[hermit_macro::system] +#[no_mangle] 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) } } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_shutdown_socket(fd: i32, how: i32) -> i32 { let obj = get_object(fd); obj.map_or_else( @@ -597,6 +610,7 @@ pub extern "C" fn sys_shutdown_socket(fd: i32, how: i32) -> i32 { } #[hermit_macro::system] +#[no_mangle] 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) }; @@ -610,6 +624,7 @@ pub unsafe extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_sendto( fd: i32, buf: *const u8, @@ -640,6 +655,7 @@ pub unsafe extern "C" fn sys_sendto( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_recvfrom( fd: i32, buf: *mut u8, diff --git a/src/syscalls/spinlock.rs b/src/syscalls/spinlock.rs index b398664bb0..5fa3b89509 100644 --- a/src/syscalls/spinlock.rs +++ b/src/syscalls/spinlock.rs @@ -15,6 +15,7 @@ pub struct SpinlockIrqSaveContainer<'a> { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; @@ -31,6 +32,7 @@ pub unsafe extern "C" fn sys_spinlock_init(lock: *mut *mut SpinlockContainer<'_> } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; @@ -44,6 +46,7 @@ pub unsafe extern "C" fn sys_spinlock_destroy(lock: *mut SpinlockContainer<'_>) } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; @@ -59,6 +62,7 @@ pub unsafe extern "C" fn sys_spinlock_lock(lock: *mut SpinlockContainer<'_>) -> } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; @@ -74,6 +78,7 @@ pub unsafe extern "C" fn sys_spinlock_unlock(lock: *mut SpinlockContainer<'_>) - } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_irqsave_init( lock: *mut *mut SpinlockIrqSaveContainer<'_>, ) -> i32 { @@ -92,6 +97,7 @@ pub unsafe extern "C" fn sys_spinlock_irqsave_init( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_irqsave_destroy( lock: *mut SpinlockIrqSaveContainer<'_>, ) -> i32 { @@ -107,6 +113,7 @@ pub unsafe extern "C" fn sys_spinlock_irqsave_destroy( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveContainer<'_>) -> i32 { if lock.is_null() { return -EINVAL; @@ -122,6 +129,7 @@ pub unsafe extern "C" fn sys_spinlock_irqsave_lock(lock: *mut SpinlockIrqSaveCon } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spinlock_irqsave_unlock( lock: *mut SpinlockIrqSaveContainer<'_>, ) -> i32 { diff --git a/src/syscalls/system.rs b/src/syscalls/system.rs index 36fee902a4..af8c1c4032 100644 --- a/src/syscalls/system.rs +++ b/src/syscalls/system.rs @@ -1,4 +1,5 @@ #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_getpagesize() -> i32 { crate::arch::mm::paging::get_application_page_size() as i32 } diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index fdfe3a5a9a..277440398e 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -20,12 +20,14 @@ pub type SignalHandler = extern "C" fn(i32); pub type Tid = i32; #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_getpid() -> Tid { core_scheduler().get_current_task_id().into() } #[cfg(feature = "newlib")] #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_getprio(id: *const Tid) -> i32 { let task = core_scheduler().get_current_task_handle(); @@ -38,6 +40,7 @@ pub extern "C" fn sys_getprio(id: *const Tid) -> i32 { #[cfg(feature = "newlib")] #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_setprio(_id: *const Tid, _prio: i32) -> i32 { -ENOSYS } @@ -48,17 +51,20 @@ fn exit(arg: i32) -> ! { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_exit(status: i32) -> ! { exit(status) } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_thread_exit(status: i32) -> ! { debug!("Exit thread with error code {}!", status); core_scheduler().exit(status) } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_abort() -> ! { exit(-1) } @@ -73,6 +79,7 @@ pub fn sbrk_init() { #[cfg(feature = "newlib")] #[hermit_macro::system] +#[no_mangle] 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(); @@ -110,16 +117,19 @@ pub(super) fn usleep(usecs: u64) { } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_msleep(ms: u32) { usleep(u64::from(ms) * 1000) } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_usleep(usecs: u64) { usleep(usecs) } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 { assert!( !rqtp.is_null(), @@ -141,6 +151,7 @@ pub unsafe extern "C" fn sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timesp /// Creates a new thread based on the configuration of the current thread. #[cfg(feature = "newlib")] #[hermit_macro::system] +#[no_mangle] 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); @@ -154,12 +165,14 @@ pub extern "C" fn sys_clone(id: *mut Tid, func: extern "C" fn(usize), arg: usize } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_yield() { core_scheduler().reschedule(); } #[cfg(feature = "newlib")] #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_kill(dest: Tid, signum: i32) -> i32 { debug!( "sys_kill is unimplemented, returning -ENOSYS for killing {} with signal {}", @@ -170,12 +183,14 @@ pub extern "C" fn sys_kill(dest: Tid, signum: i32) -> i32 { #[cfg(feature = "newlib")] #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_signal(_handler: SignalHandler) -> i32 { debug!("sys_signal is unimplemented"); 0 } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spawn2( func: unsafe extern "C" fn(usize), arg: usize, @@ -187,6 +202,7 @@ pub unsafe extern "C" fn sys_spawn2( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_spawn( id: *mut Tid, func: unsafe extern "C" fn(usize), @@ -208,6 +224,7 @@ pub unsafe extern "C" fn sys_spawn( } #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_join(id: Tid) -> i32 { match scheduler::join(TaskId::from(id)) { Ok(()) => 0, @@ -231,18 +248,21 @@ fn block_current_task(timeout: &Option) { /// Set the current task state to `blocked` #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_block_current_task() { block_current_task(&None) } /// Set the current task state to `blocked` #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_block_current_task_with_timeout(timeout: u64) { block_current_task(&Some(timeout)) } /// Wake up the task with the identifier `id` #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_wakeup_task(id: Tid) { let task_id = TaskId::from(id); @@ -253,12 +273,14 @@ pub extern "C" fn sys_wakeup_task(id: Tid) { /// Determine the priority of the current thread #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_get_priority() -> u8 { core_scheduler().get_current_task_prio().into() } /// Set priority of the thread with the identifier `id` #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_set_priority(id: Tid, prio: u8) { if prio > 0 { core_scheduler() @@ -271,6 +293,7 @@ pub extern "C" fn sys_set_priority(id: Tid, prio: u8) { /// Set priority of the current thread #[hermit_macro::system] +#[no_mangle] pub extern "C" fn sys_set_current_task_priority(prio: u8) { if prio > 0 { core_scheduler().set_current_task_priority(Priority::from(prio)); diff --git a/src/syscalls/timer.rs b/src/syscalls/timer.rs index 9a7218999f..48aab76dd1 100644 --- a/src/syscalls/timer.rs +++ b/src/syscalls/timer.rs @@ -23,6 +23,7 @@ pub(crate) const TIMER_ABSTIME: i32 = 4; /// - `CLOCK_THREAD_CPUTIME_ID` /// - `CLOCK_MONOTONIC` #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_clock_getres(clock_id: clockid_t, res: *mut timespec) -> i32 { assert!( !res.is_null(), @@ -52,6 +53,7 @@ pub unsafe extern "C" fn sys_clock_getres(clock_id: clockid_t, res: *mut timespe /// - `CLOCK_REALTIME` /// - `CLOCK_MONOTONIC` #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> i32 { assert!( !tp.is_null(), @@ -88,6 +90,7 @@ pub unsafe extern "C" fn sys_clock_gettime(clock_id: clockid_t, tp: *mut timespe /// - `CLOCK_REALTIME` /// - `CLOCK_MONOTONIC` #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_clock_nanosleep( clock_id: clockid_t, flags: i32, @@ -125,6 +128,7 @@ pub unsafe extern "C" fn sys_clock_nanosleep( } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_clock_settime(_clock_id: clockid_t, _tp: *const timespec) -> i32 { // We don't support setting any clocks yet. debug!("sys_clock_settime is unimplemented, returning -EINVAL"); @@ -138,6 +142,7 @@ pub unsafe extern "C" fn sys_clock_settime(_clock_id: clockid_t, _tp: *const tim /// /// **Parameter `tz` should be set to `0` since tz is obsolete.** #[hermit_macro::system] +#[no_mangle] 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 @@ -155,6 +160,7 @@ pub unsafe extern "C" fn sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { } #[hermit_macro::system] +#[no_mangle] pub unsafe extern "C" fn sys_setitimer( _which: i32, _value: *const itimerval, From ebe8bc3a111d73f24ccf3f2c548089ce5e01230a Mon Sep 17 00:00:00 2001 From: Jonathan Klimt Date: Tue, 21 May 2024 16:43:40 +0200 Subject: [PATCH 2/2] fix(virtio-pci): `next_ptr` + `cfg_ptr` offsets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bugfix: Use correct pointer in PCI capability, not the one to the proceeding element Bugfix: Virtio Capabilities - use correct offsets from `cfg_ptr` Co-authored-by: Martin Kröning Signed-off-by: Martin Kröning --- src/drivers/virtio/transport/pci.rs | 33 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/drivers/virtio/transport/pci.rs b/src/drivers/virtio/transport/pci.rs index f77c478706..961d25e093 100644 --- a/src/drivers/virtio/transport/pci.rs +++ b/src/drivers/virtio/transport/pci.rs @@ -702,9 +702,10 @@ impl NotifCfg { // Assumes the cap_len is a multiple of 8 // This read MIGHT be slow, as it does NOT ensure 32 bit alignment. - let notify_off_multiplier = cap.device.read_register( - u16::try_from(cap.origin.cfg_ptr).unwrap() + u16::from(cap.origin.cap_struct.cap_len), - ); + let notify_off_multiplier_ptr = + cap.origin.cfg_ptr + u32::try_from(mem::size_of::()).unwrap(); + let notify_off_multiplier_ptr = u16::try_from(notify_off_multiplier_ptr).unwrap(); + let notify_off_multiplier = cap.device.read_register(notify_off_multiplier_ptr); // define base memory address from which the actual Queue Notify address can be derived via // base_addr + queue_notify_off * notify_off_multiplier. @@ -921,8 +922,8 @@ impl PciCfgAlt { // #[repr(C)] // struct PciCap64 { // pci_cap: PciCap, -// offset_high: u32, -// length_high: u32 +// offset_hi: u32, +// length_hi: u32 pub struct ShMemCfg { mem_addr: VirtMemAddr, length: MemLen, @@ -947,24 +948,25 @@ impl ShMemCfg { // Assumes the cap_len is a multiple of 8 // This read MIGHT be slow, as it does NOT ensure 32 bit alignment. - let offset_high = cap.device.read_register( - u16::try_from(cap.origin.cfg_ptr).unwrap() + u16::from(cap.origin.cap_struct.cap_len), - ); + let offset_hi_ptr = + cap.origin.cfg_ptr + u32::try_from(mem::size_of::()).unwrap(); + let offset_hi_ptr = u16::try_from(offset_hi_ptr).unwrap(); + let offset_hi = cap.device.read_register(offset_hi_ptr); // Create 64 bit offset from high and low 32 bit values let offset = - MemOff::from((u64::from(offset_high) << 32) ^ u64::from(cap.origin.cap_struct.offset)); + MemOff::from((u64::from(offset_hi) << 32) ^ u64::from(cap.origin.cap_struct.offset)); // Assumes the cap_len is a multiple of 8 // This read MIGHT be slow, as it does NOT ensure 32 bit alignment. - let length_high = cap.device.read_register( - u16::try_from(cap.origin.cfg_ptr).unwrap() - + u16::from(cap.origin.cap_struct.cap_len + 4), - ); + let length_hi_ptr = cap.origin.cfg_ptr + + u32::try_from(mem::size_of::() + mem::size_of::()).unwrap(); + let length_hi_ptr = u16::try_from(length_hi_ptr).unwrap(); + let length_hi = cap.device.read_register(length_hi_ptr); // Create 64 bit length from high and low 32 bit values let length = - MemLen::from((u64::from(length_high) << 32) ^ u64::from(cap.origin.cap_struct.length)); + MemLen::from((u64::from(length_hi) << 32) ^ u64::from(cap.origin.cap_struct.length)); let virt_addr_raw = cap.bar.mem_addr + offset; let raw_ptr = ptr::with_exposed_provenance_mut::(virt_addr_raw.into()); @@ -1118,6 +1120,7 @@ fn read_caps( let mut iter = bars.iter(); + let cfg_ptr = next_ptr; // Set next pointer for next iteration of `caplist. next_ptr = u32::from(cap_raw.cap_next); @@ -1151,7 +1154,7 @@ fn read_caps( length: MemLen::from(cap_raw.length), device: *device, origin: Origin { - cfg_ptr: next_ptr, + cfg_ptr, dev_id: device_id, cap_struct: cap_raw, },