Skip to main content

irid_std/
start.rs

1#[cfg(target_os = "none")]
2use core::{ffi::CStr, ptr::slice_from_raw_parts};
3
4#[cfg(target_os = "none")]
5use alloc::borrow::ToOwned;
6#[cfg(target_os = "none")]
7pub use irid_syscall::ffi::thread::syscall_exit as entrypoint_exit;
8
9#[cfg(target_os = "none")]
10use crate::env::{arg_lock, var_lock};
11
12#[cfg(target_os = "none")]
13#[macro_export]
14macro_rules! entrypoint {
15    () => {
16        core::arch::global_asm!(r#"
17        .global _start
18        _start:
19            mov rbp,0
20            mov rdi,[rsp]
21            lea rsi,[rsp + 0x8]
22            call _std_entry
23        "#);
24  
25        #[unsafe(no_mangle)]
26        unsafe extern "C" fn _std_entry(argc: usize, argv: *const *const u8) -> ! {
27            $crate::start::_std_init(argc, argv);
28            
29            main();
30            
31            $crate::start::entrypoint_exit(0);
32        }
33    };
34}
35
36#[cfg(target_os = "none")]
37#[unsafe(no_mangle)]
38pub extern "C" fn _std_init(argc: usize, argv: *const *const u8) {
39    let mut arg_lock = arg_lock();
40   
41    let args = unsafe { slice_from_raw_parts(argv, argc).as_ref_unchecked() };
42
43    for arg in args {
44        let arg = unsafe { CStr::from_ptr(*arg as *const i8) }.to_str().expect("failed to parse program argument");
45
46        arg_lock.push(arg.to_owned().into_boxed_str());
47    }
48
49    let mut env_lock = var_lock();
50
51    unsafe {
52        let mut envv = argv.byte_add((argc + 1) * size_of::<*const ()>());
53
54        while !(*envv).is_null() {
55            crate::println!("{envv:?}, {:?}", *envv);
56   
57            match CStr::from_ptr(*envv as *const i8).to_str() {
58                Ok(env) => match env.split_once("=") {
59                    Some((key, value)) => {
60                        env_lock.insert(key.to_owned().into_boxed_str(), value.to_owned().into_boxed_str());
61                    }
62                    None => crate::eprintln!("invalid environment variable format @ {:?}: missing '='", *envv),
63                },
64                Err(err) => {
65                    let bytes = CStr::from_ptr(*envv as *const i8).to_bytes();
66
67                    crate::eprintln!("failed to parse environment variable @ {:?}: {err}\n{bytes:?}", *envv)
68                },
69            }
70
71            envv = envv.byte_add(size_of::<*const ()>());
72        }
73    }
74} 
75
76#[cfg(not(target_os = "none"))]
77#[macro_export]
78macro_rules! entrypoint {
79    () => {}
80}
81