mirror of
https://github.com/Noratrieb/libuwuc.git
synced 2026-01-14 11:45:05 +01:00
reading env vars
This commit is contained in:
parent
ddba35d06b
commit
0c69d7db10
7 changed files with 121 additions and 16 deletions
|
|
@ -6,3 +6,13 @@ pub(crate) unsafe extern "C" fn memset(ptr: *mut u8, constant: u8, len: usize) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub(crate) unsafe extern "C" fn strlen(mut s: *const u8) -> usize {
|
||||
let mut len = 0;
|
||||
while s.read() != 0 {
|
||||
len += 1;
|
||||
s = s.add(1);
|
||||
}
|
||||
len
|
||||
}
|
||||
|
|
|
|||
59
src/env.rs
Normal file
59
src/env.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
use core::ffi::CStr;
|
||||
|
||||
use crate::{println, utils::SharedThinCstr};
|
||||
|
||||
mod global {
|
||||
use core::cell::UnsafeCell;
|
||||
|
||||
use crate::utils::{SharedThinCstr, SyncUnsafeCell};
|
||||
|
||||
use super::EnvP;
|
||||
|
||||
static ENVP: SyncUnsafeCell<EnvP> =
|
||||
SyncUnsafeCell(UnsafeCell::new(EnvP(core::ptr::null_mut())));
|
||||
|
||||
pub(super) unsafe fn init(envp: *mut SharedThinCstr) {
|
||||
assert!((*ENVP.0.get()).0.is_null());
|
||||
*ENVP.0.get() = EnvP(envp);
|
||||
}
|
||||
|
||||
pub(super) fn get() -> EnvP {
|
||||
let ptr = unsafe { *ENVP.0.get() };
|
||||
assert!(!ptr.0.is_null());
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn init(envp: *mut SharedThinCstr) {
|
||||
global::init(envp);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct EnvP(*mut SharedThinCstr);
|
||||
|
||||
unsafe impl Sync for EnvP {}
|
||||
|
||||
impl Iterator for EnvP {
|
||||
type Item = SharedThinCstr;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
let value: SharedThinCstr = self.0.read();
|
||||
if value.0.is_null() {
|
||||
None
|
||||
} else {
|
||||
self.0 = self.0.add(1);
|
||||
Some(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn debug_env() {
|
||||
println!("start vars");
|
||||
global::get().for_each(|s| {
|
||||
let str = <&CStr>::from(s).to_str().unwrap();
|
||||
println!("{str}");
|
||||
});
|
||||
println!("end vars");
|
||||
}
|
||||
|
|
@ -2,10 +2,12 @@
|
|||
#![warn(unreachable_pub)]
|
||||
|
||||
mod basic_mem;
|
||||
mod env;
|
||||
pub mod io;
|
||||
pub mod start;
|
||||
mod stubs;
|
||||
mod sys;
|
||||
mod utils;
|
||||
|
||||
pub mod syscall {
|
||||
pub use crate::sys::syscall::*;
|
||||
|
|
|
|||
18
src/start.rs
18
src/start.rs
|
|
@ -1,18 +1,22 @@
|
|||
use core::ffi::{c_char, c_int};
|
||||
|
||||
use crate::utils::SharedThinCstr;
|
||||
|
||||
/// The entrypoint of the program.
|
||||
/// This is called by a bit of assembly handling architecture-specific _start.
|
||||
pub(crate) unsafe extern "C" fn start(
|
||||
argc: i32,
|
||||
argv: *const *const c_char,
|
||||
_envp: *const *const c_char,
|
||||
) -> ! {
|
||||
pub(crate) unsafe extern "C" fn start(argc: u64, argv: *const *const c_char, rsp: u64) -> ! {
|
||||
let envp = (8 + 8 * argc + rsp + 8) as *mut SharedThinCstr;
|
||||
|
||||
crate::env::init(envp);
|
||||
|
||||
extern "C" {
|
||||
fn main(argc: c_int, argv: *const *const c_char) -> c_int;
|
||||
}
|
||||
|
||||
let result = main(argc, argv);
|
||||
|
||||
crate::env::debug_env();
|
||||
|
||||
let result = main(argc as i32, argv);
|
||||
|
||||
exit(result as u64);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,16 +10,12 @@ core::arch::global_asm!(
|
|||
// Pass the variables to the start function arguments.
|
||||
"mov rdi, [rsp]", // &argc = rsp
|
||||
"mov rsi, [rsp+8]", // &argv = rsp+8
|
||||
|
||||
"mov rdx, rdi", // &envp = rsp+8*argc+8
|
||||
"mov rax, 8",
|
||||
"mul rdx",
|
||||
"add rdx, 8",
|
||||
"add rdx, rsp",
|
||||
"mov rdx, [rdx]", // &envp = rsp+8*argc+8
|
||||
"mov rdx, rsp",
|
||||
|
||||
// The stack will be 16-byte aligned at process entry already.
|
||||
// So we're good to go!
|
||||
"call {start}",
|
||||
// Our start never returns, but just to be sure...
|
||||
"ud2",
|
||||
start = sym crate::start::start
|
||||
);
|
||||
|
|
|
|||
28
src/utils/mod.rs
Normal file
28
src/utils/mod.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use core::{
|
||||
cell::UnsafeCell,
|
||||
ffi::{c_char, CStr},
|
||||
};
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Default)]
|
||||
pub(crate) struct SyncUnsafeCell<T>(pub(crate) UnsafeCell<T>);
|
||||
|
||||
unsafe impl<T: Sync> Sync for SyncUnsafeCell<T> {}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub(crate) struct SharedThinCstr(pub(crate) *const c_char);
|
||||
|
||||
unsafe impl Send for SharedThinCstr {}
|
||||
unsafe impl Sync for SharedThinCstr {}
|
||||
|
||||
impl From<SharedThinCstr> for &CStr {
|
||||
fn from(value: SharedThinCstr) -> Self {
|
||||
unsafe { CStr::from_ptr(value.0) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub(crate) struct SyncPtr<T>(pub(crate) *mut T);
|
||||
|
||||
unsafe impl<T> Send for SyncPtr<T> {}
|
||||
unsafe impl<T> Sync for SyncPtr<T> {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue