mod.rs 2.8 KB

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