diff --git a/Cargo.lock b/Cargo.lock index 6bdf7c708..cfc3d4388 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2702,9 +2702,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signature" diff --git a/crates/private/support/sel4-simple-task/runtime/src/lib.rs b/crates/private/support/sel4-simple-task/runtime/src/lib.rs index e893590c0..c34b3e9b4 100644 --- a/crates/private/support/sel4-simple-task/runtime/src/lib.rs +++ b/crates/private/support/sel4-simple-task/runtime/src/lib.rs @@ -79,6 +79,7 @@ pub unsafe extern "C" fn cont_fn(cont_arg: *mut sel4_runtime_common::ContArg) -> CONFIG.set(config.clone()).unwrap(); sel4_runtime_common::set_eh_frame_finder().unwrap(); sel4_panicking::set_hook(&panic_hook); + sel4_runtime_common::run_ctors(); __sel4_simple_task_main(config.arg()); } else { let endpoint = Endpoint::from_bits(thread_config.endpoint().unwrap()); diff --git a/crates/sel4-microkit/src/entry.rs b/crates/sel4-microkit/src/entry.rs index be3a235ba..4ba7882cf 100644 --- a/crates/sel4-microkit/src/entry.rs +++ b/crates/sel4-microkit/src/entry.rs @@ -39,6 +39,7 @@ fn inner_entry() -> ! { unsafe { sel4::set_ipc_buffer(get_ipc_buffer()); + sel4_runtime_common::run_ctors(); __sel4_microkit__main(); } diff --git a/crates/sel4-microkit/src/lib.rs b/crates/sel4-microkit/src/lib.rs index b6ce10123..085717de9 100644 --- a/crates/sel4-microkit/src/lib.rs +++ b/crates/sel4-microkit/src/lib.rs @@ -66,7 +66,7 @@ pub use message::{ /// See the [`protection_domain`] attribute macro for more detail. #[macro_export] macro_rules! declare_protection_domain { - { + { init = $init:expr $(,)? } => { $crate::_private::declare_protection_domain! { diff --git a/crates/sel4-panicking/env/src/lib.rs b/crates/sel4-panicking/env/src/lib.rs index 91d1591c8..c520296ed 100644 --- a/crates/sel4-panicking/env/src/lib.rs +++ b/crates/sel4-panicking/env/src/lib.rs @@ -64,7 +64,7 @@ fn default_abort_hook(info: Option<&AbortInfo>) { /// Prints via a link-time hook. /// -/// This function uses the following externally defined symobol: +/// This function uses the following externally defined symbol: /// /// ```rust /// extern "Rust" { diff --git a/crates/sel4-root-task/src/lib.rs b/crates/sel4-root-task/src/lib.rs index 247e27267..4138dd4d5 100644 --- a/crates/sel4-root-task/src/lib.rs +++ b/crates/sel4-root-task/src/lib.rs @@ -48,6 +48,7 @@ fn inner_entry(bootinfo: *const sel4::sys::seL4_BootInfo) -> ! { unsafe { let bootinfo = sel4::BootInfo::from_ptr(bootinfo); sel4::set_ipc_buffer(bootinfo.ipc_buffer()); + sel4_runtime_common::run_ctors(); __sel4_root_task__main(&bootinfo); } @@ -88,31 +89,31 @@ sel4_panicking_env::register_debug_put_char!(sel4::debug_put_char); #[macro_export] macro_rules! declare_root_task { { - main = $main:expr $(,)? - } => { - $crate::_private::declare_root_task! { - main = $main, - stack_size = $crate::_private::DEFAULT_STACK_SIZE, - } - }; - { - main = $main:expr, - stack_size = $stack_size:expr $(,)? - } => { - $crate::_private::declare_main!($main); - $crate::_private::declare_stack!($stack_size); - }; - { - main = $main:expr, - $(stack_size = $stack_size:expr,)? - heap_size = $heap_size:expr $(,)? - } => { - $crate::_private::declare_heap!($heap_size); - $crate::_private::declare_root_task! { - main = $main, - $(stack_size = $stack_size,)? - } - }; + main = $main:expr $(,)? + } => { + $crate::_private::declare_root_task! { + main = $main, + stack_size = $crate::_private::DEFAULT_STACK_SIZE, + } + }; + { + main = $main:expr, + stack_size = $stack_size:expr $(,)? + } => { + $crate::_private::declare_main!($main); + $crate::_private::declare_stack!($stack_size); + }; + { + main = $main:expr, + $(stack_size = $stack_size:expr,)? + heap_size = $heap_size:expr $(,)? + } => { + $crate::_private::declare_heap!($heap_size); + $crate::_private::declare_root_task! { + main = $main, + $(stack_size = $stack_size,)? + } + }; } #[doc(hidden)] diff --git a/crates/sel4-runtime-common/src/ctors.rs b/crates/sel4-runtime-common/src/ctors.rs new file mode 100644 index 000000000..7cff9b6bf --- /dev/null +++ b/crates/sel4-runtime-common/src/ctors.rs @@ -0,0 +1,39 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::mem; +use core::ptr; +use core::slice; + +use sel4_panicking_env::abort; + +type Ctor = unsafe extern "C" fn(); + +extern "C" { + static __init_array_start: Ctor; + static __init_array_end: Ctor; +} + +pub unsafe fn run_ctors() { + let start = ptr::addr_of!(__init_array_start); + let end = ptr::addr_of!(__init_array_end); + + // Cast to usize for comparison, otherwise rustc seems to apply an erroneous optimization + // assuming __init_array_start != __init_array_end. + if start as usize != end as usize { + if start.align_offset(mem::size_of::()) != 0 + || end.align_offset(mem::size_of::()) != 0 + { + abort!("'.init_array' section is not properly aligned"); + } + + let len = (end as usize - start as usize) / mem::size_of::(); + let ctors = slice::from_raw_parts(start, len); + for ctor in ctors { + (ctor)(); + } + } +} diff --git a/crates/sel4-runtime-common/src/lib.rs b/crates/sel4-runtime-common/src/lib.rs index 66b055c94..634ddf685 100644 --- a/crates/sel4-runtime-common/src/lib.rs +++ b/crates/sel4-runtime-common/src/lib.rs @@ -7,6 +7,10 @@ #![no_std] #![feature(cfg_target_thread_local)] +mod ctors; + +pub use ctors::run_ctors; + #[cfg(feature = "start")] mod start;