123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
- use self::tcb::{Master, Tcb};
- use crate::{c_str::CStr, platform::types::*, start::Stack};
- pub const PAGE_SIZE: usize = 4096;
- pub mod debug;
- pub mod linker;
- pub mod start;
- pub mod tcb;
- pub fn static_init(sp: &'static Stack) {
- let mut phdr_opt = None;
- let mut phent_opt = None;
- let mut phnum_opt = None;
- let mut auxv = sp.auxv();
- loop {
- let (kind, value) = unsafe { *auxv };
- if kind == 0 {
- break;
- }
- match kind {
- 3 => phdr_opt = Some(value),
- 4 => phent_opt = Some(value),
- 5 => phnum_opt = Some(value),
- _ => (),
- }
- auxv = unsafe { auxv.add(1) };
- }
- let phdr = phdr_opt.expect("failed to find AT_PHDR");
- let phent = phent_opt.expect("failed to find AT_PHENT");
- let phnum = phnum_opt.expect("failed to find AT_PHNUM");
- for i in 0..phnum {
- let ph_addr = phdr + phent * i;
- let ph: ProgramHeader = match phent {
- program_header32::SIZEOF_PHDR => {
- unsafe { *(ph_addr as *const program_header32::ProgramHeader) }.into()
- }
- program_header64::SIZEOF_PHDR => {
- unsafe { *(ph_addr as *const program_header64::ProgramHeader) }.into()
- }
- _ => panic!("unknown AT_PHENT size {}", phent),
- };
- let voff = ph.p_vaddr as usize % PAGE_SIZE;
- let vaddr = ph.p_vaddr as usize - voff;
- let vsize = ((ph.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
- match ph.p_type {
- program_header::PT_TLS => {
- let valign = if ph.p_align > 0 {
- ((ph.p_memsz + (ph.p_align - 1)) / ph.p_align) * ph.p_align
- } else {
- ph.p_memsz
- } as usize;
- let tcb_master = Master {
- ptr: ph.p_vaddr as usize as *const u8,
- len: ph.p_filesz as usize,
- offset: vsize - valign,
- };
- unsafe {
- let tcb = Tcb::new(vsize).expect("failed to allocate TCB");
- tcb.set_masters(vec![tcb_master].into_boxed_slice());
- tcb.copy_masters().expect("failed to copy TLS master data");
- tcb.activate();
- }
- //TODO: Warning on multiple TLS sections?
- return;
- }
- _ => (),
- }
- }
- }
- // Wrapper over the systemcall, Do not use outside of ld_so
- pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
- let path = CStr::from_ptr(path);
- syscall!(ACCESS, (path).as_ptr(), mode) as c_int
- }
- #[cfg(target_os = "linux")]
- pub unsafe fn init(sp: &'static Stack) {
- let mut tp = 0usize;
- const ARCH_GET_FS: usize = 0x1003;
- syscall!(ARCH_PRCTL, ARCH_GET_FS, &mut tp as *mut usize);
- if tp == 0 {
- static_init(sp);
- }
- }
- #[cfg(target_os = "redox")]
- pub unsafe fn init(_sp: &'static Stack) {}
|