use core::ffi::c_char;
pub const AT_NULL: usize = 0;
pub const AT_IGNORE: usize = 1;
pub const AT_EXECFD: usize = 2;
pub const AT_PHDR: usize = 3;
pub const AT_PHENT: usize = 4;
pub const AT_PHNUM: usize = 5;
pub const AT_PAGESZ: usize = 6;
pub const AT_BASE: usize = 7;
pub const AT_FLAGS: usize = 8;
pub const AT_ENTRY: usize = 9;
pub const AT_NOTELF: usize = 10;
pub const AT_UID: usize = 11;
pub const AT_EUID: usize = 12;
pub const AT_GID: usize = 13;
pub const AT_EGID: usize = 14;
pub const AT_PLATFORM: usize = 15;
pub const AT_HWCAP: usize = 16;
pub const AT_CLKTCK: usize = 17;
pub const AT_SECURE: usize = 23;
pub const AT_BASE_PLATFORM: usize = 24;
pub const AT_RANDOM: usize = 25;
pub const AT_HWCAP2: usize = 26;
pub const AT_EXECFN: usize = 31;
pub const AT_MINSIGSTKSZ: usize = 51;
pub struct EnvVars {
curr: *const *const c_char,
}
impl EnvVars {
pub unsafe fn new(start: *const *const c_char) -> Self {
Self { curr: start }
}
pub fn into_elf_aux_table(mut self) -> ElfAuxTable {
while self.next().is_some() {}
let start = unsafe { self.curr.offset(1) as *const ElfAuxEntry };
ElfAuxTable { curr: start }
}
}
impl Iterator for EnvVars {
type Item = *const c_char;
fn next(&mut self) -> Option<Self::Item> {
let entry = unsafe { *self.curr };
if entry.is_null() {
return None;
}
self.curr = unsafe { self.curr.offset(1) };
Some(entry)
}
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct ElfAuxEntry {
pub key: usize,
pub val: usize,
}
pub struct ElfAuxTable {
curr: *const ElfAuxEntry,
}
impl Iterator for ElfAuxTable {
type Item = ElfAuxEntry;
fn next(&mut self) -> Option<Self::Item> {
let entry = unsafe { *self.curr };
if entry.key == AT_NULL {
return None;
}
self.curr = unsafe { self.curr.offset(1) };
Some(entry)
}
}
#[macro_export]
macro_rules! def_start {
($user_entry:ident) => {
::core::arch::global_asm!(
"
.section .text
.global _start
_start:
mov rdi, rsp
jmp rust_start
"
);
#[no_mangle]
unsafe extern "C" fn rust_start(mut stack: *const usize) -> ! {
use ::core::ffi::c_char;
let argc = *stack;
stack = stack.offset(1);
let args = ::core::slice::from_raw_parts(stack as *const *const c_char, argc);
stack = stack.add(argc);
stack = stack.offset(1);
let env_vars = $crate::EnvVars::new(stack as *const *const c_char);
$user_entry(args, env_vars)
}
};
}