From 8b39059da8a8f3d58695ad62de869fb9c0973383 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Mon, 17 Jul 2023 22:54:43 +0300 Subject: [PATCH] alnyan/yggdrasil: add args implementation --- library/std/src/sys/yggdrasil/args.rs | 68 +++++++++++++++++++++++---- library/std/src/sys/yggdrasil/mod.rs | 3 +- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/library/std/src/sys/yggdrasil/args.rs b/library/std/src/sys/yggdrasil/args.rs index 02aae054769..d502e6c0264 100644 --- a/library/std/src/sys/yggdrasil/args.rs +++ b/library/std/src/sys/yggdrasil/args.rs @@ -1,10 +1,40 @@ use crate::ffi::OsString; use crate::fmt; +use crate::str::FromStr; -pub struct Args(!); +#[allow(dead_code)] +#[derive(Clone, Copy)] +pub struct Args { + base: usize, + len: usize, + index: usize, +} + +// Argument structure layout: +// +// 0x000: args len +// 0x008: arg ptr 0 +// 0x010: arg len 0 +// 0x018: arg ptr 1 +// 0x020: arg len 1 +// ... +// .....: arg data 0 +// .....: arg data 1 +static mut ARGS: usize = 0; pub fn args() -> Args { - todo!() + let base = unsafe { ARGS }; + + if base == 0 { + panic!("Program arguments not initialized"); + } + + let len = unsafe { + #[allow(fuzzy_provenance_casts)] + (base as *mut usize).read() + }; + + Args { base, len, index: 0 } } impl fmt::Debug for Args { @@ -17,17 +47,36 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { - todo!() - } + if self.index == self.len { + return None; + } - fn size_hint(&self) -> (usize, Option) { - todo!() + let ptr_ptr_addr = self.base + (1 + self.index * 2) * 8; + let arg_ptr = unsafe { + #[allow(fuzzy_provenance_casts)] + (ptr_ptr_addr as *mut usize).read() + }; + let arg_len = unsafe { + #[allow(fuzzy_provenance_casts)] + ((ptr_ptr_addr + 8) as *mut usize).read() + }; + + let slice = unsafe { + #[allow(fuzzy_provenance_casts)] + crate::slice::from_raw_parts(arg_ptr as *const u8, arg_len) + }; + let arg_str = crate::str::from_utf8(slice).unwrap(); + let arg_os_string = OsString::from_str(arg_str).unwrap(); + + self.index += 1; + + Some(arg_os_string) } } impl ExactSizeIterator for Args { fn len(&self) -> usize { - todo!() + self.len } } @@ -37,7 +86,6 @@ impl DoubleEndedIterator for Args { } } -#[allow(dead_code)] -pub unsafe fn init(_argc: isize, _argv: *const *const u8) { - todo!() +pub unsafe fn init(program_arg: usize) { + ARGS = program_arg; } diff --git a/library/std/src/sys/yggdrasil/mod.rs b/library/std/src/sys/yggdrasil/mod.rs index 6e99d96aed4..f1655804286 100644 --- a/library/std/src/sys/yggdrasil/mod.rs +++ b/library/std/src/sys/yggdrasil/mod.rs @@ -99,7 +99,7 @@ pub fn unsupported() -> ! { #[cfg(not(test))] #[no_mangle] -pub unsafe extern "C" fn runtime_entry(_arg: usize) -> ! { +pub unsafe extern "C" fn runtime_entry(program_arg: usize) -> ! { use crate::ffi::c_char; use crate::ptr::null; @@ -107,6 +107,7 @@ pub unsafe extern "C" fn runtime_entry(_arg: usize) -> ! { fn main(argc: isize, argv: *const *const c_char) -> i32; } + args::init(program_arg); let result = main(0, null()); yggdrasil_rt::sys::exit(result);