From b55be91442600afdaa76c3bfb0337333255bbaf2 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Mon, 4 Sep 2023 15:52:05 +0200 Subject: [PATCH 01/14] Move logic from entry to indipendent functions --- src/program.rs | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/program.rs b/src/program.rs index fe834fa..840f3d0 100644 --- a/src/program.rs +++ b/src/program.rs @@ -30,8 +30,6 @@ use rustix_futex_sync::Mutex; /// `mem` should point to the stack as provided by the operating system. #[cfg(any(feature = "origin-start", feature = "external-start"))] pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { - use linux_raw_sys::ctypes::c_uint; - extern "C" { fn main(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> c_int; } @@ -75,6 +73,27 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { } // Compute `argc`, `argv`, and `envp`. + let (argc, argv, envp) = compute_args(mem); + init_runtime(mem, argc, argv, envp); + + #[cfg(feature = "log")] + log::trace!("Calling `main({:?}, {:?}, {:?})`", argc, argv, envp); + + // Call `main`. + let status = main(argc, argv, envp); + + #[cfg(feature = "log")] + log::trace!("`main` returned `{:?}`", status); + + // Run functions registered with `at_exit`, and exit with main's return + // value. + exit(status) +} + +#[cfg(any(feature = "origin-start", feature = "external-start"))] +unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) { + use linux_raw_sys::ctypes::c_uint; + let argc = *mem as c_int; let argv = mem.add(1).cast::<*mut u8>(); let envp = argv.add(argc as c_uint as usize + 1); @@ -84,6 +103,12 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { debug_assert_eq!(*mem, argc as _); debug_assert_eq!(*argv.add(argc as usize), core::ptr::null_mut()); + (argc, argv, envp) +} + +#[cfg(any(feature = "origin-start", feature = "external-start"))] +#[allow(unused_variables)] +unsafe fn init_runtime(mem: *mut usize, argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) { // Explicitly initialize `rustix` so that we can control the initialization // order. #[cfg(feature = "param")] @@ -102,19 +127,6 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { // Call the functions registered via `.init_array`. #[cfg(feature = "init-fini-arrays")] call_ctors(argc, argv, envp); - - #[cfg(feature = "log")] - log::trace!("Calling `main({:?}, {:?}, {:?})`", argc, argv, envp); - - // Call `main`. - let status = main(argc, argv, envp); - - #[cfg(feature = "log")] - log::trace!("`main` returned `{:?}`", status); - - // Run functions registered with `at_exit`, and exit with main's return - // value. - exit(status) } /// Call the constructors in the `.init_array` section. From e926c295c0897d6df39470278a9801836aec727b Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 18:27:05 +0200 Subject: [PATCH 02/14] Move some logic to call_user_code fn --- src/program.rs | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/program.rs b/src/program.rs index 840f3d0..5b75f95 100644 --- a/src/program.rs +++ b/src/program.rs @@ -30,10 +30,6 @@ use rustix_futex_sync::Mutex; /// `mem` should point to the stack as provided by the operating system. #[cfg(any(feature = "origin-start", feature = "external-start"))] pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { - extern "C" { - fn main(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> c_int; - } - // Do some basic precondition checks, to ensure that our assembly code did // what we expect it to do. These are debug-only for now, to keep the // release-mode startup code simple to disassemble and inspect, while we're @@ -74,16 +70,9 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { // Compute `argc`, `argv`, and `envp`. let (argc, argv, envp) = compute_args(mem); - init_runtime(mem, argc, argv, envp); + init_runtime(mem, envp); - #[cfg(feature = "log")] - log::trace!("Calling `main({:?}, {:?}, {:?})`", argc, argv, envp); - - // Call `main`. - let status = main(argc, argv, envp); - - #[cfg(feature = "log")] - log::trace!("`main` returned `{:?}`", status); + let status = call_user_code(argc, argv, envp); // Run functions registered with `at_exit`, and exit with main's return // value. @@ -108,7 +97,7 @@ unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) { #[cfg(any(feature = "origin-start", feature = "external-start"))] #[allow(unused_variables)] -unsafe fn init_runtime(mem: *mut usize, argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) { +unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) { // Explicitly initialize `rustix` so that we can control the initialization // order. #[cfg(feature = "param")] @@ -123,10 +112,29 @@ unsafe fn init_runtime(mem: *mut usize, argc: c_int, argv: *mut *mut u8, envp: * // Initialize the main thread. #[cfg(feature = "origin-thread")] initialize_main_thread(mem.cast()); +} + +#[cfg(any(feature = "origin-start", feature = "external-start"))] +#[allow(unused_variables)] +unsafe fn call_user_code(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> i32 { + extern "C" { + fn main(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> c_int; + } // Call the functions registered via `.init_array`. #[cfg(feature = "init-fini-arrays")] call_ctors(argc, argv, envp); + + #[cfg(feature = "log")] + log::trace!("Calling `main({:?}, {:?}, {:?})`", argc, argv, envp); + + // Call `main`. + let status = main(argc, argv, envp); + + #[cfg(feature = "log")] + log::trace!("`main` returned `{:?}`", status); + + status } /// Call the constructors in the `.init_array` section. From 2881889baf6888d6e000d4aec8a7cb02c49b4839 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 18:31:37 +0200 Subject: [PATCH 03/14] Create origin-macros crate --- Cargo.toml | 3 +++ macros/Cargo.toml | 12 ++++++++++++ macros/src/lib.rs | 14 ++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 macros/Cargo.toml create mode 100644 macros/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 19f5c1c..47b100f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["macros"] + [package] name = "origin" version = "0.12.1" diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 0000000..3a7629c --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "origin-macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.66" +quote = "1.0.33" +syn = "2.0.31" diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} From 6f8c04ed64a3373ae5636f6692926c6720f100b7 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 18:37:55 +0200 Subject: [PATCH 04/14] Create empty macro stub --- macros/src/lib.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 7d12d9a..f87f0a4 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,14 +1,6 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; +use proc_macro::TokenStream; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } +#[proc_macro_attribute] +pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream { + item } From 2c93544f6497c45ade8389b533ba4f758fabb11b Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 18:40:16 +0200 Subject: [PATCH 05/14] Added main macro to origin crate --- Cargo.toml | 5 +++++ src/lib.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 47b100f..7448f9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,9 @@ memoffset = { version = "0.9.0", optional = true } log = { version = "0.4.14", default-features = false, optional = true } rustix-futex-sync = "0.1.0" +# Provides "origin::main" macro +origin-macros = { version = "0.1.0", path = "./macros", optional = true } + # Optional logging backends. You can use any external logger, but using these # features allows origin to initialize the logger before main, so that you can # see the log messages emitted before main is called. @@ -58,6 +61,8 @@ rustc-dep-of-std = [ "libc/rustc-dep-of-std", ] +macros = ["dep:origin-macros"] + # Use origin's implementation of program startup and shutdown. origin-program = [] diff --git a/src/lib.rs b/src/lib.rs index 68d17ee..838e87a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,10 @@ pub mod thread; #[cfg_attr(target_arch = "arm", path = "arch/arm.rs")] mod arch; + +#[cfg(feature = "macros")] +pub use origin_macros::main; + /// The program entry point. /// /// # Safety From 90eb32724c68c5f7684509403940759632c890c4 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:16:17 +0200 Subject: [PATCH 06/14] Added required syn feature --- macros/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 3a7629c..18c4a3d 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -9,4 +9,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.66" quote = "1.0.33" -syn = "2.0.31" +syn = { version = "2.0.31", features = ["full"] } From 69eeb9a7b8b520420868c78b464c5d620c85e2e7 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:16:39 +0200 Subject: [PATCH 07/14] Initial macro implementation --- macros/src/lib.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index f87f0a4..88c7e6b 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,6 +1,32 @@ use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, ItemFn}; #[proc_macro_attribute] -pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream { - item +pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream { + let main_fn: ItemFn = parse_macro_input!(input); + + quote! { + #main_fn + + #[naked] + #[no_mangle] + unsafe extern "C" fn _start() -> ! { + unsafe fn entry(mem: *mut usize) -> ! { + let (argc, argv, envp) = origin::program::compute_args(mem); + origin::program::init_runtime(mem, envp); + origin::program::exit(main()) + } + + #[cfg(target_arch = "x86_64")] + core::arch::asm!( + "mov rdi, rsp", // Pass the incoming `rsp` as the arg to `entry`. + "push rbp", // Set the return address to zero. + "jmp {entry}", // Jump to `entry`. + entry = sym entry, + options(noreturn), + ); + } + } + .into() } From 1dda4a7ba67e3ccebac8843041037e1cfd7e8617 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:23:22 +0200 Subject: [PATCH 08/14] Fully implement macro --- macros/src/lib.rs | 74 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 88c7e6b..4e19830 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,10 +1,13 @@ use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::{parse_macro_input, ItemFn}; #[proc_macro_attribute] pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream { let main_fn: ItemFn = parse_macro_input!(input); + let main_fn_ident = &main_fn.sig.ident; + let asm_impl = asm_impl(); quote! { #main_fn @@ -15,18 +18,71 @@ pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream { unsafe fn entry(mem: *mut usize) -> ! { let (argc, argv, envp) = origin::program::compute_args(mem); origin::program::init_runtime(mem, envp); - origin::program::exit(main()) + origin::program::exit(#main_fn_ident()) } - #[cfg(target_arch = "x86_64")] - core::arch::asm!( - "mov rdi, rsp", // Pass the incoming `rsp` as the arg to `entry`. - "push rbp", // Set the return address to zero. - "jmp {entry}", // Jump to `entry`. - entry = sym entry, - options(noreturn), - ); + #asm_impl } } .into() } + +/// Provides the asm implementation to start the program +fn asm_impl() -> TokenStream2 { + quote! { + // Jump to `entry`, passing it the initial stack pointer value as an + // argument, a null return address, a null frame pointer, and an aligned + // stack pointer. On many architectures, the incoming frame pointer is + // already null. + + #[cfg(target_arch = "x86_64")] + core::arch::asm!( + "mov rdi, rsp", // Pass the incoming `rsp` as the arg to `entry`. + "push rbp", // Set the return address to zero. + "jmp {entry}", // Jump to `entry`. + entry = sym entry, + options(noreturn), + ); + + #[cfg(target_arch = "aarch64")] + core::arch::asm!( + "mov x0, sp", // Pass the incoming `sp` as the arg to `entry`. + "mov x30, xzr", // Set the return address to zero. + "b {entry}", // Jump to `entry`. + entry = sym entry, + options(noreturn), + ); + + #[cfg(target_arch = "arm")] + core::arch::asm!( + "mov r0, sp\n", // Pass the incoming `sp` as the arg to `entry`. + "mov lr, #0", // Set the return address to zero. + "b {entry}", // Jump to `entry`. + entry = sym entry, + options(noreturn), + ); + + #[cfg(target_arch = "riscv64")] + core::arch::asm!( + "mv a0, sp", // Pass the incoming `sp` as the arg to `entry`. + "mv ra, zero", // Set the return address to zero. + "mv fp, zero", // Set the frame address to zero. + "tail {entry}", // Jump to `entry`. + entry = sym entry, + options(noreturn), + ); + + #[cfg(target_arch = "x86")] + core::arch::asm!( + "mov eax, esp", // Save the incoming `esp` value. + "push ebp", // Pad for alignment. + "push ebp", // Pad for alignment. + "push ebp", // Pad for alignment. + "push eax", // Pass saved the incoming `esp` as the arg to `entry`. + "push ebp", // Set the return address to zero. + "jmp {entry}", // Jump to `entry`. + entry = sym entry, + options(noreturn), + ); + } +} From 21ee11847be6523d1240f97bd828943b06f664cf Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:24:23 +0200 Subject: [PATCH 09/14] Add readme file to macros --- macros/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 macros/README.md diff --git a/macros/README.md b/macros/README.md new file mode 100644 index 0000000..cdc6a98 --- /dev/null +++ b/macros/README.md @@ -0,0 +1 @@ +# Origin Macros From 750573c771940a76e56c8e962e3029881cc95fe5 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:27:28 +0200 Subject: [PATCH 10/14] Updated manifest informations --- macros/Cargo.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 18c4a3d..2ea5a08 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -2,6 +2,17 @@ name = "origin-macros" version = "0.1.0" edition = "2021" +authors = [ + "Dan Gohman ", + "Federico Maria Morrone ", +] +description = "Macros for origin crate" +documentation = "https://docs.rs/origin-macros" +license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" +repository = "https://github.com/sunfishcode/origin" +keywords = ["linux"] +categories = ["no-std"] +include = ["src", "Cargo.toml", "../COPYRIGHT", "../LICENSE*", "README.md"] [lib] proc-macro = true From c7c7697dfc52d266a4540b31dbfdeaf1112c1b2c Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:29:24 +0200 Subject: [PATCH 11/14] Remove provided _start impementation --- src/lib.rs | 72 ------------------------------------------------------ 1 file changed, 72 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 838e87a..f5f64dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,81 +40,9 @@ pub mod thread; #[cfg_attr(target_arch = "arm", path = "arch/arm.rs")] mod arch; - #[cfg(feature = "macros")] pub use origin_macros::main; -/// The program entry point. -/// -/// # Safety -/// -/// This function should never be called explicitly. It is the first thing -/// executed in the program, and it assumes that memory is laid out according -/// to the operating system convention for starting a new program. -#[cfg(feature = "origin-program")] -#[cfg(feature = "origin-start")] -#[naked] -#[no_mangle] -unsafe extern "C" fn _start() -> ! { - use core::arch::asm; - use program::entry; - - // Jump to `entry`, passing it the initial stack pointer value as an - // argument, a null return address, a null frame pointer, and an aligned - // stack pointer. On many architectures, the incoming frame pointer is - // already null. - - #[cfg(target_arch = "x86_64")] - asm!( - "mov rdi, rsp", // Pass the incoming `rsp` as the arg to `entry`. - "push rbp", // Set the return address to zero. - "jmp {entry}", // Jump to `entry`. - entry = sym entry, - options(noreturn), - ); - - #[cfg(target_arch = "aarch64")] - asm!( - "mov x0, sp", // Pass the incoming `sp` as the arg to `entry`. - "mov x30, xzr", // Set the return address to zero. - "b {entry}", // Jump to `entry`. - entry = sym entry, - options(noreturn), - ); - - #[cfg(target_arch = "arm")] - asm!( - "mov r0, sp\n", // Pass the incoming `sp` as the arg to `entry`. - "mov lr, #0", // Set the return address to zero. - "b {entry}", // Jump to `entry`. - entry = sym entry, - options(noreturn), - ); - - #[cfg(target_arch = "riscv64")] - asm!( - "mv a0, sp", // Pass the incoming `sp` as the arg to `entry`. - "mv ra, zero", // Set the return address to zero. - "mv fp, zero", // Set the frame address to zero. - "tail {entry}", // Jump to `entry`. - entry = sym entry, - options(noreturn), - ); - - #[cfg(target_arch = "x86")] - asm!( - "mov eax, esp", // Save the incoming `esp` value. - "push ebp", // Pad for alignment. - "push ebp", // Pad for alignment. - "push ebp", // Pad for alignment. - "push eax", // Pass saved the incoming `esp` as the arg to `entry`. - "push ebp", // Set the return address to zero. - "jmp {entry}", // Jump to `entry`. - entry = sym entry, - options(noreturn), - ); -} - /// A program entry point similar to `_start`, but which is meant to be called /// by something else in the program rather than the OS. /// From 51847d85ff1bafd0764b93006afcc78a3bf27090 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:29:48 +0200 Subject: [PATCH 12/14] Mark some functions as public --- src/program.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/program.rs b/src/program.rs index 5b75f95..4c4bc6e 100644 --- a/src/program.rs +++ b/src/program.rs @@ -79,8 +79,9 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! { exit(status) } +/// TODO: docs #[cfg(any(feature = "origin-start", feature = "external-start"))] -unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) { +pub unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) { use linux_raw_sys::ctypes::c_uint; let argc = *mem as c_int; @@ -95,9 +96,10 @@ unsafe fn compute_args(mem: *mut usize) -> (i32, *mut *mut u8, *mut *mut u8) { (argc, argv, envp) } +/// TODO: docs #[cfg(any(feature = "origin-start", feature = "external-start"))] #[allow(unused_variables)] -unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) { +pub unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) { // Explicitly initialize `rustix` so that we can control the initialization // order. #[cfg(feature = "param")] @@ -114,9 +116,10 @@ unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) { initialize_main_thread(mem.cast()); } +/// TODO: docs #[cfg(any(feature = "origin-start", feature = "external-start"))] #[allow(unused_variables)] -unsafe fn call_user_code(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> i32 { +pub unsafe fn call_user_code(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> i32 { extern "C" { fn main(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> c_int; } @@ -140,7 +143,7 @@ unsafe fn call_user_code(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) -> /// Call the constructors in the `.init_array` section. #[cfg(any(feature = "origin-start", feature = "external-start"))] #[cfg(feature = "init-fini-arrays")] -unsafe fn call_ctors(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) { +pub unsafe fn call_ctors(argc: c_int, argv: *mut *mut u8, envp: *mut *mut u8) { use core::ffi::c_void; extern "C" { From 16f99c6e111a1adcd68d6d31cd02953ad44e5f33 Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:42:11 +0200 Subject: [PATCH 13/14] Update examples to use macros --- example-crates/origin-start-lto/Cargo.toml | 2 +- example-crates/origin-start-lto/src/main.rs | 8 +++++--- example-crates/origin-start-no-alloc/Cargo.toml | 2 +- example-crates/origin-start-no-alloc/src/main.rs | 8 ++++---- example-crates/origin-start-tiny/Cargo.toml | 2 +- example-crates/origin-start-tiny/src/main.rs | 7 ++++--- example-crates/origin-start/Cargo.toml | 2 +- example-crates/origin-start/src/main.rs | 5 +++-- 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/example-crates/origin-start-lto/Cargo.toml b/example-crates/origin-start-lto/Cargo.toml index bd5496e..1eb5f57 100644 --- a/example-crates/origin-start-lto/Cargo.toml +++ b/example-crates/origin-start-lto/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] # Origin can be depended on just like any other crate. For no_std, disable # the default features, and the desired features. -origin = { path = "../..", default-features = false, features = ["origin-program", "origin-thread", "origin-start"] } +origin = { path = "../..", default-features = false, features = ["origin-program", "origin-thread", "origin-start", "macros"] } # Crates to help writing no_std code. atomic-dbg = { version = "0.1.8", default-features = false } diff --git a/example-crates/origin-start-lto/src/main.rs b/example-crates/origin-start-lto/src/main.rs index a998553..e35b361 100644 --- a/example-crates/origin-start-lto/src/main.rs +++ b/example-crates/origin-start-lto/src/main.rs @@ -5,6 +5,7 @@ #![allow(internal_features)] #![feature(lang_items)] #![feature(core_intrinsics)] +#![feature(naked_functions)] extern crate alloc; extern crate compiler_builtins; @@ -26,8 +27,8 @@ extern "C" fn eh_personality() {} #[global_allocator] static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc; -#[no_mangle] -extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { +#[origin::main] +fn main() -> i32 { eprintln!("Hello from main thread"); at_exit(Box::new(|| eprintln!("Hello from an at_exit handler"))); @@ -53,5 +54,6 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { } eprintln!("Goodbye from main"); - exit(0); + + 0 } diff --git a/example-crates/origin-start-no-alloc/Cargo.toml b/example-crates/origin-start-no-alloc/Cargo.toml index b6a71ae..4948cd9 100644 --- a/example-crates/origin-start-no-alloc/Cargo.toml +++ b/example-crates/origin-start-no-alloc/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] # Origin can be depended on just like any other crate. For no_std, disable # the default features, and the desired features. -origin = { path = "../..", default-features = false, features = ["origin-program", "origin-start"] } +origin = { path = "../..", default-features = false, features = ["origin-program", "origin-start", "macros"] } # Crates to help writing no_std code. atomic-dbg = { version = "0.1.8", default-features = false } diff --git a/example-crates/origin-start-no-alloc/src/main.rs b/example-crates/origin-start-no-alloc/src/main.rs index 8500ec1..b0b6515 100644 --- a/example-crates/origin-start-no-alloc/src/main.rs +++ b/example-crates/origin-start-no-alloc/src/main.rs @@ -5,11 +5,11 @@ #![allow(internal_features)] #![feature(lang_items)] #![feature(core_intrinsics)] +#![feature(naked_functions)] extern crate compiler_builtins; use atomic_dbg::{dbg, eprintln}; -use origin::program::*; #[panic_handler] fn panic(panic: &core::panic::PanicInfo<'_>) -> ! { @@ -20,12 +20,12 @@ fn panic(panic: &core::panic::PanicInfo<'_>) -> ! { #[lang = "eh_personality"] extern "C" fn eh_personality() {} -#[no_mangle] -extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { +#[origin::main] +fn start() -> i32 { eprintln!("Hello!"); // Unlike origin-start, this example can't create threads because origin's // thread support requires an allocator. - exit(0); + 0 } diff --git a/example-crates/origin-start-tiny/Cargo.toml b/example-crates/origin-start-tiny/Cargo.toml index 9616543..6e7fea1 100644 --- a/example-crates/origin-start-tiny/Cargo.toml +++ b/example-crates/origin-start-tiny/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] # Origin can be depended on just like any other crate. For no_std, disable # the default features, and the desired features. -origin = { path = "../..", default-features = false, features = ["origin-program", "origin-start"] } +origin = { path = "../..", default-features = false, features = ["origin-program", "origin-start", "macros"] } # Crates to help writing no_std code. compiler_builtins = { version = "0.1.101", features = ["mem"] } diff --git a/example-crates/origin-start-tiny/src/main.rs b/example-crates/origin-start-tiny/src/main.rs index 526028d..18d5e0a 100644 --- a/example-crates/origin-start-tiny/src/main.rs +++ b/example-crates/origin-start-tiny/src/main.rs @@ -5,9 +5,10 @@ #![allow(internal_features)] #![feature(lang_items)] #![feature(core_intrinsics)] +#![feature(naked_functions)] -extern crate origin; extern crate compiler_builtins; +extern crate origin; #[panic_handler] fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { @@ -17,7 +18,7 @@ fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { #[lang = "eh_personality"] extern "C" fn eh_personality() {} -#[no_mangle] -extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { +#[origin::start] +fn main() -> i32 { 42 } diff --git a/example-crates/origin-start/Cargo.toml b/example-crates/origin-start/Cargo.toml index 6182e2b..55e55a7 100644 --- a/example-crates/origin-start/Cargo.toml +++ b/example-crates/origin-start/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] # Origin can be depended on just like any other crate. For no_std, disable # the default features, and the desired features. -origin = { path = "../..", default-features = false, features = ["origin-program", "origin-thread", "origin-start"] } +origin = { path = "../..", default-features = false, features = ["origin-program", "origin-thread", "origin-start", "macros"] } # Crates to help writing no_std code. atomic-dbg = { version = "0.1.8", default-features = false } diff --git a/example-crates/origin-start/src/main.rs b/example-crates/origin-start/src/main.rs index a998553..89280ab 100644 --- a/example-crates/origin-start/src/main.rs +++ b/example-crates/origin-start/src/main.rs @@ -5,6 +5,7 @@ #![allow(internal_features)] #![feature(lang_items)] #![feature(core_intrinsics)] +#![feature(naked_functions)] extern crate alloc; extern crate compiler_builtins; @@ -26,8 +27,8 @@ extern "C" fn eh_personality() {} #[global_allocator] static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc; -#[no_mangle] -extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { +#[origin::main] +fn main() -> i32 { eprintln!("Hello from main thread"); at_exit(Box::new(|| eprintln!("Hello from an at_exit handler"))); From 6eac445d84c64659fb7dbae1543df55af15f80fa Mon Sep 17 00:00:00 2001 From: Federico Maria Morrone Date: Tue, 5 Sep 2023 19:42:32 +0200 Subject: [PATCH 14/14] Add fix to make test pass --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index f5f64dd..4f85f2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,9 @@ #![deny(lossy_provenance_casts)] #![no_std] +#![allow(dead_code)] // FIXME: this is just so tests pass while I implement everything + + #[cfg(all(feature = "alloc", not(feature = "rustc-dep-of-std")))] extern crate alloc;