alnyan/yggdrasil: better argument passing from kernel

This commit is contained in:
2023-11-16 16:10:02 +02:00
parent 8a5d469dc3
commit bc22846ab3
5 changed files with 14 additions and 77 deletions
+6 -15
View File
@@ -2,17 +2,15 @@ use crate::ffi::OsString;
use crate::fmt;
use crate::mem::size_of;
use crate::str::FromStr;
use crate::sys::yggdrasil::util::KStringList;
#[allow(dead_code)]
#[derive(Clone, Copy)]
#[derive(Clone)]
pub struct Args {
list: KStringList,
index: usize,
iter: crate::slice::Iter<'static, &'static str>,
}
pub fn args() -> Args {
Args { list: unsafe { KStringList::new(super::ARGS) }, index: 0 }
unsafe { Args { iter: super::ARGS.assume_init_ref().iter() } }
}
impl fmt::Debug for Args {
@@ -25,22 +23,15 @@ impl Iterator for Args {
type Item = OsString;
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.list.len() {
return None;
}
let str = self.list.get(self.index);
self.index += 1;
let os_str = OsString::from_str(str).unwrap();
let item = self.iter.next()?;
let os_str = OsString::from_str(item).unwrap();
Some(os_str)
}
}
impl ExactSizeIterator for Args {
fn len(&self) -> usize {
self.list.len()
self.iter.len()
}
}
+7 -15
View File
@@ -37,7 +37,7 @@ pub(self) use yggdrasil_rt;
mod util;
use yggdrasil_rt::process::ExitCode as OsExitCode;
use yggdrasil_rt::process::{ExitCode as OsExitCode, ProgramArgumentInner};
use yggdrasil_rt::Error as OsError;
use crate::path::Path;
@@ -46,8 +46,9 @@ use crate::path::Path;
//
// 0x000: args pointer
// 0x008: envs pointer
static mut ARGS: usize = 0;
// static mut ARGS: usize = 0;
// TODO handle this in better way
static mut ARGS: MaybeUninit<&'static [&'static str]> = MaybeUninit::uninit();
static mut ENVS: MaybeUninit<HashMap<OsString, OsString>> = MaybeUninit::uninit();
#[doc(hidden)]
@@ -163,23 +164,14 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
}
unsafe fn init_kernel_arg(program_arg: usize) {
#[repr(C)]
struct Header {
args_ptr: usize,
envs_ptr: usize,
};
#[allow(fuzzy_provenance_casts)]
let hdr = program_arg as *const Header;
ARGS = (*hdr).args_ptr;
let env_list = util::KStringList::new((*hdr).envs_ptr);
let arg = &*(program_arg as *const ProgramArgumentInner<'static>);
ARGS.write(arg.args);
let mut envs = ENVS.write(HashMap::new());
for i in 0..env_list.len() {
let line = env_list.get(i);
let Some((key, value)) = line.split_once('=') else {
for pair in arg.env {
let Some((key, value)) = pair.split_once('=') else {
continue;
};
let key = OsString::from_str(key).unwrap();
-1
View File
@@ -6,7 +6,6 @@ use crate::io;
use crate::marker::PhantomData;
use crate::path::{Path, PathBuf};
use crate::str::FromStr;
use crate::sys::yggdrasil::util::KStringList;
use yggdrasil_rt::Error as OsError;
-45
View File
@@ -1,51 +1,6 @@
use crate::env;
use crate::mem::size_of;
use crate::path::PathBuf;
#[derive(Clone, Copy)]
pub struct KStringList {
base: usize,
len: usize,
}
impl KStringList {
pub unsafe fn new(base: usize) -> Self {
if base == 0 {
panic!("Program arguments not initialized");
}
let len = unsafe {
#[allow(fuzzy_provenance_casts)]
(base as *const usize).read()
};
Self { base, len }
}
pub fn get(&self, index: usize) -> &'static str {
assert!(index < self.len);
let len = unsafe {
#[allow(fuzzy_provenance_casts)]
(Self::item(self.base, index) as *const usize).read()
};
let ptr = unsafe {
#[allow(fuzzy_provenance_casts)]
((Self::item(self.base, index) + size_of::<usize>()) as *const *const u8).read()
};
let slice = unsafe { crate::slice::from_raw_parts(ptr, len) };
crate::str::from_utf8(slice).unwrap()
}
pub const fn len(&self) -> usize {
self.len
}
const fn item(base: usize, index: usize) -> usize {
base + (/* array len */1 + /* pair */ 2 * index) * size_of::<usize>()
}
}
pub fn resolve_binary(name: &str) -> Option<String> {
// Already an absolute path
if name.starts_with('/') {