mod.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
  2. use self::tcb::{Master, Tcb};
  3. use crate::{c_str::CStr, platform::types::*, start::Stack};
  4. pub const PAGE_SIZE: usize = 4096;
  5. pub mod debug;
  6. pub mod linker;
  7. pub mod start;
  8. pub mod tcb;
  9. pub fn static_init(sp: &'static Stack) {
  10. let mut phdr_opt = None;
  11. let mut phent_opt = None;
  12. let mut phnum_opt = None;
  13. let mut auxv = sp.auxv();
  14. loop {
  15. let (kind, value) = unsafe { *auxv };
  16. if kind == 0 {
  17. break;
  18. }
  19. match kind {
  20. 3 => phdr_opt = Some(value),
  21. 4 => phent_opt = Some(value),
  22. 5 => phnum_opt = Some(value),
  23. _ => (),
  24. }
  25. auxv = unsafe { auxv.add(1) };
  26. }
  27. let phdr = phdr_opt.expect("failed to find AT_PHDR");
  28. let phent = phent_opt.expect("failed to find AT_PHENT");
  29. let phnum = phnum_opt.expect("failed to find AT_PHNUM");
  30. for i in 0..phnum {
  31. let ph_addr = phdr + phent * i;
  32. let ph: ProgramHeader = match phent {
  33. program_header32::SIZEOF_PHDR => {
  34. unsafe { *(ph_addr as *const program_header32::ProgramHeader) }.into()
  35. }
  36. program_header64::SIZEOF_PHDR => {
  37. unsafe { *(ph_addr as *const program_header64::ProgramHeader) }.into()
  38. }
  39. _ => panic!("unknown AT_PHENT size {}", phent),
  40. };
  41. let voff = ph.p_vaddr as usize % PAGE_SIZE;
  42. let vaddr = ph.p_vaddr as usize - voff;
  43. let vsize = ((ph.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
  44. match ph.p_type {
  45. program_header::PT_TLS => {
  46. let valign = if ph.p_align > 0 {
  47. ((ph.p_memsz + (ph.p_align - 1)) / ph.p_align) * ph.p_align
  48. } else {
  49. ph.p_memsz
  50. } as usize;
  51. let tcb_master = Master {
  52. ptr: ph.p_vaddr as usize as *const u8,
  53. len: ph.p_filesz as usize,
  54. offset: vsize - valign,
  55. };
  56. unsafe {
  57. let tcb = Tcb::new(vsize).expect("failed to allocate TCB");
  58. tcb.set_masters(vec![tcb_master].into_boxed_slice());
  59. tcb.copy_masters().expect("failed to copy TLS master data");
  60. tcb.activate();
  61. }
  62. //TODO: Warning on multiple TLS sections?
  63. return;
  64. }
  65. _ => (),
  66. }
  67. }
  68. }
  69. // Wrapper over the systemcall, Do not use outside of ld_so
  70. pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
  71. let path = CStr::from_ptr(path);
  72. syscall!(ACCESS, (path).as_ptr(), mode) as c_int
  73. }
  74. #[cfg(target_os = "linux")]
  75. pub unsafe fn init(sp: &'static Stack) {
  76. let mut tp = 0usize;
  77. const ARCH_GET_FS: usize = 0x1003;
  78. syscall!(ARCH_PRCTL, ARCH_GET_FS, &mut tp as *mut usize);
  79. if tp == 0 {
  80. static_init(sp);
  81. }
  82. }
  83. #[cfg(target_os = "redox")]
  84. pub unsafe fn init(_sp: &'static Stack) {}