elf.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. use super::{LoadInfo, ELF_MAGIC};
  2. use crate::io::UninitBuffer;
  3. use crate::kernel::task::loader::aux_vec::{AuxKey, AuxVec};
  4. use crate::path::Path;
  5. use crate::{
  6. io::ByteBuffer,
  7. kernel::{
  8. constants::ENOEXEC,
  9. mem::{FileMapping, MMList, Mapping, Permission},
  10. vfs::{dentry::Dentry, FsContext},
  11. },
  12. prelude::*,
  13. };
  14. use align_ext::AlignExt;
  15. use alloc::vec::Vec;
  16. use alloc::{ffi::CString, sync::Arc};
  17. use eonix_mm::{
  18. address::{Addr, AddrOps as _, VAddr},
  19. paging::PAGE_SIZE,
  20. };
  21. use xmas_elf::{
  22. header::{self, Class, HeaderPt1, Machine_},
  23. program::{self, ProgramHeader32, ProgramHeader64},
  24. };
  25. const INIT_STACK_SIZE: usize = 0x80_0000;
  26. #[derive(Debug, Clone, Copy)]
  27. #[repr(C)]
  28. struct HeaderPt2<P> {
  29. type_: header::Type_,
  30. machine: Machine_,
  31. version: u32,
  32. entry_point: P,
  33. ph_offset: P,
  34. sh_offset: P,
  35. flags: u32,
  36. header_size: u16,
  37. ph_entry_size: u16,
  38. ph_count: u16,
  39. sh_entry_size: u16,
  40. sh_count: u16,
  41. sh_str_index: u16,
  42. }
  43. #[derive(Debug, Clone, Copy)]
  44. #[repr(C)]
  45. struct ElfHeader<P> {
  46. pt1: HeaderPt1,
  47. pt2: HeaderPt2<P>,
  48. }
  49. pub trait ProgramHeader {
  50. fn offset(&self) -> usize;
  51. fn file_size(&self) -> usize;
  52. fn virtual_addr(&self) -> usize;
  53. fn mem_size(&self) -> usize;
  54. fn flags(&self) -> program::Flags;
  55. fn type_(&self) -> KResult<program::Type>;
  56. }
  57. macro_rules! impl_program_header {
  58. ($ProgramHeaderN:ident) => {
  59. impl ProgramHeader for $ProgramHeaderN {
  60. fn offset(&self) -> usize {
  61. self.offset as usize
  62. }
  63. fn file_size(&self) -> usize {
  64. self.file_size as usize
  65. }
  66. fn virtual_addr(&self) -> usize {
  67. self.virtual_addr as usize
  68. }
  69. fn mem_size(&self) -> usize {
  70. self.mem_size as usize
  71. }
  72. fn flags(&self) -> program::Flags {
  73. self.flags
  74. }
  75. fn type_(&self) -> KResult<program::Type> {
  76. self.get_type().map_err(|_| ENOEXEC)
  77. }
  78. }
  79. };
  80. }
  81. impl_program_header!(ProgramHeader32);
  82. impl_program_header!(ProgramHeader64);
  83. struct LdsoLoadInfo {
  84. base: VAddr,
  85. entry_ip: VAddr,
  86. }
  87. pub trait ElfAddr {
  88. type Integer;
  89. fn from_usize(val: usize) -> Self;
  90. fn into_usize(&self) -> usize;
  91. }
  92. macro_rules! impl_elf_addr {
  93. ($Type:ident) => {
  94. impl ElfAddr for $Type {
  95. type Integer = $Type;
  96. fn from_usize(val: usize) -> Self {
  97. val as Self::Integer
  98. }
  99. fn into_usize(&self) -> usize {
  100. *self as usize
  101. }
  102. }
  103. };
  104. }
  105. impl_elf_addr!(u32);
  106. impl_elf_addr!(u64);
  107. pub trait ElfArch {
  108. type Ea: ElfAddr + Clone + Copy;
  109. type Ph: ProgramHeader + Clone + Copy + Default;
  110. const DYN_BASE_ADDR: usize;
  111. const LDSO_BASE_ADDR: usize;
  112. const STACK_BASE_ADDR: usize;
  113. }
  114. pub struct ElfArch32;
  115. pub struct ElfArch64;
  116. pub struct Elf<E: ElfArch> {
  117. file: Arc<Dentry>,
  118. elf_header: ElfHeader<E::Ea>,
  119. program_headers: Vec<E::Ph>,
  120. }
  121. impl ElfArch for ElfArch32 {
  122. type Ea = u32;
  123. type Ph = ProgramHeader32;
  124. const DYN_BASE_ADDR: usize = 0x4000_0000;
  125. const LDSO_BASE_ADDR: usize = 0xf000_0000;
  126. const STACK_BASE_ADDR: usize = 0xffff_0000;
  127. }
  128. impl ElfArch for ElfArch64 {
  129. type Ea = u64;
  130. type Ph = ProgramHeader64;
  131. const DYN_BASE_ADDR: usize = 0x2aaa_0000_0000;
  132. const LDSO_BASE_ADDR: usize = 0x7000_0000_0000;
  133. const STACK_BASE_ADDR: usize = 0x7fff_ffff_0000;
  134. }
  135. impl<E: ElfArch> Elf<E> {
  136. fn is_shared_object(&self) -> bool {
  137. self.elf_header.pt2.type_.as_type() == header::Type::SharedObject
  138. }
  139. fn entry_point(&self) -> usize {
  140. self.elf_header.pt2.entry_point.into_usize()
  141. }
  142. fn ph_count(&self) -> usize {
  143. self.elf_header.pt2.ph_count as usize
  144. }
  145. fn ph_offset(&self) -> usize {
  146. self.elf_header.pt2.ph_offset.into_usize()
  147. }
  148. fn ph_entry_size(&self) -> usize {
  149. self.elf_header.pt2.ph_entry_size as usize
  150. }
  151. fn ph_addr(&self) -> KResult<usize> {
  152. let ph_offset = self.ph_offset();
  153. for program_header in &self.program_headers {
  154. if program_header.offset() <= ph_offset
  155. && ph_offset < program_header.offset() + program_header.file_size()
  156. {
  157. return Ok(ph_offset - program_header.offset() + program_header.virtual_addr());
  158. }
  159. }
  160. Err(ENOEXEC)
  161. }
  162. fn parse(elf_file: Arc<Dentry>) -> KResult<Self> {
  163. let mut elf_header = UninitBuffer::<ElfHeader<E::Ea>>::new();
  164. elf_file.read(&mut elf_header, 0)?;
  165. let elf_header = elf_header.assume_init().map_err(|_| ENOEXEC)?;
  166. let ph_offset = elf_header.pt2.ph_offset;
  167. let ph_count = elf_header.pt2.ph_count;
  168. let mut program_headers = vec![E::Ph::default(); ph_count as usize];
  169. elf_file.read(
  170. &mut ByteBuffer::from(program_headers.as_mut_slice()),
  171. ph_offset.into_usize(),
  172. )?;
  173. Ok(Self {
  174. file: elf_file,
  175. elf_header,
  176. program_headers,
  177. })
  178. }
  179. fn load(&self, args: Vec<CString>, envs: Vec<CString>) -> KResult<LoadInfo> {
  180. let mm_list = MMList::new();
  181. // Load Segments
  182. let (elf_base, data_segment_end) = self.load_segments(&mm_list)?;
  183. // Load ldso (if any)
  184. let ldso_load_info = self.load_ldso(&mm_list)?;
  185. // Load vdso
  186. self.load_vdso(&mm_list)?;
  187. // Heap
  188. mm_list.register_break(data_segment_end + 0x10000);
  189. let aux_vec = self.init_aux_vec(
  190. elf_base,
  191. ldso_load_info
  192. .as_ref()
  193. .map(|ldso_load_info| ldso_load_info.base),
  194. )?;
  195. // Map stack
  196. let sp = self.create_and_init_stack(&mm_list, args, envs, aux_vec)?;
  197. let entry_ip = if let Some(ldso_load_info) = ldso_load_info {
  198. // Normal shared object(DYN)
  199. ldso_load_info.entry_ip.into()
  200. } else if self.is_shared_object() {
  201. // ldso itself
  202. elf_base + self.entry_point()
  203. } else {
  204. // statically linked executable
  205. self.entry_point().into()
  206. };
  207. Ok(LoadInfo {
  208. entry_ip,
  209. sp,
  210. mm_list,
  211. })
  212. }
  213. fn create_and_init_stack(
  214. &self,
  215. mm_list: &MMList,
  216. args: Vec<CString>,
  217. envs: Vec<CString>,
  218. aux_vec: AuxVec<E::Ea>,
  219. ) -> KResult<VAddr> {
  220. mm_list.mmap_fixed(
  221. VAddr::from(E::STACK_BASE_ADDR - INIT_STACK_SIZE),
  222. INIT_STACK_SIZE,
  223. Mapping::Anonymous,
  224. Permission {
  225. read: true,
  226. write: true,
  227. execute: false,
  228. },
  229. )?;
  230. StackInitializer::new(&mm_list, E::STACK_BASE_ADDR, args, envs, aux_vec).init()
  231. }
  232. fn init_aux_vec(&self, elf_base: VAddr, ldso_base: Option<VAddr>) -> KResult<AuxVec<E::Ea>> {
  233. let mut aux_vec: AuxVec<E::Ea> = AuxVec::new();
  234. let ph_addr = if self.is_shared_object() {
  235. elf_base.addr() + self.ph_addr()?
  236. } else {
  237. self.ph_addr()?
  238. };
  239. aux_vec.set(AuxKey::AT_PAGESZ, E::Ea::from_usize(PAGE_SIZE))?;
  240. aux_vec.set(AuxKey::AT_PHDR, E::Ea::from_usize(ph_addr))?;
  241. aux_vec.set(AuxKey::AT_PHNUM, E::Ea::from_usize(self.ph_count()))?;
  242. aux_vec.set(AuxKey::AT_PHENT, E::Ea::from_usize(self.ph_entry_size()))?;
  243. let elf_entry = if self.is_shared_object() {
  244. elf_base.addr() + self.entry_point()
  245. } else {
  246. self.entry_point()
  247. };
  248. aux_vec.set(AuxKey::AT_ENTRY, E::Ea::from_usize(elf_entry))?;
  249. aux_vec.set(
  250. AuxKey::AT_RANDOM,
  251. E::Ea::from_usize(E::STACK_BASE_ADDR - 16),
  252. )?;
  253. if let Some(ldso_base) = ldso_base {
  254. aux_vec.set(AuxKey::AT_BASE, E::Ea::from_usize(ldso_base.addr()))?;
  255. }
  256. Ok(aux_vec)
  257. }
  258. fn load_segments(&self, mm_list: &MMList) -> KResult<(VAddr, VAddr)> {
  259. let base: VAddr = if self.is_shared_object() { E::DYN_BASE_ADDR } else { 0 }.into();
  260. let mut segments_end = VAddr::NULL;
  261. for program_header in &self.program_headers {
  262. let type_ = program_header.type_().map_err(|_| ENOEXEC)?;
  263. if type_ == program::Type::Load {
  264. let segment_end = self.load_segment(program_header, mm_list, base)?;
  265. if segment_end > segments_end {
  266. segments_end = segment_end;
  267. }
  268. }
  269. }
  270. Ok((base, segments_end))
  271. }
  272. fn load_segment(
  273. &self,
  274. program_header: &E::Ph,
  275. mm_list: &MMList,
  276. base_addr: VAddr,
  277. ) -> KResult<VAddr> {
  278. let virtual_addr = base_addr + program_header.virtual_addr();
  279. let vmem_vaddr_end = virtual_addr + program_header.mem_size();
  280. let load_vaddr_end = virtual_addr + program_header.file_size();
  281. let vmap_start = virtual_addr.floor();
  282. let vmem_len = vmem_vaddr_end.ceil() - vmap_start;
  283. let file_len = load_vaddr_end.ceil() - vmap_start;
  284. let file_offset = (program_header.offset()).align_down(PAGE_SIZE);
  285. let permission = Permission {
  286. read: program_header.flags().is_read(),
  287. write: program_header.flags().is_write(),
  288. execute: program_header.flags().is_execute(),
  289. };
  290. if file_len != 0 {
  291. let real_file_length = load_vaddr_end - vmap_start;
  292. mm_list.mmap_fixed(
  293. vmap_start,
  294. file_len,
  295. Mapping::File(FileMapping::new(
  296. self.file.clone(),
  297. file_offset,
  298. real_file_length,
  299. )),
  300. permission,
  301. )?;
  302. }
  303. if vmem_len > file_len {
  304. mm_list.mmap_fixed(
  305. vmap_start + file_len,
  306. vmem_len - file_len,
  307. Mapping::Anonymous,
  308. permission,
  309. )?;
  310. }
  311. Ok(vmap_start + vmem_len)
  312. }
  313. fn load_ldso(&self, mm_list: &MMList) -> KResult<Option<LdsoLoadInfo>> {
  314. let ldso_path = self.ldso_path()?;
  315. if let Some(ldso_path) = ldso_path {
  316. let fs_context = FsContext::global();
  317. let ldso_file = Dentry::open(fs_context, Path::new(ldso_path.as_bytes())?, true)?;
  318. let ldso_elf = Elf::<E>::parse(ldso_file)?;
  319. let base = VAddr::from(E::LDSO_BASE_ADDR);
  320. for program_header in &ldso_elf.program_headers {
  321. let type_ = program_header.type_().map_err(|_| ENOEXEC)?;
  322. if type_ == program::Type::Load {
  323. ldso_elf.load_segment(program_header, mm_list, base)?;
  324. }
  325. }
  326. return Ok(Some(LdsoLoadInfo {
  327. base,
  328. entry_ip: base + ldso_elf.entry_point() as usize,
  329. }));
  330. }
  331. Ok(None)
  332. }
  333. fn load_vdso(&self, mm_list: &MMList) -> KResult<()> {
  334. mm_list.map_vdso()
  335. }
  336. fn ldso_path(&self) -> KResult<Option<String>> {
  337. for program_header in &self.program_headers {
  338. let type_ = program_header.type_().map_err(|_| ENOEXEC)?;
  339. if type_ == program::Type::Interp {
  340. let file_size = program_header.file_size();
  341. let file_offset = program_header.offset();
  342. let mut ldso_vec = vec![0u8; file_size - 1]; // -1 due to '\0'
  343. self.file
  344. .read(&mut ByteBuffer::from(ldso_vec.as_mut_slice()), file_offset)?;
  345. let ldso_path = String::from_utf8(ldso_vec).map_err(|_| ENOEXEC)?;
  346. return Ok(Some(ldso_path));
  347. }
  348. }
  349. Ok(None)
  350. }
  351. }
  352. pub enum ELF {
  353. Elf32(Elf<ElfArch32>),
  354. Elf64(Elf<ElfArch64>),
  355. }
  356. impl ELF {
  357. pub fn parse(elf_file: Arc<Dentry>) -> KResult<Self> {
  358. let mut header_pt1 = UninitBuffer::<HeaderPt1>::new();
  359. elf_file.read(&mut header_pt1, 0)?;
  360. let header_pt1 = header_pt1.assume_init().map_err(|_| ENOEXEC)?;
  361. assert_eq!(header_pt1.magic, ELF_MAGIC);
  362. match header_pt1.class() {
  363. Class::ThirtyTwo => Ok(ELF::Elf32(Elf::parse(elf_file)?)),
  364. Class::SixtyFour => Ok(ELF::Elf64(Elf::parse(elf_file)?)),
  365. _ => Err(ENOEXEC),
  366. }
  367. }
  368. pub fn load(&self, args: Vec<CString>, envs: Vec<CString>) -> KResult<LoadInfo> {
  369. match &self {
  370. ELF::Elf32(elf32) => elf32.load(args, envs),
  371. ELF::Elf64(elf64) => elf64.load(args, envs),
  372. }
  373. }
  374. }
  375. struct StackInitializer<'a, T> {
  376. mm_list: &'a MMList,
  377. sp: usize,
  378. args: Vec<CString>,
  379. envs: Vec<CString>,
  380. aux_vec: AuxVec<T>,
  381. }
  382. impl<'a, T: ElfAddr + Clone + Copy> StackInitializer<'a, T> {
  383. fn new(
  384. mm_list: &'a MMList,
  385. sp: usize,
  386. args: Vec<CString>,
  387. envs: Vec<CString>,
  388. aux_vec: AuxVec<T>,
  389. ) -> Self {
  390. Self {
  391. mm_list,
  392. sp,
  393. args,
  394. envs,
  395. aux_vec,
  396. }
  397. }
  398. // return sp after stack init
  399. fn init(mut self) -> KResult<VAddr> {
  400. let env_pointers = self.push_envs()?;
  401. let arg_pointers = self.push_args()?;
  402. self.stack_alignment();
  403. self.push_aux_vec()?;
  404. self.push_pointers(env_pointers)?;
  405. self.push_pointers(arg_pointers)?;
  406. self.push_argc(T::from_usize(self.args.len()))?;
  407. assert_eq!(self.sp.align_down(16), self.sp);
  408. Ok(VAddr::from(self.sp))
  409. }
  410. fn push_envs(&mut self) -> KResult<Vec<T>> {
  411. let mut addrs = Vec::with_capacity(self.envs.len());
  412. for string in self.envs.iter().rev() {
  413. let len = string.as_bytes_with_nul().len();
  414. self.sp -= len;
  415. self.mm_list
  416. .access_mut(VAddr::from(self.sp), len, |offset, data| {
  417. data.copy_from_slice(&string.as_bytes_with_nul()[offset..offset + data.len()])
  418. })?;
  419. addrs.push(T::from_usize(self.sp));
  420. }
  421. addrs.reverse();
  422. Ok(addrs)
  423. }
  424. fn push_args(&mut self) -> KResult<Vec<T>> {
  425. let mut addrs = Vec::with_capacity(self.args.len());
  426. for string in self.args.iter().rev() {
  427. let len = string.as_bytes_with_nul().len();
  428. self.sp -= len;
  429. self.mm_list
  430. .access_mut(VAddr::from(self.sp), len, |offset, data| {
  431. data.copy_from_slice(&string.as_bytes_with_nul()[offset..offset + data.len()])
  432. })?;
  433. addrs.push(T::from_usize(self.sp));
  434. }
  435. addrs.reverse();
  436. Ok(addrs)
  437. }
  438. fn stack_alignment(&mut self) {
  439. let aux_vec_size = (self.aux_vec.table().len() + 1) * (size_of::<T>() * 2);
  440. let envp_pointers_size = (self.envs.len() + 1) * size_of::<T>();
  441. let argv_pointers_size = (self.args.len() + 1) * size_of::<T>();
  442. let argc_size = size_of::<T>();
  443. let all_size = aux_vec_size + envp_pointers_size + argv_pointers_size + argc_size;
  444. let align_sp = (self.sp - all_size).align_down(16);
  445. self.sp = align_sp + all_size;
  446. }
  447. fn push_pointers(&mut self, mut pointers: Vec<T>) -> KResult<()> {
  448. pointers.push(T::from_usize(0));
  449. self.sp -= pointers.len() * size_of::<T>();
  450. self.mm_list.access_mut(
  451. VAddr::from(self.sp),
  452. pointers.len() * size_of::<T>(),
  453. |offset, data| {
  454. data.copy_from_slice(unsafe {
  455. core::slice::from_raw_parts(
  456. pointers.as_ptr().byte_add(offset) as *const u8,
  457. data.len(),
  458. )
  459. })
  460. },
  461. )?;
  462. Ok(())
  463. }
  464. fn push_argc(&mut self, val: T) -> KResult<()> {
  465. self.sp -= size_of::<T>();
  466. self.mm_list
  467. .access_mut(VAddr::from(self.sp), size_of::<u32>(), |_, data| {
  468. data.copy_from_slice(unsafe {
  469. core::slice::from_raw_parts(&val as *const _ as *const u8, data.len())
  470. })
  471. })?;
  472. Ok(())
  473. }
  474. fn push_aux_vec(&mut self) -> KResult<()> {
  475. let mut longs: Vec<T> = vec![];
  476. // Write Auxiliary vectors
  477. let aux_vec: Vec<_> = self
  478. .aux_vec
  479. .table()
  480. .iter()
  481. .map(|(aux_key, aux_value)| (*aux_key, *aux_value))
  482. .collect();
  483. for (aux_key, aux_value) in aux_vec.iter() {
  484. longs.push(T::from_usize(*aux_key as usize));
  485. longs.push(*aux_value);
  486. }
  487. // Write NULL auxiliary
  488. longs.push(T::from_usize(AuxKey::AT_NULL as usize));
  489. longs.push(T::from_usize(0));
  490. self.sp -= longs.len() * size_of::<T>();
  491. self.mm_list.access_mut(
  492. VAddr::from(self.sp),
  493. longs.len() * size_of::<T>(),
  494. |offset, data| {
  495. data.copy_from_slice(unsafe {
  496. core::slice::from_raw_parts(
  497. longs.as_ptr().byte_add(offset) as *const u8,
  498. data.len(),
  499. )
  500. })
  501. },
  502. )?;
  503. Ok(())
  504. }
  505. }