Skip to content

Change main from extern "C" to "Rust", and rename to origin_main #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example-crates/basic/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use origin::thread::*;
use origin::program::*;
use origin::thread::*;

fn main() {
eprintln!("Hello from main thread");
Expand Down
15 changes: 10 additions & 5 deletions example-crates/external-start/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ extern crate libc;
use alloc::boxed::Box;
use atomic_dbg::{dbg, eprintln};
use core::sync::atomic::{AtomicBool, Ordering};
use origin::thread::*;
use origin::program::*;
use origin::thread::*;

#[panic_handler]
fn panic(panic: &core::panic::PanicInfo<'_>) -> ! {
Expand Down Expand Up @@ -56,7 +56,7 @@ static EARLY_INIT_ARRAY: unsafe extern "C" fn(i32, *mut *mut u8) = {
};

#[no_mangle]
extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
unsafe fn origin_main(_argc: usize, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
eprintln!("Hello from main thread");

at_exit(Box::new(|| eprintln!("Hello from an at_exit handler")));
Expand All @@ -77,10 +77,15 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
)
.unwrap();

unsafe {
join_thread(thread);
}
join_thread(thread);

eprintln!("Goodbye from main");
exit(0);
}

// Libc calls `main` so we need to provide a definition to satisfy the
// linker, however origin gains control before libc can call this `main`.
#[no_mangle]
unsafe fn main(_argc: i32, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
core::intrinsics::abort();
}
2 changes: 1 addition & 1 deletion example-crates/no-std/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ extern crate alloc;

use alloc::boxed::Box;
use atomic_dbg::{dbg, eprintln};
use origin::thread::*;
use origin::program::*;
use origin::thread::*;

#[panic_handler]
fn panic(panic: &core::panic::PanicInfo<'_>) -> ! {
Expand Down
6 changes: 2 additions & 4 deletions example-crates/origin-start-lto/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "C" fn eh_personality() {}
static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc;

#[no_mangle]
extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
unsafe fn origin_main(_argc: usize, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
eprintln!("Hello from main thread");

at_exit(Box::new(|| eprintln!("Hello from an at_exit handler")));
Expand All @@ -48,9 +48,7 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
)
.unwrap();

unsafe {
join_thread(thread);
}
join_thread(thread);

eprintln!("Goodbye from main");
exit(0);
Expand Down
2 changes: 1 addition & 1 deletion example-crates/origin-start-no-alloc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn panic(panic: &core::panic::PanicInfo<'_>) -> ! {
extern "C" fn eh_personality() {}

#[no_mangle]
extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
unsafe fn origin_main(_argc: usize, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
eprintln!("Hello!");

// Unlike origin-start, this example can't create threads because origin's
Expand Down
6 changes: 2 additions & 4 deletions example-crates/origin-start/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "C" fn eh_personality() {}
static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc;

#[no_mangle]
extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
unsafe fn origin_main(_argc: usize, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
eprintln!("Hello from main thread");

at_exit(Box::new(|| eprintln!("Hello from an at_exit handler")));
Expand All @@ -48,9 +48,7 @@ extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
)
.unwrap();

unsafe {
join_thread(thread);
}
join_thread(thread);

eprintln!("Goodbye from main");
exit(0);
Expand Down
4 changes: 2 additions & 2 deletions example-crates/tiny/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#![feature(lang_items)]
#![feature(core_intrinsics)]

extern crate origin;
extern crate compiler_builtins;
extern crate origin;

#[panic_handler]
fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! {
Expand All @@ -18,6 +18,6 @@ fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! {
extern "C" fn eh_personality() {}

#[no_mangle]
extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
unsafe fn origin_main(_argc: usize, _argv: *mut *mut u8, _envp: *mut *mut u8) -> i32 {
42
}
35 changes: 29 additions & 6 deletions src/program.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
//! Program startup and shutdown.
//!
//! To use origin's program startup, define a function named `origin_main` like
//! this:
//!
//! ```no_run
//! #[no_mangle]
//! fn origin_main(argc: usize, argv: *mut *mut u8, envp: *mut *mut u8) -> i32 {
//! todo!("Run the program and return the program exit status.")
//! }
//! ```
//!
//! Origin will call this function after starting up the program and running
//! the constructors. `argc` is the number of command-line arguments with a
//! value of at most `c_int::MAX`, and `argv` is a pointer to a NULL-terminated
//! array of pointers to NUL-terminated C strings. `argc` and `argv` describe
//! the command-line arguments. `envp` is a pointer to a NULL-terminated array
//! of pointers to NUL-terminated C strings containing a key followed by `b'='`
//! followed by a value. It describes the environment variables. The function
//! should return a value for the program exit status.
//!
//! This is a low-level and somewhat C-flavored interface, which is in tension
//! with origin's goal of providing Rust-idiomatic interfaces, however it does
//! mean that origin can avoid doing any work that users might not need.

#[cfg(feature = "origin-thread")]
use crate::thread::initialize_main_thread;
Expand Down Expand Up @@ -116,22 +139,22 @@ unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) {
#[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;
extern "Rust" {
fn origin_main(argc: usize, argv: *mut *mut u8, envp: *mut *mut u8) -> i32;
}

// 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);
log::trace!("Calling `origin_main({:?}, {:?}, {:?})`", argc, argv, envp);

// Call `main`.
let status = main(argc, argv, envp);
// Call `origin_main`.
let status = origin_main(argc as usize, argv, envp);

#[cfg(feature = "log")]
log::trace!("`main` returned `{:?}`", status);
log::trace!("`origin_main` returned `{:?}`", status);

status
}
Expand Down