diff --git a/Cargo.lock b/Cargo.lock index 02b05df1a..1001ef9fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1980,6 +1980,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" +[[package]] +name = "rangemap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" + [[package]] name = "rcgen" version = "0.14.5" @@ -2902,6 +2908,8 @@ name = "sel4-reset" version = "0.1.0" dependencies = [ "cfg-if", + "sel4-elf-header", + "sel4-panicking-env", "sel4-stack", ] @@ -2912,9 +2920,22 @@ dependencies = [ "anyhow", "clap", "num", - "sel4-synthetic-elf", + "object", + "rangemap", +] + +[[package]] +name = "sel4-reset-tests" +version = "0.1.0" +dependencies = [ + "sel4-minimal-linux-runtime", + "sel4-reset", ] +[[package]] +name = "sel4-rodata-static" +version = "0.1.0" + [[package]] name = "sel4-root-task" version = "0.1.0" @@ -2964,6 +2985,7 @@ dependencies = [ "sel4", "sel4-ctors-dtors", "sel4-elf-header", + "sel4-immutable-cell", "sel4-initialize-tls", "sel4-panicking-env", "sel4-stack", @@ -3679,6 +3701,16 @@ dependencies = [ "sel4-test-root-task", ] +[[package]] +name = "tests-root-task-reset" +version = "0.1.0" +dependencies = [ + "sel4", + "sel4-reset", + "sel4-root-task", + "sel4-test-root-task", +] + [[package]] name = "tests-root-task-ring-test-harness" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 41144c4df..3fd4df4ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,8 +71,6 @@ members = [ "crates/experimental/sel4-microkit/simple-ipc", "crates/experimental/sel4-musl", "crates/experimental/sel4-newlib", - "crates/experimental/sel4-reset", - "crates/experimental/sel4-reset/cli", "crates/experimental/sel4-shared-ring-buffer", "crates/experimental/sel4-shared-ring-buffer/block-io", "crates/experimental/sel4-shared-ring-buffer/block-io/types", @@ -114,6 +112,7 @@ members = [ "crates/private/tests/root-task/loader", "crates/private/tests/root-task/musl", "crates/private/tests/root-task/panicking", + "crates/private/tests/root-task/reset", "crates/private/tests/root-task/ring-test-harness", "crates/private/tests/root-task/tls", "crates/private/tests/root-task/verus/core", @@ -146,6 +145,10 @@ members = [ "crates/sel4-panicking/env", "crates/sel4-platform-info", "crates/sel4-platform-info/types", + "crates/sel4-reset", + "crates/sel4-reset/cli", + "crates/sel4-reset/tests", + "crates/sel4-rodata-static", "crates/sel4-root-task", "crates/sel4-root-task/macros", "crates/sel4-runtime-common", diff --git a/crates/examples/root-task/spawn-thread/src/main.rs b/crates/examples/root-task/spawn-thread/src/main.rs index 42c9b83fa..d591428f3 100644 --- a/crates/examples/root-task/spawn-thread/src/main.rs +++ b/crates/examples/root-task/spawn-thread/src/main.rs @@ -19,7 +19,7 @@ use core::ptr; use cfg_if::cfg_if; -use sel4_elf_header::{ElfHeader, PT_TLS}; +use sel4_elf_header::{PT_TLS, locate_phdrs}; use sel4_initialize_tls::{TlsImage, UncheckedTlsImage}; use sel4_root_task::{ Never, abort, panicking::catch_unwind, root_task, set_global_allocator_mutex_notification, @@ -215,14 +215,11 @@ impl SecondaryThreadFn { // // // fn get_tls_image() -> TlsImage { - unsafe extern "C" { - static __ehdr_start: ElfHeader; - } - let phdrs = unsafe { - assert!(__ehdr_start.is_magic_valid()); - __ehdr_start.locate_phdrs() - }; - let phdr = phdrs.iter().find(|phdr| phdr.p_type == PT_TLS).unwrap(); + let phdr = locate_phdrs() + .unwrap_or_else(|err| abort!("{err}")) + .iter() + .find(|phdr| phdr.p_type == PT_TLS) + .unwrap_or_else(|| abort!("missing PT_TLS program header")); let unchecked = UncheckedTlsImage { vaddr: phdr.p_vaddr, filesz: phdr.p_filesz, diff --git a/crates/experimental/sel4-reset/cli/src/args.rs b/crates/experimental/sel4-reset/cli/src/args.rs deleted file mode 100644 index d656ec699..000000000 --- a/crates/experimental/sel4-reset/cli/src/args.rs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright 2024, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -use anyhow::Result; -use clap::{Arg, ArgAction, Command}; - -#[derive(Debug)] -pub struct Args { - pub in_file_path: String, - pub out_file_path: String, - pub verbose: bool, -} - -impl Args { - pub fn parse() -> Result { - let matches = Command::new("") - .arg(Arg::new("in_file").value_name("IN")) - .arg( - Arg::new("out_file") - .short('o') - .value_name("OUT") - .required(true), - ) - .arg(Arg::new("verbose").short('v').action(ArgAction::SetTrue)) - .get_matches(); - - let in_file_path = matches.get_one::("in_file").unwrap().to_owned(); - let out_file_path = matches.get_one::("out_file").unwrap().to_owned(); - let verbose = *matches.get_one::("verbose").unwrap(); - - Ok(Self { - in_file_path, - out_file_path, - verbose, - }) - } -} diff --git a/crates/experimental/sel4-reset/cli/src/main.rs b/crates/experimental/sel4-reset/cli/src/main.rs deleted file mode 100644 index 27e76ecf0..000000000 --- a/crates/experimental/sel4-reset/cli/src/main.rs +++ /dev/null @@ -1,196 +0,0 @@ -// -// Copyright 2024, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -use std::borrow::Cow; -use std::fs; - -use anyhow::Result; -use num::NumCast; -use object::elf::{PF_W, PT_LOAD}; -use object::read::elf::{ElfFile, FileHeader, ProgramHeader}; -use object::{Endian, File, Object, ObjectSection, ReadCache, ReadRef}; - -use sel4_synthetic_elf::{Builder, PatchValue, Segment, object}; - -mod args; - -use args::Args; - -fn main() -> Result<()> { - let args = Args::parse()?; - - if args.verbose { - eprintln!("{args:#?}"); - } - - let in_file = fs::File::open(&args.in_file_path)?; - let in_file_cached = ReadCache::new(in_file); - let in_obj_file = File::parse(&in_file_cached)?; - - match in_obj_file { - File::Elf32(elf) => continue_with_type(&args, &elf), - File::Elf64(elf) => continue_with_type(&args, &elf), - _ => { - panic!() - } - } -} - -fn continue_with_type<'a, T, R>(args: &Args, elf: &'a ElfFile<'a, T, R>) -> Result<()> -where - R: ReadRef<'a>, - T: FileHeader, -{ - let endian = elf.endian(); - - let persistent_section = elf.section_by_name(".persistent"); - - let mut builder = Builder::empty(elf); - - let mut regions_builder = RegionsBuilder::::new(); - - let mut persistent_section_placed = false; - - for phdr in elf.elf_program_headers() { - if phdr.p_type(endian) == PT_LOAD { - let mut segment = Segment::from_phdr(phdr, endian, elf.data())?; - if phdr.p_flags(endian) & PF_W != 0 { - let vaddr = phdr.p_vaddr(endian).into(); - let memsz = phdr.p_memsz(endian).into(); - let data = phdr.data(endian, elf.data()).unwrap(); - let skip = persistent_section - .as_ref() - .and_then(|section| { - if section.address() == vaddr { - persistent_section_placed = true; - Some(section.size()) - } else { - None - } - }) - .unwrap_or(0); - regions_builder.add_region_with_skip(skip, vaddr, memsz, data); - segment.data = match &segment.data { - Cow::Borrowed(slice) => slice[..usize::try_from(skip).unwrap()].into(), - _ => panic!(), - } - } - builder.add_segment(segment); - } - } - - assert!(persistent_section.is_none() || persistent_section_placed); - - let regions = regions_builder.build(endian); - - let vaddr = builder.next_vaddr().next_multiple_of(4096); - - builder.add_segment(Segment::simple(vaddr, regions.raw.into())); - - builder - .patch_word_with_cast("sel4_reset_regions_start", vaddr) - .unwrap(); - builder - .patch_word_with_cast("sel4_reset_regions_meta_offset", regions.meta_offset) - .unwrap(); - builder - .patch_word_with_cast("sel4_reset_regions_meta_count", regions.meta_count) - .unwrap(); - builder - .patch_word_with_cast("sel4_reset_regions_data_offset", regions.data_offset) - .unwrap(); - builder - .patch_word_with_cast("sel4_reset_regions_data_size", regions.data_size) - .unwrap(); - - builder.discard_p_align(true); - - let out_bytes = builder.build().unwrap(); - - let out_file_path = &args.out_file_path; - - fs::write(out_file_path, out_bytes)?; - Ok(()) -} - -struct RegionsBuilder { - meta: Vec>, - data: Vec, -} - -impl> RegionsBuilder { - fn new() -> Self { - Self { - meta: vec![], - data: vec![], - } - } - - fn add_region(&mut self, vaddr: u64, memsz: u64, data: &[u8]) { - let offset = self.data.len(); - let filesz = data.len(); - self.data.extend_from_slice(data); - self.meta.push(RegionMeta { - vaddr: NumCast::from(vaddr).unwrap(), - offset: NumCast::from(offset).unwrap(), - filesz: NumCast::from(filesz).unwrap(), - memsz: NumCast::from(memsz).unwrap(), - }) - } - - fn add_region_with_skip(&mut self, skip: u64, vaddr: u64, memsz: u64, data: &[u8]) { - if skip < memsz { - self.add_region( - vaddr + skip, - memsz - skip, - &data[data.len().min(skip.try_into().unwrap())..], - ); - } - } - - fn build(&self, endian: impl Endian) -> Regions { - let mut raw = vec![]; - let meta_offset = raw.len(); - let meta_count = self.meta.len(); - for meta in self.meta.iter() { - meta.pack(endian, &mut raw); - } - let data_offset = raw.len(); - let data_size = self.data.len(); - raw.extend_from_slice(&self.data); - Regions { - raw, - meta_offset, - meta_count, - data_offset, - data_size, - } - } -} - -struct RegionMeta { - vaddr: T::Word, - offset: T::Word, - filesz: T::Word, - memsz: T::Word, -} - -impl> RegionMeta { - fn pack(&self, endian: impl Endian, buf: &mut Vec) { - buf.extend_from_slice(&self.vaddr.to_bytes(endian)); - buf.extend_from_slice(&self.offset.to_bytes(endian)); - buf.extend_from_slice(&self.filesz.to_bytes(endian)); - buf.extend_from_slice(&self.memsz.to_bytes(endian)); - } -} - -struct Regions { - raw: Vec, - meta_offset: usize, - meta_count: usize, - data_offset: usize, - data_size: usize, -} diff --git a/crates/experimental/sel4-reset/src/lib.rs b/crates/experimental/sel4-reset/src/lib.rs deleted file mode 100644 index fdfcba457..000000000 --- a/crates/experimental/sel4-reset/src/lib.rs +++ /dev/null @@ -1,159 +0,0 @@ -// -// Copyright 2024, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use core::arch::global_asm; -use core::ptr; -use core::slice; - -use sel4_stack::{Stack, StackBottom}; - -#[cfg(not(any(target_arch = "aarch64",)))] -compile_error!("unsupported architecture"); - -// // // - -#[repr(C)] -#[derive(Debug)] -struct RegionMeta { - vaddr: usize, - offset: usize, - filesz: usize, - memsz: usize, -} - -struct Regions<'a> { - meta: &'a [RegionMeta], - data: &'a [u8], -} - -impl Regions<'_> { - unsafe fn reset_memory(&self) { - for meta in self.meta { - let dst = unsafe { slice::from_raw_parts_mut(meta.vaddr as *mut _, meta.memsz) }; - let (dst_data, dst_zero) = dst.split_at_mut(meta.filesz); - let src_data = &self.data[meta.offset..][..meta.filesz]; - dst_data.copy_from_slice(src_data); - unsafe { - ptr::write_bytes(dst_zero.as_mut_ptr(), 0, dst_zero.len()); - } - } - } -} - -// // // - -const STACK_SIZE: usize = 4096; - -#[unsafe(link_section = ".persistent")] -static STACK: Stack = Stack::new(); - -#[unsafe(no_mangle)] -static __sel4_reset__stack_bottom: StackBottom = STACK.bottom(); - -// // // - -#[unsafe(no_mangle)] -unsafe extern "C" fn __sel4_reset__reset_memory() { - unsafe { - get_regions().reset_memory(); - } -} - -unsafe fn get_regions() -> Regions<'static> { - unsafe { - Regions { - meta: slice::from_raw_parts( - (sel4_reset_regions_start + sel4_reset_regions_meta_offset) as *const _, - sel4_reset_regions_meta_count, - ), - data: slice::from_raw_parts( - (sel4_reset_regions_start + sel4_reset_regions_data_offset) as *const _, - sel4_reset_regions_data_size, - ), - } - } -} - -// HACK to force variables into .rodata without causing .rodata to end up in a PF_W segment -macro_rules! rodata { - ($ident:ident) => { - unsafe extern "C" { - static $ident: usize; - } - global_asm! { - r#" - .section .rodata - "#, - #[cfg(target_pointer_width = "64")] - r#" - .align 8 - "#, - #[cfg(target_pointer_width = "32")] - r#" - .align 4 - "#, - r#" - .global {ident} - {ident}: - "#, - #[cfg(target_pointer_width = "64")] - r#" - .quad 0 - "#, - #[cfg(target_pointer_width = "32")] - r#" - .word 0 - "#, - r#" - .size {ident}, .-{ident} - "#, - ident = sym $ident, - } - }; -} - -rodata!(sel4_reset_regions_start); -rodata!(sel4_reset_regions_meta_offset); -rodata!(sel4_reset_regions_meta_count); -rodata!(sel4_reset_regions_data_offset); -rodata!(sel4_reset_regions_data_size); - -// // // - -pub fn reset() -> ! { - unsafe { - _reset(); - } - unreachable!() -} - -unsafe extern "C" { - fn _reset(); -} - -global_asm! { - r#" - .extern _start - - .global _reset - - .section .text - - _reset: - "#, - #[cfg(target_arch = "aarch64")] - r#" - ldr x9, =__sel4_reset__stack_bottom - ldr x9, [x9] - mov sp, x9 - bl __sel4_reset__reset_memory - b _start - - 1: b 1b - "#, -} diff --git a/crates/private/meta/Cargo.toml b/crates/private/meta/Cargo.toml index 694f0c610..7cfcfc65a 100644 --- a/crates/private/meta/Cargo.toml +++ b/crates/private/meta/Cargo.toml @@ -79,4 +79,4 @@ sel4-platform-info = { path = "../../sel4-platform-info", optional = true } sel4 = { path = "../../sel4", features = ["single-threaded"] } [target."cfg(target_arch = \"aarch64\")".dependencies] -sel4-reset = { path = "../../experimental/sel4-reset" } +sel4-reset = { path = "../../sel4-reset" } diff --git a/crates/private/support/sel4-minimal-linux-runtime/src/lib.rs b/crates/private/support/sel4-minimal-linux-runtime/src/lib.rs index 29184f0ef..6d2bf7c96 100644 --- a/crates/private/support/sel4-minimal-linux-runtime/src/lib.rs +++ b/crates/private/support/sel4-minimal-linux-runtime/src/lib.rs @@ -8,7 +8,7 @@ use core::panic::UnwindSafe; -pub use sel4_minimal_linux_syscalls::exit_success; +pub use sel4_minimal_linux_syscalls::{exit_failure, exit_success}; pub use sel4_panicking::catch_unwind; pub use sel4_panicking_env::{abort, debug_println}; @@ -90,7 +90,7 @@ pub fn _run_main(f: F) -> ! where F: FnOnce() + UnwindSafe, { - let r = catch_unwind(move || f()); + let r = catch_unwind(f); match r { Ok(()) => exit_success(), Err(()) => abort!("uncaught panic in main"), diff --git a/crates/private/support/sel4-test-runner/src/main.rs b/crates/private/support/sel4-test-runner/src/main.rs index 1dcfeefeb..f7d733c55 100644 --- a/crates/private/support/sel4-test-runner/src/main.rs +++ b/crates/private/support/sel4-test-runner/src/main.rs @@ -87,10 +87,10 @@ struct Runner<'a> { impl<'a> Runner<'a> { fn run(&self) -> anyhow::Result<()> { + self.mk_resettable()?; match self.get_sel4_test_kind() { None => self.run_not_sel4(), Some(kind) => { - self.mk_resettable()?; let image = match kind { SeL4TestKind::RootTask => self.mk_root_task_image(self.exe)?, SeL4TestKind::Microkit => self.mk_microkit_image()?, @@ -177,15 +177,19 @@ impl<'a> Runner<'a> { } fn run_not_sel4(&self) -> anyhow::Result<()> { - ensure!( - Command::new(self.get_qemu_exe()) - .args( - iter::once(self.exe.as_os_str()) - .chain(self.cli.simulate_args.iter().map(AsRef::as_ref)), - ) - .status()? - .success() - ); + if self.cli.no_run { + println!("{}", self.d.display()); + } else { + ensure!( + Command::new(self.get_qemu_exe()) + .args( + iter::once(self.exe.as_os_str()) + .chain(self.cli.simulate_args.iter().map(AsRef::as_ref)), + ) + .status()? + .success() + ); + } Ok(()) } @@ -203,11 +207,7 @@ impl<'a> Runner<'a> { } fn is_resettable(&self) -> bool { - if let Some(sym) = self.file.symbol_by_name("_reset") { - self.file.entry() == sym.address() - } else { - false - } + self.file.symbol_by_name("_reset").is_some() } fn mk_resettable(&self) -> anyhow::Result<()> { @@ -226,15 +226,6 @@ impl<'a> Runner<'a> { .status()? .success() ); - let sup = self.exe.with_extension("sup.elf"); - ensure!( - Command::new("llvm-objcopy") - .arg("--only-keep-debug") - .arg(&orig) - .arg(&sup) - .status()? - .success() - ); } Ok(()) } diff --git a/crates/private/tests/microkit/reset/Cargo.toml b/crates/private/tests/microkit/reset/Cargo.toml index 4b8e1bea5..c07ec9f20 100644 --- a/crates/private/tests/microkit/reset/Cargo.toml +++ b/crates/private/tests/microkit/reset/Cargo.toml @@ -18,5 +18,5 @@ license = "BSD-2-Clause" [dependencies] sel4-microkit = { path = "../../../../sel4-microkit" } -sel4-reset = { path = "../../../../experimental/sel4-reset" } +sel4-reset = { path = "../../../../sel4-reset" } sel4-test-microkit = { path = "../../../support/sel4-test-microkit" } diff --git a/crates/private/tests/microkit/reset/src/bin/system.xml b/crates/private/tests/microkit/reset/src/bin/system.xml index 82cbb7b00..bf9aa9899 100644 --- a/crates/private/tests/microkit/reset/src/bin/system.xml +++ b/crates/private/tests/microkit/reset/src/bin/system.xml @@ -6,6 +6,6 @@ --> - + diff --git a/crates/private/tests/root-task/reset/Cargo.nix b/crates/private/tests/root-task/reset/Cargo.nix new file mode 100644 index 000000000..41926b46f --- /dev/null +++ b/crates/private/tests/root-task/reset/Cargo.nix @@ -0,0 +1,19 @@ +# +# Copyright 2026, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, localCrates, versions }: + +mk { + package.name = "tests-root-task-reset"; + dependencies = { + inherit (localCrates) + sel4 + sel4-root-task + sel4-reset + sel4-test-root-task + ; + }; +} diff --git a/crates/private/tests/root-task/reset/Cargo.toml b/crates/private/tests/root-task/reset/Cargo.toml new file mode 100644 index 000000000..494b77476 --- /dev/null +++ b/crates/private/tests/root-task/reset/Cargo.toml @@ -0,0 +1,23 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "tests-root-task-reset" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2024" +license = "BSD-2-Clause" + +[dependencies] +sel4 = { path = "../../../../sel4" } +sel4-reset = { path = "../../../../sel4-reset" } +sel4-root-task = { path = "../../../../sel4-root-task" } +sel4-test-root-task = { path = "../../../support/sel4-test-root-task" } diff --git a/crates/private/tests/root-task/reset/src/main.rs b/crates/private/tests/root-task/reset/src/main.rs new file mode 100644 index 000000000..ef12423c5 --- /dev/null +++ b/crates/private/tests/root-task/reset/src/main.rs @@ -0,0 +1,42 @@ +// +// Copyright 2023, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] +#![no_main] +#![allow(static_mut_refs)] + +use sel4_reset::reset1; +use sel4_root_task::{debug_println, root_task}; + +const INIT: usize = 1337; + +static mut NOT_PERSISTENT: usize = INIT; + +#[unsafe(link_section = ".persistent")] +static mut PERSISTENT: usize = INIT; + +#[unsafe(link_section = ".persistent")] +static mut RESET_COUNT: usize = 0; + +#[root_task] +fn main(bootinfo: &sel4::BootInfoPtr) -> ! { + unsafe { + debug_println!("NOT_PERSISTENT: {NOT_PERSISTENT}"); + debug_println!("PERSISTENT: {PERSISTENT}"); + debug_println!("RESET_COUNT: {RESET_COUNT}"); + + if RESET_COUNT == 3 { + assert_eq!(NOT_PERSISTENT, INIT); + assert_eq!(PERSISTENT, INIT + RESET_COUNT); + sel4_test_root_task::indicate_success() + } + + NOT_PERSISTENT += 1; + PERSISTENT += 1; + RESET_COUNT += 1; + } + reset1(bootinfo.ptr() as usize) +} diff --git a/crates/sel4-elf-header/src/lib.rs b/crates/sel4-elf-header/src/lib.rs index c1e466511..14a1a0848 100644 --- a/crates/sel4-elf-header/src/lib.rs +++ b/crates/sel4-elf-header/src/lib.rs @@ -6,6 +6,8 @@ #![no_std] +use core::error::Error; +use core::fmt; use core::ops::Range; use core::ptr; use core::slice; @@ -48,6 +50,16 @@ impl ElfHeader { self.e_ident.magic == ELFMAG } + pub fn check_magic(&self) -> Result<(), InvalidMagic> { + if self.is_magic_valid() { + Ok(()) + } else { + Err(InvalidMagic { + ehdr_addr: self as *const _ as usize, + }) + } + } + pub fn locate_phdrs(&'static self) -> &'static [ProgramHeader] { unsafe { let ptr = ptr::from_ref(self) @@ -59,6 +71,29 @@ impl ElfHeader { } } +pub fn locate_phdrs() -> Result<&'static [ProgramHeader], InvalidMagic> { + unsafe extern "C" { + static __ehdr_start: ElfHeader; + } + unsafe { + __ehdr_start.check_magic()?; + } + Ok(unsafe { __ehdr_start.locate_phdrs() }) +} + +#[derive(Debug, Copy, Clone)] +pub struct InvalidMagic { + ehdr_addr: usize, +} + +impl fmt::Display for InvalidMagic { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "invalid magic for ELF header at 0x{:x}", self.ehdr_addr) + } +} + +impl Error for InvalidMagic {} + #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct ProgramHeader { @@ -80,6 +115,9 @@ pub const PT_LOAD: u32 = 1; pub const PT_TLS: u32 = 7; pub const PT_GNU_EH_FRAME: u32 = 0x6474_e550; +// seL4-specific +pub const PT_SEL4_RESET_REGIONS: u32 = 0x64c3_4001; + impl ProgramHeader { pub fn vaddr_range(&self) -> Range { let start = self.p_vaddr; @@ -87,3 +125,25 @@ impl ProgramHeader { start..end } } + +#[macro_export] +macro_rules! add_placeholder_phdrs { + ($label:ident) => { + const _: () = { + #[unsafe(link_section = $crate::_private::concat!(".note.sel4.placeholder.", $crate::_private::stringify!($label), ".1"))] + static _1: [u32; 0] = []; + + #[unsafe(link_section = $crate::_private::concat!(".note.sel4.placeholder.", $crate::_private::stringify!($label), ".2"))] + static _2: [u64; 0] = []; + + #[unsafe(link_section = $crate::_private::concat!(".note.sel4.placeholder.", $crate::_private::stringify!($label), ".3"))] + static _3: [u32; 0] = []; + + }; + }; +} + +#[doc(hidden)] +pub mod _private { + pub use core::{concat, stringify}; +} diff --git a/crates/sel4-generate-target-specs/src/main.rs b/crates/sel4-generate-target-specs/src/main.rs index 681492a84..a1c0cc369 100644 --- a/crates/sel4-generate-target-specs/src/main.rs +++ b/crates/sel4-generate-target-specs/src/main.rs @@ -36,7 +36,6 @@ const CHOSEN_LINKER_FLAVOR: LinkerFlavor = LinkerFlavor::Gnu(Cc::No, Lld::Yes); struct Config { arch: Arch, context: Context, - resettable: bool, minimal: bool, unwind: bool, musl: bool, @@ -117,15 +116,6 @@ impl Config { assert_eq!(target.options.linker_flavor, CHOSEN_LINKER_FLAVOR); - if self.resettable { - target - .options - .link_script - .get_or_insert_default() - .to_mut() - .push_str(include_str!("resettable.lds")); - } - if let Context::RootTask = &self.context { target .options @@ -180,9 +170,6 @@ impl Config { } fn filter(&self) -> bool { - if self.resettable && self.context != Context::Microkit { - return false; - } if self.unwind && !self.arch.unwinding_support() { return false; } @@ -210,9 +197,6 @@ impl Config { name.push_str("-microkit"); } } - if self.resettable { - name.push_str("-resettable"); - } if self.minimal { name.push_str("-minimal"); } @@ -229,21 +213,18 @@ impl Config { let mut all = vec![]; for arch in Arch::all() { for context in Context::all() { - for resettable in [true, false] { - for minimal in [true, false] { - for unwind in [true, false] { - for musl in [true, false] { - let config = Self { - arch, - context, - resettable, - minimal, - unwind, - musl, - }; - if config.filter() { - all.push(config); - } + for minimal in [true, false] { + for unwind in [true, false] { + for musl in [true, false] { + let config = Self { + arch, + context, + minimal, + unwind, + musl, + }; + if config.filter() { + all.push(config); } } } diff --git a/crates/sel4-generate-target-specs/src/resettable.lds b/crates/sel4-generate-target-specs/src/resettable.lds deleted file mode 100644 index b63b31e0f..000000000 --- a/crates/sel4-generate-target-specs/src/resettable.lds +++ /dev/null @@ -1,9 +0,0 @@ -SECTIONS { - .persistent : { - *(.persistent .persistent.*) - } -} INSERT BEFORE .data; - -ASSERT(DEFINED(_reset), "_reset is not defined") - -ENTRY(_reset) diff --git a/crates/experimental/sel4-reset/Cargo.nix b/crates/sel4-reset/Cargo.nix similarity index 74% rename from crates/experimental/sel4-reset/Cargo.nix rename to crates/sel4-reset/Cargo.nix index 6c91b430f..ae2d43229 100644 --- a/crates/experimental/sel4-reset/Cargo.nix +++ b/crates/sel4-reset/Cargo.nix @@ -10,6 +10,6 @@ mk { package.name = "sel4-reset"; dependencies = { inherit (versions) cfg-if; - inherit (localCrates) sel4-stack; + inherit (localCrates) sel4-stack sel4-panicking-env sel4-elf-header; }; } diff --git a/crates/sel4-reset/Cargo.toml b/crates/sel4-reset/Cargo.toml new file mode 100644 index 000000000..595ad9d9e --- /dev/null +++ b/crates/sel4-reset/Cargo.toml @@ -0,0 +1,23 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-reset" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2024" +license = "BSD-2-Clause" + +[dependencies] +cfg-if = "1.0.4" +sel4-elf-header = { path = "../sel4-elf-header" } +sel4-panicking-env = { path = "../sel4-panicking/env" } +sel4-stack = { path = "../sel4-stack" } diff --git a/crates/experimental/sel4-reset/cli/Cargo.nix b/crates/sel4-reset/cli/Cargo.nix similarity index 71% rename from crates/experimental/sel4-reset/cli/Cargo.nix rename to crates/sel4-reset/cli/Cargo.nix index 3615c914a..9d3cf9778 100644 --- a/crates/experimental/sel4-reset/cli/Cargo.nix +++ b/crates/sel4-reset/cli/Cargo.nix @@ -12,10 +12,9 @@ mk { inherit (versions) anyhow num - clap - ; - inherit (localCrates) - sel4-synthetic-elf + rangemap + object ; + clap = { version = versions.clap; features = [ "derive" ]; }; }; } diff --git a/crates/experimental/sel4-reset/cli/Cargo.toml b/crates/sel4-reset/cli/Cargo.toml similarity index 85% rename from crates/experimental/sel4-reset/cli/Cargo.toml rename to crates/sel4-reset/cli/Cargo.toml index dca544580..cb00483e6 100644 --- a/crates/experimental/sel4-reset/cli/Cargo.toml +++ b/crates/sel4-reset/cli/Cargo.toml @@ -18,6 +18,7 @@ license = "BSD-2-Clause" [dependencies] anyhow = "1.0.100" -clap = "4.5.50" +clap = { version = "4.5.50", features = ["derive"] } num = "0.4.3" -sel4-synthetic-elf = { path = "../../../sel4-synthetic-elf" } +object = "0.38.1" +rangemap = "1.7.1" diff --git a/crates/sel4-reset/cli/src/main.rs b/crates/sel4-reset/cli/src/main.rs new file mode 100644 index 000000000..1dec1d32a --- /dev/null +++ b/crates/sel4-reset/cli/src/main.rs @@ -0,0 +1,168 @@ +// +// Copyright 2026, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use std::fs; +use std::path::PathBuf; + +use anyhow::Error; +use clap::Parser; +use num::NumCast; +use object::elf::{PF_R, PF_W, PT_LOAD}; +use object::read::elf::{ElfFile, FileHeader, ProgramHeader}; +use object::{File, Object, ObjectSection, Pod, pod}; +use rangemap::RangeSet; + +mod patch; + +use patch::{GenericProgramHeader, Patching, ProgramHeaderExt}; + +pub const PT_SEL4_RESET_REGIONS: u32 = 0x64c3_4001; + +// HACK +const PAGE_SIZE: u64 = 4096; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Cli { + in_file_path: PathBuf, + #[arg(short = 'o')] + out_file_path: PathBuf, +} + +fn main() -> Result<(), Error> { + let cli = Cli::parse(); + + let in_perms = fs::metadata(&cli.in_file_path)?.permissions(); + let in_bytes = fs::read(&cli.in_file_path)?; + let in_file = File::parse(in_bytes.as_slice())?; + + let out_bytes = match in_file { + File::Elf32(elf) => continue_with_type(&elf), + File::Elf64(elf) => continue_with_type(&elf), + _ => { + panic!() + } + }?; + + fs::write(&cli.out_file_path, &out_bytes)?; + fs::set_permissions(&cli.out_file_path, in_perms)?; + + Ok(()) +} + +fn continue_with_type<'a, T>(orig_elf: &'a ElfFile<'a, T>) -> Result, Error> +where + T: FileHeader, +{ + let mut patching = Patching::new(orig_elf); + add_regions(&mut patching)?; + Ok(patching.finalize()) +} + +struct RegionMeta { + dst_vaddr: T::Word, + dst_size: T::Word, + src_vaddr: T::Word, + src_size: T::Word, +} + +impl> RegionMeta { + fn pack(&self, buf: &mut Vec) { + buf.extend_from_slice(pod::bytes_of(&self.dst_vaddr)); + buf.extend_from_slice(pod::bytes_of(&self.dst_size)); + buf.extend_from_slice(pod::bytes_of(&self.src_vaddr)); + buf.extend_from_slice(pod::bytes_of(&self.src_size)); + } + + fn pack_to_vec(regions: &[RegionMeta]) -> Vec { + let mut buf = vec![]; + for meta in regions.iter() { + meta.pack(&mut buf); + } + buf + } +} + +fn get_all_persistent_ranges<'a, T>(elf: &'a ElfFile<'a, T>) -> RangeSet +where + T: FileHeader, +{ + let mut set = RangeSet::new(); + for s in elf.sections() { + if let Ok(name) = s.name() + && (name == ".persistent" || name.starts_with(".persistent.")) + { + set.insert(s.address()..(s.address() + s.size())); + } + } + set +} + +fn add_regions<'a, T: FileHeader>( + this: &mut Patching<'a, T>, +) -> Result<(), Error> { + let endian = this.endian(); + + let mut regions: Vec> = vec![]; + for seg in this.orig_elf().segments() { + let phdr = seg.elf_program_header(); + if phdr.p_type(endian) == PT_LOAD && phdr.p_flags(endian) & PF_W != 0 { + let p_offset = phdr.p_offset(endian).into(); + let p_vaddr = phdr.p_vaddr(endian).into(); + let p_memsz = phdr.p_memsz(endian).into(); + let p_filesz = phdr.p_filesz(endian).into(); + let p_align = phdr.p_align(endian).into(); + let ro_phdr = this.add_segment_raw(GenericProgramHeader { + p_type: PT_LOAD, + p_flags: PF_R, + p_offset, + p_vaddr: 0, + p_paddr: 0, + p_filesz, + p_memsz: p_filesz, + p_align, + })?; + let ro_p_vaddr = ro_phdr.p_vaddr(endian).into(); + let ro_p_filesz = ro_phdr.p_filesz(endian).into(); + for ephermal_region in + get_all_persistent_ranges(this.orig_elf()).gaps(&(p_vaddr..(p_vaddr + p_memsz))) + { + let ephermal_region_size = ephermal_region.end - ephermal_region.start; + let ephermal_region_offset_in_segment = ephermal_region.start - p_vaddr; + let (src_vaddr, src_size) = if ephermal_region_offset_in_segment < ro_p_filesz { + ( + ro_p_vaddr + ephermal_region_offset_in_segment, + (ro_p_filesz - ephermal_region_offset_in_segment).min(ephermal_region_size), + ) + } else { + (0, 0) + }; + regions.push(RegionMeta { + dst_vaddr: ::from(ephermal_region.start).unwrap(), + dst_size: ::from(ephermal_region_size).unwrap(), + src_vaddr: ::from(src_vaddr).unwrap(), + src_size: ::from(src_size).unwrap(), + }); + } + } + } + + let regions_meta_data = RegionMeta::pack_to_vec(®ions); + let mut regions_meta_info_phdr = *this.add_segment( + GenericProgramHeader { + p_type: PT_LOAD, + p_flags: PF_R, + p_memsz: regions_meta_data.len().try_into().unwrap(), + p_align: PAGE_SIZE, + ..Default::default() + }, + align_of::>().try_into().unwrap(), + ®ions_meta_data, + )?; + regions_meta_info_phdr.set_p_type(endian, PT_SEL4_RESET_REGIONS); + this.add_phdr(regions_meta_info_phdr)?; + Ok(()) +} diff --git a/crates/sel4-reset/cli/src/patch.rs b/crates/sel4-reset/cli/src/patch.rs new file mode 100644 index 000000000..5c1520bd9 --- /dev/null +++ b/crates/sel4-reset/cli/src/patch.rs @@ -0,0 +1,250 @@ +// +// Copyright 2026, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use std::ops::Range; + +use anyhow::{Error, bail}; +use object::elf::{PT_NOTE, PT_NULL, ProgramHeader32, ProgramHeader64}; +use object::read::elf::{ElfFile, FileHeader, ProgramHeader}; +use object::{Endian, Pod, U32, U64, pod}; + +pub struct Patching<'a, T: FileHeader> { + orig_elf: &'a ElfFile<'a, T>, + data: Vec, +} + +impl<'a, T: FileHeader> Patching<'a, T> { + pub fn new(orig_elf: &'a ElfFile<'a, T>) -> Self { + let mut this = Self { + orig_elf, + data: orig_elf.data().to_vec(), + }; + this.clear_placeholder_phdrs(); + this + } + + pub fn orig_elf(&self) -> &'a ElfFile<'a, T> { + self.orig_elf + } + + pub fn endian(&self) -> T::Endian { + self.orig_elf().endian() + } + + fn phdrs_range(&self) -> Range { + let ehdr = self.orig_elf().elf_header(); + let phoff: usize = ehdr.e_phoff(self.endian()).into().try_into().unwrap(); + let phnum: usize = ehdr.e_phnum(self.endian()).into(); + let phentsize: usize = ehdr.e_phentsize(self.endian()).into(); + phoff..(phoff + phnum * phentsize) + } + + fn phdrs(&self) -> &[T::ProgramHeader] { + let range = self.phdrs_range(); + pod::slice_from_all_bytes(&self.data[range]).unwrap() + } + + fn phdrs_mut(&mut self) -> &mut [T::ProgramHeader] { + let range = self.phdrs_range(); + pod::slice_from_all_bytes_mut(&mut self.data[range]).unwrap() + } + + fn clear_placeholder_phdrs(&mut self) { + let endian = self.endian(); + for phdr_slot in self.phdrs_mut().iter_mut() { + if phdr_slot.p_type(endian) == PT_NOTE && phdr_slot.p_filesz(endian).into() == 0 { + pod::bytes_of_mut(phdr_slot).fill(0); + phdr_slot.set_p_type(endian, PT_NULL); + } + } + } + + pub fn add_phdr(&mut self, phdr: T::ProgramHeader) -> Result<&mut T::ProgramHeader, Error> { + let endian = self.endian(); + for phdr_slot in self.phdrs_mut().iter_mut() { + if phdr_slot.p_type(endian) == PT_NULL { + *phdr_slot = phdr; + return Ok(phdr_slot); + } + } + bail!("no placeholder phdrs") + } + + fn footprint(&self) -> Option> { + let start = self + .phdrs() + .iter() + .map(|phdr| phdr.p_vaddr(self.endian()).into()) + .min()?; + let end = self + .phdrs() + .iter() + .map(|phdr| phdr.p_vaddr(self.endian()).into() + phdr.p_memsz(self.endian()).into()) + .max()?; + Some(start..end) + } + + pub fn next_aligned_vaddr(&self, align: u64) -> u64 { + self.footprint() + .map(|footprint| footprint.end) + .unwrap_or(0) + .next_multiple_of(align.max(1)) + } + + pub fn align_data_cursor(&mut self, align: u64) { + self.data.resize( + self.data.len().next_multiple_of(align.try_into().unwrap()), + 0, + ); + } + + pub fn add_segment( + &mut self, + mut phdr: GenericProgramHeader, + data_align: u64, + data: &[u8], + ) -> Result<&T::ProgramHeader, Error> { + assert!(data_align <= phdr.p_align); + self.align_data_cursor(data_align); + phdr.p_offset = self.data.len().try_into().unwrap(); + phdr.p_filesz = data.len().try_into().unwrap(); + self.data.extend_from_slice(data); + self.add_segment_raw(phdr) + } + + pub fn add_segment_raw( + &mut self, + mut phdr: GenericProgramHeader, + ) -> Result<&T::ProgramHeader, Error> { + let p_vaddr = self.next_aligned_vaddr(phdr.p_align) + phdr.p_offset % phdr.p_align.max(1); + phdr.p_vaddr = p_vaddr; + phdr.p_paddr = p_vaddr; + Ok(&*self.add_phdr(T::ProgramHeader::from_generic(self.endian(), &phdr))?) + } + + pub fn finalize(self) -> Vec { + self.data + } +} + +#[derive(Debug, Copy, Clone, Default)] +pub struct GenericProgramHeader { + pub p_type: u32, + pub p_flags: u32, + pub p_offset: u64, + pub p_vaddr: u64, + pub p_paddr: u64, + pub p_filesz: u64, + pub p_memsz: u64, + pub p_align: u64, +} + +#[allow(dead_code)] +pub trait ProgramHeaderExt: ProgramHeader { + fn from_generic(endian: Self::Endian, generic: &GenericProgramHeader) -> Self; + fn set_p_type(&mut self, endian: Self::Endian, p_type: u32); + fn set_p_flags(&mut self, endian: Self::Endian, p_flags: u32); + fn set_p_offset(&mut self, endian: Self::Endian, p_offset: Self::Word); + fn set_p_vaddr(&mut self, endian: Self::Endian, p_vaddr: Self::Word); + fn set_p_paddr(&mut self, endian: Self::Endian, p_paddr: Self::Word); + fn set_p_filesz(&mut self, endian: Self::Endian, p_filesz: Self::Word); + fn set_p_memsz(&mut self, endian: Self::Endian, p_memsz: Self::Word); + fn set_p_align(&mut self, endian: Self::Endian, p_align: Self::Word); +} + +impl ProgramHeaderExt for ProgramHeader32 { + fn from_generic(endian: Self::Endian, generic: &GenericProgramHeader) -> Self { + ProgramHeader32 { + p_type: U32::new(endian, generic.p_type), + p_offset: U32::new(endian, generic.p_offset.try_into().unwrap()), + p_vaddr: U32::new(endian, generic.p_vaddr.try_into().unwrap()), + p_paddr: U32::new(endian, generic.p_paddr.try_into().unwrap()), + p_filesz: U32::new(endian, generic.p_filesz.try_into().unwrap()), + p_memsz: U32::new(endian, generic.p_memsz.try_into().unwrap()), + p_flags: U32::new(endian, generic.p_flags), + p_align: U32::new(endian, generic.p_align.try_into().unwrap()), + } + } + + fn set_p_type(&mut self, endian: Self::Endian, p_type: u32) { + self.p_type.set(endian, p_type) + } + + fn set_p_flags(&mut self, endian: Self::Endian, p_flags: u32) { + self.p_flags.set(endian, p_flags) + } + + fn set_p_offset(&mut self, endian: Self::Endian, p_offset: Self::Word) { + self.p_offset.set(endian, p_offset) + } + + fn set_p_vaddr(&mut self, endian: Self::Endian, p_vaddr: Self::Word) { + self.p_vaddr.set(endian, p_vaddr) + } + + fn set_p_paddr(&mut self, endian: Self::Endian, p_paddr: Self::Word) { + self.p_vaddr.set(endian, p_paddr) + } + + fn set_p_filesz(&mut self, endian: Self::Endian, p_filesz: Self::Word) { + self.p_offset.set(endian, p_filesz) + } + + fn set_p_memsz(&mut self, endian: Self::Endian, p_memsz: Self::Word) { + self.p_vaddr.set(endian, p_memsz) + } + + fn set_p_align(&mut self, endian: Self::Endian, p_align: Self::Word) { + self.p_vaddr.set(endian, p_align) + } +} + +impl ProgramHeaderExt for ProgramHeader64 { + fn from_generic(endian: Self::Endian, generic: &GenericProgramHeader) -> Self { + ProgramHeader64 { + p_type: U32::new(endian, generic.p_type), + p_flags: U32::new(endian, generic.p_flags), + p_offset: U64::new(endian, generic.p_offset), + p_vaddr: U64::new(endian, generic.p_vaddr), + p_paddr: U64::new(endian, generic.p_paddr), + p_filesz: U64::new(endian, generic.p_filesz), + p_memsz: U64::new(endian, generic.p_memsz), + p_align: U64::new(endian, generic.p_align), + } + } + + fn set_p_type(&mut self, endian: Self::Endian, p_type: u32) { + self.p_type.set(endian, p_type) + } + + fn set_p_flags(&mut self, endian: Self::Endian, p_flags: u32) { + self.p_flags.set(endian, p_flags) + } + + fn set_p_offset(&mut self, endian: Self::Endian, p_offset: Self::Word) { + self.p_offset.set(endian, p_offset) + } + + fn set_p_vaddr(&mut self, endian: Self::Endian, p_vaddr: Self::Word) { + self.p_vaddr.set(endian, p_vaddr) + } + + fn set_p_paddr(&mut self, endian: Self::Endian, p_paddr: Self::Word) { + self.p_vaddr.set(endian, p_paddr) + } + + fn set_p_filesz(&mut self, endian: Self::Endian, p_filesz: Self::Word) { + self.p_offset.set(endian, p_filesz) + } + + fn set_p_memsz(&mut self, endian: Self::Endian, p_memsz: Self::Word) { + self.p_vaddr.set(endian, p_memsz) + } + + fn set_p_align(&mut self, endian: Self::Endian, p_align: Self::Word) { + self.p_vaddr.set(endian, p_align) + } +} diff --git a/crates/sel4-reset/src/lib.rs b/crates/sel4-reset/src/lib.rs new file mode 100644 index 000000000..83ab20d4c --- /dev/null +++ b/crates/sel4-reset/src/lib.rs @@ -0,0 +1,176 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use core::arch::global_asm; +use core::slice; + +use sel4_elf_header::{PT_SEL4_RESET_REGIONS, locate_phdrs}; +use sel4_panicking_env::abort; +use sel4_stack::{Stack, StackBottom}; + +#[cfg(not(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "x86_64", +)))] +compile_error!("unsupported architecture"); + +// 6 should be enough: +// - 1 PT_LOAD for region meta +// - 1 PT_SEL4_RESET_REGIONS for region meta +// - 4 for writeable PT_LOAD +sel4_elf_header::add_placeholder_phdrs!(reset1); +sel4_elf_header::add_placeholder_phdrs!(reset2); +sel4_elf_header::add_placeholder_phdrs!(reset3); +sel4_elf_header::add_placeholder_phdrs!(reset4); +sel4_elf_header::add_placeholder_phdrs!(reset5); +sel4_elf_header::add_placeholder_phdrs!(reset6); + +// // // + +#[repr(C)] +#[derive(Debug)] +struct RegionMeta { + dst_vaddr: usize, + dst_size: usize, + src_vaddr: usize, + src_size: usize, +} + +unsafe fn reset_memory(regions: &'static [RegionMeta]) { + for meta in regions { + let dst = unsafe { slice::from_raw_parts_mut(meta.dst_vaddr as *mut u8, meta.dst_size) }; + let (dst_data, dst_zero) = dst.split_at_mut(meta.src_size); + if meta.src_vaddr != 0 { + let src = + unsafe { slice::from_raw_parts_mut(meta.src_vaddr as *mut u8, meta.src_size) }; + dst_data.copy_from_slice(src); + } + dst_zero.fill(0); + } +} + +unsafe fn get_regions() -> &'static [RegionMeta] { + unsafe { + let phdr = locate_phdrs() + .unwrap_or_else(|err| abort!("{err}")) + .iter() + .find(|phdr| phdr.p_type == PT_SEL4_RESET_REGIONS) + .unwrap_or_else(|| abort!("missing PT_SEL4_RESET_REGIONS program header")); + slice::from_raw_parts( + phdr.p_vaddr as *const _, + phdr.p_memsz / size_of::(), + ) + } +} + +// // // + +unsafe extern "C" { + fn _reset(x0: usize, x1: usize, x2: usize, x3: usize) -> !; + fn _start(x0: usize, x1: usize, x2: usize, x3: usize) -> !; +} + +pub fn reset() -> ! { + unsafe { + _reset(0, 0, 0, 0); + } +} + +pub fn reset1(x0: usize) -> ! { + unsafe { + _reset(x0, 0, 0, 0); + } +} + +pub fn reset2(x0: usize, x1: usize) -> ! { + unsafe { + _reset(x0, x1, 0, 0); + } +} + +pub fn reset3(x0: usize, x1: usize, x2: usize) -> ! { + unsafe { + _reset(x0, x1, x2, 0); + } +} + +pub fn reset4(x0: usize, x1: usize, x2: usize, x3: usize) -> ! { + unsafe { + _reset(x0, x1, x2, x3); + } +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn __sel4_reset__rust_entrypoint( + x0: usize, + x1: usize, + x2: usize, + x3: usize, +) -> ! { + unsafe { + reset_memory(get_regions()); + _start(x0, x1, x2, x3) + } +} + +const STACK_SIZE: usize = 4096; + +#[unsafe(link_section = ".persistent")] +static STACK: Stack = Stack::new(); + +#[unsafe(no_mangle)] +static __sel4_reset__stack_bottom: StackBottom = STACK.bottom(); + +global_asm! { + r#" + .extern __sel4_reset__stack_bottom + .extern __sel4_reset__rust_entrypoint + + .global _reset + + .section .text.reset, "axR", %progbits + _reset: + "#, + #[cfg(target_arch = "aarch64")] + r#" + ldr x9, =__sel4_reset__stack_bottom + ldr x9, [x9] + mov sp, x9 + b __sel4_reset__rust_entrypoint + "#, + #[cfg(target_arch = "arm")] + r#" + ldr r8, =__sel4_reset__stack_bottom + ldr r8, [r8] + mov sp, r8 + b __sel4_reset__rust_entrypoint + "#, + #[cfg(target_arch = "riscv64")] + r#" + la sp, __sel4_reset__stack_bottom + ld sp, (sp) + j __sel4_reset__rust_entrypoint + "#, + #[cfg(target_arch = "riscv32")] + r#" + la sp, __sel4_reset__stack_bottom + lw sp, (sp) + j __sel4_reset__rust_entrypoint + "#, + #[cfg(target_arch = "x86_64")] + r#" + mov rsp, __sel4_reset__stack_bottom + mov rbp, rsp + sub rsp, 0x8 // Stack must be 16-byte aligned before call + push rbp + jmp __sel4_reset__rust_entrypoint + "#, +} diff --git a/crates/sel4-reset/tests/Cargo.nix b/crates/sel4-reset/tests/Cargo.nix new file mode 100644 index 000000000..28120c294 --- /dev/null +++ b/crates/sel4-reset/tests/Cargo.nix @@ -0,0 +1,24 @@ +# +# Copyright 2026, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, localCrates }: + +mk { + package.name = "sel4-reset-tests"; + lib.test = false; + dependencies = { + inherit (localCrates) + sel4-minimal-linux-runtime + sel4-reset + ; + }; + test = [ + { + name = "test1"; + harness = false; + } + ]; +} diff --git a/crates/sel4-reset/tests/Cargo.toml b/crates/sel4-reset/tests/Cargo.toml new file mode 100644 index 000000000..581b003c1 --- /dev/null +++ b/crates/sel4-reset/tests/Cargo.toml @@ -0,0 +1,28 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-reset-tests" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2024" +license = "BSD-2-Clause" + +[lib] +test = false + +[[test]] +harness = false +name = "test1" + +[dependencies] +sel4-minimal-linux-runtime = { path = "../../private/support/sel4-minimal-linux-runtime" } +sel4-reset = { path = ".." } diff --git a/crates/sel4-reset/tests/src/lib.rs b/crates/sel4-reset/tests/src/lib.rs new file mode 100644 index 000000000..c1bfa5897 --- /dev/null +++ b/crates/sel4-reset/tests/src/lib.rs @@ -0,0 +1,7 @@ +// +// Copyright 2026, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] diff --git a/crates/sel4-reset/tests/tests/test1.rs b/crates/sel4-reset/tests/tests/test1.rs new file mode 100644 index 000000000..71d69d26a --- /dev/null +++ b/crates/sel4-reset/tests/tests/test1.rs @@ -0,0 +1,42 @@ +// +// Copyright 2023, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] +#![no_main] +#![allow(static_mut_refs)] + +use sel4_minimal_linux_runtime::*; +use sel4_reset::reset; + +const INIT: usize = 1337; + +static mut NOT_PERSISTENT: usize = INIT; + +#[unsafe(link_section = ".persistent")] +static mut PERSISTENT: usize = INIT; + +#[unsafe(link_section = ".persistent")] +static mut RESET_COUNT: usize = 0; + +#[main] +fn main() { + unsafe { + debug_println!("NOT_PERSISTENT: {NOT_PERSISTENT}"); + debug_println!("PERSISTENT: {PERSISTENT}"); + debug_println!("RESET_COUNT: {RESET_COUNT}"); + + if RESET_COUNT == 3 { + assert_eq!(NOT_PERSISTENT, INIT); + assert_eq!(PERSISTENT, INIT + RESET_COUNT); + exit_success() + } + + NOT_PERSISTENT += 1; + PERSISTENT += 1; + RESET_COUNT += 1; + } + reset() +} diff --git a/crates/sel4-rodata-static/Cargo.nix b/crates/sel4-rodata-static/Cargo.nix new file mode 100644 index 000000000..07852c03a --- /dev/null +++ b/crates/sel4-rodata-static/Cargo.nix @@ -0,0 +1,11 @@ +# +# Copyright 2026, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk }: + +mk { + package.name = "sel4-rodata-static"; +} diff --git a/crates/experimental/sel4-reset/Cargo.toml b/crates/sel4-rodata-static/Cargo.toml similarity index 81% rename from crates/experimental/sel4-reset/Cargo.toml rename to crates/sel4-rodata-static/Cargo.toml index c5ef43938..7b358de23 100644 --- a/crates/experimental/sel4-reset/Cargo.toml +++ b/crates/sel4-rodata-static/Cargo.toml @@ -10,12 +10,8 @@ # [package] -name = "sel4-reset" +name = "sel4-rodata-static" version = "0.1.0" authors = ["Nick Spinale "] edition = "2024" license = "BSD-2-Clause" - -[dependencies] -cfg-if = "1.0.4" -sel4-stack = { path = "../../sel4-stack" } diff --git a/crates/sel4-rodata-static/src/lib.rs b/crates/sel4-rodata-static/src/lib.rs new file mode 100644 index 000000000..38931bf64 --- /dev/null +++ b/crates/sel4-rodata-static/src/lib.rs @@ -0,0 +1,40 @@ +// +// Copyright 2026, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +/// Forces a static into `.rodata` without causing `.rodata` to end up in a `PF_W` segment +#[macro_export] +macro_rules! rodata_static { + ($ident:ident: $ty:ty) => {{ + mod asm { + use super::*; + unsafe extern "C" { + pub(super) static $ident: $ty; + } + $crate::_private::global_asm! { + r#" + .section .rodata.rodata_static.{ident}, "aR", %progbits + .global {ident} + .size {ident}, {size} + .p2align {align} + {ident}: + .skip {size}, 0 + "#, + ident = sym $ident, + size = const $crate::_private::size_of::<$ty>(), + align = const $crate::_private::align_of::<$ty>(), + } + } + unsafe { &asm::$ident } + }}; +} + +#[doc(hidden)] +pub mod _private { + pub use core::arch::global_asm; + pub use core::mem::{align_of, size_of}; +} diff --git a/crates/sel4-runtime-common/Cargo.nix b/crates/sel4-runtime-common/Cargo.nix index 66083bce3..6873bd519 100644 --- a/crates/sel4-runtime-common/Cargo.nix +++ b/crates/sel4-runtime-common/Cargo.nix @@ -13,6 +13,7 @@ mk { inherit (localCrates) sel4-panicking-env sel4-elf-header + sel4-immutable-cell sel4-stack sel4-ctors-dtors ; diff --git a/crates/sel4-runtime-common/Cargo.toml b/crates/sel4-runtime-common/Cargo.toml index a1ed6368a..0fcf2e44f 100644 --- a/crates/sel4-runtime-common/Cargo.toml +++ b/crates/sel4-runtime-common/Cargo.toml @@ -20,6 +20,7 @@ license = "BSD-2-Clause" cfg-if = "1.0.4" sel4-ctors-dtors = { path = "../sel4-ctors-dtors" } sel4-elf-header = { path = "../sel4-elf-header" } +sel4-immutable-cell = { path = "../sel4-immutable-cell" } sel4-panicking-env = { path = "../sel4-panicking/env" } sel4-stack = { path = "../sel4-stack" } diff --git a/crates/sel4-runtime-common/src/lib.rs b/crates/sel4-runtime-common/src/lib.rs index ad312b92d..141fd2cad 100644 --- a/crates/sel4-runtime-common/src/lib.rs +++ b/crates/sel4-runtime-common/src/lib.rs @@ -13,7 +13,6 @@ use core::sync::atomic::{AtomicBool, Ordering}; -use sel4_elf_header::{ElfHeader, ProgramHeader}; use sel4_panicking_env::abort; mod abort; @@ -64,19 +63,6 @@ pub fn global_init_complete() -> bool { GLOBAL_INIT_COMPLETE.load(Ordering::Acquire) } -#[allow(dead_code)] -fn locate_phdrs() -> &'static [ProgramHeader] { - unsafe extern "C" { - static __ehdr_start: ElfHeader; - } - unsafe { - if !__ehdr_start.is_magic_valid() { - abort!("ELF header magic mismatch") - } - __ehdr_start.locate_phdrs() - } -} - #[cfg(target_arch = "arm")] #[linkage = "weak"] #[unsafe(no_mangle)] diff --git a/crates/sel4-runtime-common/src/start.rs b/crates/sel4-runtime-common/src/start.rs index 9b42855a9..bdafdbb33 100644 --- a/crates/sel4-runtime-common/src/start.rs +++ b/crates/sel4-runtime-common/src/start.rs @@ -122,26 +122,26 @@ global_asm! { ldr x9, =__sel4_runtime_common__stack_bottom ldr x9, [x9] mov sp, x9 - b __sel4_runtime_common__rust_entrypoint + b __sel4_runtime_common__call_rust_entrypoint "#, #[cfg(target_arch = "arm")] r#" ldr r8, =__sel4_runtime_common__stack_bottom ldr r8, [r8] mov sp, r8 - b __sel4_runtime_common__rust_entrypoint + b __sel4_runtime_common__call_rust_entrypoint "#, #[cfg(target_arch = "riscv64")] r#" la sp, __sel4_runtime_common__stack_bottom ld sp, (sp) - j __sel4_runtime_common__rust_entrypoint + j __sel4_runtime_common__call_rust_entrypoint "#, #[cfg(target_arch = "riscv32")] r#" la sp, __sel4_runtime_common__stack_bottom lw sp, (sp) - j __sel4_runtime_common__rust_entrypoint + j __sel4_runtime_common__call_rust_entrypoint "#, #[cfg(target_arch = "x86_64")] r#" @@ -149,7 +149,7 @@ global_asm! { mov rbp, rsp sub rsp, 0x8 // Stack must be 16-byte aligned before call push rbp - call __sel4_runtime_common__rust_entrypoint + call __sel4_runtime_common__call_rust_entrypoint 1: jmp 1b "#, } diff --git a/crates/sel4-runtime-common/src/tls.rs b/crates/sel4-runtime-common/src/tls.rs index d0e85b4bb..8133d6552 100644 --- a/crates/sel4-runtime-common/src/tls.rs +++ b/crates/sel4-runtime-common/src/tls.rs @@ -7,16 +7,16 @@ use cfg_if::cfg_if; use sel4_elf_header::PT_TLS; +use sel4_elf_header::locate_phdrs; use sel4_panicking_env::abort; #[allow(unused_imports)] use sel4_initialize_tls::{DEFAULT_SET_THREAD_POINTER_FN, SetThreadPointerFn, UncheckedTlsImage}; -use crate::locate_phdrs; - #[allow(clippy::missing_safety_doc)] pub(crate) unsafe fn with_tls(f: impl FnOnce() -> !) -> ! { let phdr = locate_phdrs() + .unwrap_or_else(|err| abort!("{err}")) .iter() .find(|phdr| phdr.p_type == PT_TLS) .unwrap_or_else(|| abort!("no PT_TLS segment")); diff --git a/crates/sel4-runtime-common/src/unwinding.rs b/crates/sel4-runtime-common/src/unwinding.rs index 51a6daea4..de362d7b2 100644 --- a/crates/sel4-runtime-common/src/unwinding.rs +++ b/crates/sel4-runtime-common/src/unwinding.rs @@ -10,15 +10,13 @@ use unwinding::custom_eh_frame_finder::{ EhFrameFinder, FrameInfo, FrameInfoKind, set_custom_eh_frame_finder, }; -use sel4_elf_header::{PT_GNU_EH_FRAME, PT_LOAD}; - -use crate::locate_phdrs; +use sel4_elf_header::{PT_GNU_EH_FRAME, PT_LOAD, locate_phdrs}; struct EhFrameFinderImpl; unsafe impl EhFrameFinder for EhFrameFinderImpl { fn find(&self, pc: usize) -> Option { - let phdrs = locate_phdrs(); + let phdrs = locate_phdrs().unwrap_or_else(|err| abort!("{err}")); let text_base = phdrs.iter().find_map(|phdr| { if phdr.p_type == PT_LOAD { diff --git a/hacking/cargo-manifest-management/direct-dependency-allow-list.toml b/hacking/cargo-manifest-management/direct-dependency-allow-list.toml index 8c7032f92..adec828c5 100644 --- a/hacking/cargo-manifest-management/direct-dependency-allow-list.toml +++ b/hacking/cargo-manifest-management/direct-dependency-allow-list.toml @@ -50,6 +50,7 @@ proc-macro2 = "1.0.103" ptr_meta = "0.3.1" quote = "1.0.41" rand = "0.10.0" +rangemap = "1.7.1" rcgen = "0.14.5" regex = "1.12.2" ring = { version = "=0.17.8", auto-update = false } diff --git a/hacking/nix/scope/default.nix b/hacking/nix/scope/default.nix index 51d64cfa8..8252b04f5 100644 --- a/hacking/nix/scope/default.nix +++ b/hacking/nix/scope/default.nix @@ -215,7 +215,6 @@ superCallPackage ../rust-utils {} self // mkSeL4CustomRustTargetTripleName = { rootTask ? false , microkit ? false - , resettable ? false , minimal ? false , unwind ? false , musl ? false @@ -225,7 +224,6 @@ superCallPackage ../rust-utils {} self // "-sel4" (lib.optionalString rootTask "-roottask") (lib.optionalString microkit "-microkit") - (lib.optionalString resettable "-resettable") (lib.optionalString minimal "-minimal") (lib.optionalString unwind "-unwind") (lib.optionalString musl "-musl") diff --git a/hacking/nix/scope/world/instances/default.nix b/hacking/nix/scope/world/instances/default.nix index 64f106cf0..62ac8ed02 100644 --- a/hacking/nix/scope/world/instances/default.nix +++ b/hacking/nix/scope/world/instances/default.nix @@ -25,6 +25,7 @@ , seL4Config , seL4RustEnvVars , seL4Modifications +, prepareResettable , muslForSeL4 , dummyLibunwind @@ -160,6 +161,19 @@ in rec { }; }); + reset = + let + origRootTask = mkTask { + rootCrate = crates.tests-root-task-reset; + release = false; + }; + in maybe haveFullRuntime (mkInstance { + rootTask.elf = prepareResettable origRootTask.elf; + extraPlatformArgs = lib.optionalAttrs canSimulate { + canAutomateSimply = true; + }; + }); + backtrace = maybe (haveFullRuntime && haveUnwindingSupport) (mkInstance rec { rootTask = let diff --git a/hacking/nix/scope/world/instances/microkit/default.nix b/hacking/nix/scope/world/instances/microkit/default.nix index 5560bd192..3f4f7b1fb 100644 --- a/hacking/nix/scope/world/instances/microkit/default.nix +++ b/hacking/nix/scope/world/instances/microkit/default.nix @@ -153,7 +153,6 @@ in { rootCrate = crates.tests-microkit-reset; targetTriple = mkSeL4RustTargetTriple { microkit = true; - resettable = true; minimal = false; }; release = false; @@ -162,10 +161,6 @@ in { origELF = "${orig}/bin/test.elf"; patched = prepareResettable origELF; - - sup = runCommandCC "test.sup.elf" {} '' - $OBJCOPY --only-keep-debug ${origELF} $out - ''; }; in callPlatform { @@ -174,9 +169,6 @@ in { (linkFarm "pd" { "test.elf" = pd.patched; }) - (linkFarm "pd" { - "test.sup.elf" = pd.sup; - }) ]; systemXML = sources.srcRoot + "/crates/private/tests/microkit/reset/src/bin/system.xml"; }; @@ -186,7 +178,6 @@ in { extraDebuggingLinks = [ { name = "test.orig.elf"; path = pd.origELF; } { name = "test.patched.elf"; path = pd.patched; } - { name = "test.sup.elf"; path = pd.sup; } ]; } // { inherit pd; diff --git a/support/targets/aarch64-sel4-microkit-resettable-minimal.json b/support/targets/aarch64-sel4-microkit-resettable-minimal.json deleted file mode 100644 index 43039919c..000000000 --- a/support/targets/aarch64-sel4-microkit-resettable-minimal.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "arch": "aarch64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", - "default-uwtable": true, - "disable-redzone": true, - "exe-suffix": ".elf", - "features": "+v8a,+strict-align,+neon", - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-target": "aarch64-unknown-none", - "max-atomic-width": 128, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "pre-link-args": { - "gnu": [ - "--fix-cortex-a53-843419" - ], - "gnu-lld": [ - "--fix-cortex-a53-843419" - ] - }, - "relocation-model": "static", - "stack-probes": { - "kind": "inline" - }, - "supported-sanitizers": [ - "kcfi", - "kernel-address", - "kernel-hwaddress" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/aarch64-sel4-microkit-resettable-unwind.json b/support/targets/aarch64-sel4-microkit-resettable-unwind.json deleted file mode 100644 index 6b7689ef4..000000000 --- a/support/targets/aarch64-sel4-microkit-resettable-unwind.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "arch": "aarch64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", - "default-uwtable": true, - "disable-redzone": true, - "exe-suffix": ".elf", - "features": "+v8a,+strict-align,+neon", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-target": "aarch64-unknown-none", - "max-atomic-width": 128, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "pre-link-args": { - "gnu": [ - "--fix-cortex-a53-843419" - ], - "gnu-lld": [ - "--fix-cortex-a53-843419" - ] - }, - "relocation-model": "static", - "stack-probes": { - "kind": "inline" - }, - "supported-sanitizers": [ - "kcfi", - "kernel-address", - "kernel-hwaddress" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/aarch64-sel4-microkit-resettable.json b/support/targets/aarch64-sel4-microkit-resettable.json deleted file mode 100644 index 231dba49a..000000000 --- a/support/targets/aarch64-sel4-microkit-resettable.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "arch": "aarch64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", - "default-uwtable": true, - "disable-redzone": true, - "exe-suffix": ".elf", - "features": "+v8a,+strict-align,+neon", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-target": "aarch64-unknown-none", - "max-atomic-width": 128, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "pre-link-args": { - "gnu": [ - "--fix-cortex-a53-843419" - ], - "gnu-lld": [ - "--fix-cortex-a53-843419" - ] - }, - "relocation-model": "static", - "stack-probes": { - "kind": "inline" - }, - "supported-sanitizers": [ - "kcfi", - "kernel-address", - "kernel-hwaddress" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/riscv64gc-sel4-microkit-resettable-minimal.json b/support/targets/riscv64gc-sel4-microkit-resettable-minimal.json deleted file mode 100644 index 36330d97f..000000000 --- a/support/targets/riscv64gc-sel4-microkit-resettable-minimal.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "arch": "riscv64", - "code-model": "medium", - "cpu": "generic-rv64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", - "emit-debug-gdb-scripts": false, - "exe-suffix": ".elf", - "features": "+m,+a,+f,+d,+c,+zicsr,+zifencei", - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-abiname": "lp64d", - "llvm-target": "riscv64", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "relocation-model": "static", - "supported-sanitizers": [ - "shadow-call-stack", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/riscv64gc-sel4-microkit-resettable-unwind.json b/support/targets/riscv64gc-sel4-microkit-resettable-unwind.json deleted file mode 100644 index 30348e515..000000000 --- a/support/targets/riscv64gc-sel4-microkit-resettable-unwind.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "arch": "riscv64", - "code-model": "medium", - "cpu": "generic-rv64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", - "emit-debug-gdb-scripts": false, - "exe-suffix": ".elf", - "features": "+m,+a,+f,+d,+c,+zicsr,+zifencei", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-abiname": "lp64d", - "llvm-target": "riscv64", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "relocation-model": "static", - "supported-sanitizers": [ - "shadow-call-stack", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/riscv64gc-sel4-microkit-resettable.json b/support/targets/riscv64gc-sel4-microkit-resettable.json deleted file mode 100644 index ef91bab8f..000000000 --- a/support/targets/riscv64gc-sel4-microkit-resettable.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "arch": "riscv64", - "code-model": "medium", - "cpu": "generic-rv64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", - "emit-debug-gdb-scripts": false, - "exe-suffix": ".elf", - "features": "+m,+a,+f,+d,+c,+zicsr,+zifencei", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-abiname": "lp64d", - "llvm-target": "riscv64", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "relocation-model": "static", - "supported-sanitizers": [ - "shadow-call-stack", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/riscv64imac-sel4-microkit-resettable-minimal.json b/support/targets/riscv64imac-sel4-microkit-resettable-minimal.json deleted file mode 100644 index 9ff08bdf4..000000000 --- a/support/targets/riscv64imac-sel4-microkit-resettable-minimal.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "arch": "riscv64", - "code-model": "medium", - "cpu": "generic-rv64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", - "emit-debug-gdb-scripts": false, - "exe-suffix": ".elf", - "features": "+m,+a,+c", - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-abiname": "lp64", - "llvm-target": "riscv64", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "relocation-model": "static", - "supported-sanitizers": [ - "shadow-call-stack", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/riscv64imac-sel4-microkit-resettable-unwind.json b/support/targets/riscv64imac-sel4-microkit-resettable-unwind.json deleted file mode 100644 index 8c71ec2dd..000000000 --- a/support/targets/riscv64imac-sel4-microkit-resettable-unwind.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "arch": "riscv64", - "code-model": "medium", - "cpu": "generic-rv64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", - "emit-debug-gdb-scripts": false, - "exe-suffix": ".elf", - "features": "+m,+a,+c", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-abiname": "lp64", - "llvm-target": "riscv64", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "relocation-model": "static", - "supported-sanitizers": [ - "shadow-call-stack", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/riscv64imac-sel4-microkit-resettable.json b/support/targets/riscv64imac-sel4-microkit-resettable.json deleted file mode 100644 index 351ab2d30..000000000 --- a/support/targets/riscv64imac-sel4-microkit-resettable.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "arch": "riscv64", - "code-model": "medium", - "cpu": "generic-rv64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", - "emit-debug-gdb-scripts": false, - "exe-suffix": ".elf", - "features": "+m,+a,+c", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-abiname": "lp64", - "llvm-target": "riscv64", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "relocation-model": "static", - "supported-sanitizers": [ - "shadow-call-stack", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/x86_64-sel4-microkit-resettable-minimal.json b/support/targets/x86_64-sel4-microkit-resettable-minimal.json deleted file mode 100644 index 56e932045..000000000 --- a/support/targets/x86_64-sel4-microkit-resettable-minimal.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "arch": "x86_64", - "code-model": "kernel", - "cpu": "x86-64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", - "disable-redzone": true, - "exe-suffix": ".elf", - "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float", - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-target": "x86_64-unknown-none-elf", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "plt-by-default": false, - "position-independent-executables": true, - "relocation-model": "static", - "relro-level": "off", - "rustc-abi": "softfloat", - "stack-probes": { - "kind": "inline" - }, - "static-position-independent-executables": true, - "supported-sanitizers": [ - "kcfi", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/x86_64-sel4-microkit-resettable-unwind.json b/support/targets/x86_64-sel4-microkit-resettable-unwind.json deleted file mode 100644 index 3dd7efab1..000000000 --- a/support/targets/x86_64-sel4-microkit-resettable-unwind.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "arch": "x86_64", - "code-model": "kernel", - "cpu": "x86-64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", - "disable-redzone": true, - "exe-suffix": ".elf", - "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-target": "x86_64-unknown-none-elf", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "plt-by-default": false, - "position-independent-executables": true, - "relocation-model": "static", - "relro-level": "off", - "rustc-abi": "softfloat", - "stack-probes": { - "kind": "inline" - }, - "static-position-independent-executables": true, - "supported-sanitizers": [ - "kcfi", - "kernel-address" - ], - "target-pointer-width": 64 -} diff --git a/support/targets/x86_64-sel4-microkit-resettable.json b/support/targets/x86_64-sel4-microkit-resettable.json deleted file mode 100644 index 378468882..000000000 --- a/support/targets/x86_64-sel4-microkit-resettable.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "arch": "x86_64", - "code-model": "kernel", - "cpu": "x86-64", - "crt-objects-fallback": "false", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", - "disable-redzone": true, - "exe-suffix": ".elf", - "features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float", - "has-thread-local": true, - "link-script": "SECTIONS {\n .persistent : {\n *(.persistent .persistent.*)\n }\n} INSERT BEFORE .data;\n\nASSERT(DEFINED(_reset), \"_reset is not defined\")\n\nENTRY(_reset)\n__sel4_ipc_buffer_obj = (__ehdr_start & ~(4096 - 1)) - 4096;", - "linker": "rust-lld", - "linker-flavor": "gnu-lld", - "llvm-target": "x86_64-unknown-none-elf", - "max-atomic-width": 64, - "metadata": { - "description": null, - "host_tools": null, - "std": null, - "tier": null - }, - "panic-strategy": "abort", - "plt-by-default": false, - "position-independent-executables": true, - "relocation-model": "static", - "relro-level": "off", - "rustc-abi": "softfloat", - "stack-probes": { - "kind": "inline" - }, - "static-position-independent-executables": true, - "supported-sanitizers": [ - "kcfi", - "kernel-address" - ], - "target-pointer-width": 64 -}