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
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![feature(panic_info_message)]
|
||||||
#![cfg_attr(not(test), no_std)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
|
|
@ -9,8 +10,13 @@ extern crate libuwuc;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
fn handler(_arg: &core::panic::PanicInfo) -> ! {
|
fn handler(arg: &core::panic::PanicInfo) -> ! {
|
||||||
libuwuc::io::println!("panic!");
|
let args = format_args!("<no message>");
|
||||||
|
let payload = arg.message().unwrap_or(&args);
|
||||||
|
libuwuc::io::println!("panicked: {payload}");
|
||||||
|
if let Some(loc) = arg.location() {
|
||||||
|
libuwuc::io::println!(" at {}:{}:{}", loc.file(), loc.line(), loc.column());
|
||||||
|
}
|
||||||
libuwuc::start::exit(1);
|
libuwuc::start::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
#![warn(unreachable_pub)]
|
||||||
|
|
||||||
mod basic_mem;
|
mod basic_mem;
|
||||||
|
mod env;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod start;
|
pub mod start;
|
||||||
mod stubs;
|
mod stubs;
|
||||||
mod sys;
|
mod sys;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
pub mod syscall {
|
pub mod syscall {
|
||||||
pub use crate::sys::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 core::ffi::{c_char, c_int};
|
||||||
|
|
||||||
|
use crate::utils::SharedThinCstr;
|
||||||
|
|
||||||
/// The entrypoint of the program.
|
/// The entrypoint of the program.
|
||||||
/// This is called by a bit of assembly handling architecture-specific _start.
|
/// This is called by a bit of assembly handling architecture-specific _start.
|
||||||
pub(crate) unsafe extern "C" fn start(
|
pub(crate) unsafe extern "C" fn start(argc: u64, argv: *const *const c_char, rsp: u64) -> ! {
|
||||||
argc: i32,
|
let envp = (8 + 8 * argc + rsp + 8) as *mut SharedThinCstr;
|
||||||
argv: *const *const c_char,
|
|
||||||
_envp: *const *const c_char,
|
crate::env::init(envp);
|
||||||
) -> ! {
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn main(argc: c_int, argv: *const *const c_char) -> c_int;
|
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);
|
exit(result as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,12 @@ core::arch::global_asm!(
|
||||||
// Pass the variables to the start function arguments.
|
// Pass the variables to the start function arguments.
|
||||||
"mov rdi, [rsp]", // &argc = rsp
|
"mov rdi, [rsp]", // &argc = rsp
|
||||||
"mov rsi, [rsp+8]", // &argv = rsp+8
|
"mov rsi, [rsp+8]", // &argv = rsp+8
|
||||||
|
"mov rdx, rsp",
|
||||||
"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
|
|
||||||
|
|
||||||
// The stack will be 16-byte aligned at process entry already.
|
// The stack will be 16-byte aligned at process entry already.
|
||||||
// So we're good to go!
|
// So we're good to go!
|
||||||
"call {start}",
|
"call {start}",
|
||||||
|
// Our start never returns, but just to be sure...
|
||||||
|
"ud2",
|
||||||
start = sym crate::start::start
|
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