elf.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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. 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. 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. 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. struct ElfArch32;
  115. struct ElfArch64;
  116. 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 have)
  184. let ldso_load_info = self.load_ldso(&mm_list)?;
  185. // Heap
  186. mm_list.register_break(data_segment_end + 0x10000);
  187. let aux_vec = self.init_aux_vec(
  188. elf_base,
  189. ldso_load_info
  190. .as_ref()
  191. .map(|ldso_load_info| ldso_load_info.base),
  192. )?;
  193. // Map stack
  194. let sp = self.create_and_init_stack(&mm_list, args, envs, aux_vec)?;
  195. let entry_ip = if let Some(ldso_load_info) = ldso_load_info {
  196. // Normal shared object(DYN)
  197. ldso_load_info.entry_ip.into()
  198. } else if self.is_shared_object() {
  199. // ldso itself
  200. elf_base + self.entry_point()
  201. } else {
  202. // statically linked executable
  203. self.entry_point().into()
  204. };
  205. Ok(LoadInfo {
  206. entry_ip,
  207. sp,
  208. mm_list,
  209. })
  210. }
  211. fn create_and_init_stack(
  212. &self,
  213. mm_list: &MMList,
  214. args: Vec<CString>,
  215. envs: Vec<CString>,
  216. aux_vec: AuxVec<E::Ea>,
  217. ) -> KResult<VAddr> {
  218. mm_list.mmap_fixed(
  219. VAddr::from(E::STACK_BASE_ADDR - INIT_STACK_SIZE),
  220. INIT_STACK_SIZE,
  221. Mapping::Anonymous,
  222. Permission {
  223. read: true,
  224. write: true,
  225. execute: false,
  226. },
  227. )?;
  228. StackInitializer::new(&mm_list, E::STACK_BASE_ADDR, args, envs, aux_vec).init()
  229. }
  230. fn init_aux_vec(&self, elf_base: VAddr, ldso_base: Option<VAddr>) -> KResult<AuxVec<E::Ea>> {
  231. let mut aux_vec: AuxVec<E::Ea> = AuxVec::new();
  232. let ph_addr = if self.is_shared_object() {
  233. elf_base.addr() + self.ph_addr()?
  234. } else {
  235. self.ph_addr()?
  236. };
  237. aux_vec.set(AuxKey::AT_PAGESZ, E::Ea::from_usize(PAGE_SIZE))?;
  238. aux_vec.set(AuxKey::AT_PHDR, E::Ea::from_usize(ph_addr))?;
  239. aux_vec.set(AuxKey::AT_PHNUM, E::Ea::from_usize(self.ph_count()))?;
  240. aux_vec.set(AuxKey::AT_PHENT, E::Ea::from_usize(self.ph_entry_size()))?;
  241. let elf_entry = if self.is_shared_object() {
  242. elf_base.addr() + self.entry_point()
  243. } else {
  244. self.entry_point()
  245. };
  246. aux_vec.set(AuxKey::AT_ENTRY, E::Ea::from_usize(elf_entry))?;
  247. if let Some(ldso_base) = ldso_base {
  248. aux_vec.set(AuxKey::AT_BASE, E::Ea::from_usize(ldso_base.addr()))?;
  249. }
  250. Ok(aux_vec)
  251. }
  252. fn load_segments(&self, mm_list: &MMList) -> KResult<(VAddr, VAddr)> {
  253. let base: VAddr = if self.is_shared_object() { E::DYN_BASE_ADDR } else { 0 }.into();
  254. let mut segments_end = VAddr::NULL;
  255. for program_header in &self.program_headers {
  256. let type_ = program_header.type_().map_err(|_| ENOEXEC)?;
  257. if type_ == program::Type::Load {
  258. let segment_end = self.load_segment(program_header, mm_list, base)?;
  259. if segment_end > segments_end {
  260. segments_end = segment_end;
  261. }
  262. }
  263. }
  264. Ok((base, segments_end))
  265. }
  266. fn load_segment(
  267. &self,
  268. program_header: &E::Ph,
  269. mm_list: &MMList,
  270. base_addr: VAddr,
  271. ) -> KResult<VAddr> {
  272. let virtual_addr = base_addr + program_header.virtual_addr();
  273. let vmem_vaddr_end = virtual_addr + program_header.mem_size();
  274. let load_vaddr_end = virtual_addr + program_header.file_size();
  275. let vmap_start = virtual_addr.floor();
  276. let vmem_len = vmem_vaddr_end.ceil() - vmap_start;
  277. let file_len = load_vaddr_end.ceil() - vmap_start;
  278. let file_offset = (program_header.offset()).align_down(PAGE_SIZE);
  279. let permission = Permission {
  280. read: program_header.flags().is_read(),
  281. write: program_header.flags().is_write(),
  282. execute: program_header.flags().is_execute(),
  283. };
  284. if file_len != 0 {
  285. let real_file_length = load_vaddr_end - vmap_start;
  286. mm_list.mmap_fixed(
  287. vmap_start,
  288. file_len,
  289. Mapping::File(FileMapping::new(
  290. self.file.clone(),
  291. file_offset,
  292. real_file_length,
  293. )),
  294. permission,
  295. )?;
  296. }
  297. if vmem_len > file_len {
  298. mm_list.mmap_fixed(
  299. vmap_start + file_len,
  300. vmem_len - file_len,
  301. Mapping::Anonymous,
  302. permission,
  303. )?;
  304. }
  305. Ok(vmap_start + vmem_len)
  306. }
  307. fn load_ldso(&self, mm_list: &MMList) -> KResult<Option<LdsoLoadInfo>> {
  308. let ldso_path = self.ldso_path()?;
  309. if let Some(ldso_path) = ldso_path {
  310. let fs_context = FsContext::global();
  311. let ldso_file =
  312. Dentry::open(fs_context, Path::new(ldso_path.as_bytes()).unwrap(), true).unwrap();
  313. let ldso_elf = Elf::<E>::parse(ldso_file).unwrap();
  314. let base = VAddr::from(E::LDSO_BASE_ADDR);
  315. for program_header in &ldso_elf.program_headers {
  316. let type_ = program_header.type_().map_err(|_| ENOEXEC)?;
  317. if type_ == program::Type::Load {
  318. ldso_elf.load_segment(program_header, mm_list, base)?;
  319. }
  320. }
  321. return Ok(Some(LdsoLoadInfo {
  322. base,
  323. entry_ip: base + ldso_elf.entry_point() as usize,
  324. }));
  325. }
  326. Ok(None)
  327. }
  328. fn ldso_path(&self) -> KResult<Option<String>> {
  329. for program_header in &self.program_headers {
  330. let type_ = program_header.type_().map_err(|_| ENOEXEC)?;
  331. if type_ == program::Type::Interp {
  332. let file_size = program_header.file_size();
  333. let file_offset = program_header.offset();
  334. let mut ldso_vec = vec![0u8; file_size - 1]; // -1 due to '\0'
  335. self.file
  336. .read(&mut ByteBuffer::from(ldso_vec.as_mut_slice()), file_offset)?;
  337. let ldso_path = String::from_utf8(ldso_vec).map_err(|_| ENOEXEC)?;
  338. return Ok(Some(ldso_path));
  339. }
  340. }
  341. Ok(None)
  342. }
  343. }
  344. pub enum ELF {
  345. Elf32(Elf<ElfArch32>),
  346. Elf64(Elf<ElfArch64>),
  347. }
  348. impl ELF {
  349. pub fn parse(elf_file: Arc<Dentry>) -> KResult<Self> {
  350. let mut header_pt1 = UninitBuffer::<HeaderPt1>::new();
  351. elf_file.read(&mut header_pt1, 0)?;
  352. let header_pt1 = header_pt1.assume_init().map_err(|_| ENOEXEC)?;
  353. assert_eq!(header_pt1.magic, ELF_MAGIC);
  354. match header_pt1.class() {
  355. Class::ThirtyTwo => Ok(ELF::Elf32(Elf::parse(elf_file)?)),
  356. Class::SixtyFour => Ok(ELF::Elf64(Elf::parse(elf_file)?)),
  357. _ => Err(ENOEXEC),
  358. }
  359. }
  360. pub fn load(&self, args: Vec<CString>, envs: Vec<CString>) -> KResult<LoadInfo> {
  361. match &self {
  362. ELF::Elf32(elf32) => elf32.load(args, envs),
  363. ELF::Elf64(elf64) => elf64.load(args, envs),
  364. }
  365. }
  366. }
  367. struct StackInitializer<'a, T> {
  368. mm_list: &'a MMList,
  369. sp: usize,
  370. args: Vec<CString>,
  371. envs: Vec<CString>,
  372. aux_vec: AuxVec<T>,
  373. }
  374. impl<'a, T: ElfAddr + Clone + Copy> StackInitializer<'a, T> {
  375. fn new(
  376. mm_list: &'a MMList,
  377. sp: usize,
  378. args: Vec<CString>,
  379. envs: Vec<CString>,
  380. aux_vec: AuxVec<T>,
  381. ) -> Self {
  382. Self {
  383. mm_list,
  384. sp,
  385. args,
  386. envs,
  387. aux_vec,
  388. }
  389. }
  390. // return sp after stack init
  391. fn init(mut self) -> KResult<VAddr> {
  392. let env_pointers = self.push_envs()?;
  393. let arg_pointers = self.push_args()?;
  394. self.stack_alignment();
  395. self.push_aux_vec()?;
  396. self.push_pointers(env_pointers)?;
  397. self.push_pointers(arg_pointers)?;
  398. self.push_argc(T::from_usize(self.args.len()))?;
  399. assert_eq!(self.sp.align_down(16), self.sp);
  400. Ok(VAddr::from(self.sp))
  401. }
  402. fn push_envs(&mut self) -> KResult<Vec<T>> {
  403. let mut addrs = Vec::with_capacity(self.envs.len());
  404. for string in self.envs.iter().rev() {
  405. let len = string.as_bytes_with_nul().len();
  406. self.sp -= len;
  407. self.mm_list
  408. .access_mut(VAddr::from(self.sp), len, |offset, data| {
  409. data.copy_from_slice(&string.as_bytes_with_nul()[offset..offset + data.len()])
  410. })?;
  411. addrs.push(T::from_usize(self.sp));
  412. }
  413. addrs.reverse();
  414. Ok(addrs)
  415. }
  416. fn push_args(&mut self) -> KResult<Vec<T>> {
  417. let mut addrs = Vec::with_capacity(self.args.len());
  418. for string in self.args.iter().rev() {
  419. let len = string.as_bytes_with_nul().len();
  420. self.sp -= len;
  421. self.mm_list
  422. .access_mut(VAddr::from(self.sp), len, |offset, data| {
  423. data.copy_from_slice(&string.as_bytes_with_nul()[offset..offset + data.len()])
  424. })?;
  425. addrs.push(T::from_usize(self.sp));
  426. }
  427. addrs.reverse();
  428. Ok(addrs)
  429. }
  430. fn stack_alignment(&mut self) {
  431. let aux_vec_size = (self.aux_vec.table().len() + 1) * (size_of::<T>() * 2);
  432. let envp_pointers_size = (self.envs.len() + 1) * size_of::<T>();
  433. let argv_pointers_size = (self.args.len() + 1) * size_of::<T>();
  434. let argc_size = size_of::<T>();
  435. let all_size = aux_vec_size + envp_pointers_size + argv_pointers_size + argc_size;
  436. let align_sp = (self.sp - all_size).align_down(16);
  437. self.sp = align_sp + all_size;
  438. }
  439. fn push_pointers(&mut self, mut pointers: Vec<T>) -> KResult<()> {
  440. pointers.push(T::from_usize(0));
  441. self.sp -= pointers.len() * size_of::<T>();
  442. self.mm_list.access_mut(
  443. VAddr::from(self.sp),
  444. pointers.len() * size_of::<T>(),
  445. |offset, data| {
  446. data.copy_from_slice(unsafe {
  447. core::slice::from_raw_parts(
  448. pointers.as_ptr().byte_add(offset) as *const u8,
  449. data.len(),
  450. )
  451. })
  452. },
  453. )?;
  454. Ok(())
  455. }
  456. fn push_argc(&mut self, val: T) -> KResult<()> {
  457. self.sp -= size_of::<T>();
  458. self.mm_list
  459. .access_mut(VAddr::from(self.sp), size_of::<u32>(), |_, data| {
  460. data.copy_from_slice(unsafe {
  461. core::slice::from_raw_parts(&val as *const _ as *const u8, data.len())
  462. })
  463. })?;
  464. Ok(())
  465. }
  466. fn push_aux_vec(&mut self) -> KResult<()> {
  467. let mut longs: Vec<T> = vec![];
  468. // Write Auxiliary vectors
  469. let aux_vec: Vec<_> = self
  470. .aux_vec
  471. .table()
  472. .iter()
  473. .map(|(aux_key, aux_value)| (*aux_key, *aux_value))
  474. .collect();
  475. for (aux_key, aux_value) in aux_vec.iter() {
  476. longs.push(T::from_usize(*aux_key as usize));
  477. longs.push(*aux_value);
  478. }
  479. // Write NULL auxiliary
  480. longs.push(T::from_usize(AuxKey::AT_NULL as usize));
  481. longs.push(T::from_usize(0));
  482. self.sp -= longs.len() * size_of::<T>();
  483. self.mm_list.access_mut(
  484. VAddr::from(self.sp),
  485. longs.len() * size_of::<T>(),
  486. |offset, data| {
  487. data.copy_from_slice(unsafe {
  488. core::slice::from_raw_parts(
  489. longs.as_ptr().byte_add(offset) as *const u8,
  490. data.len(),
  491. )
  492. })
  493. },
  494. )?;
  495. Ok(())
  496. }
  497. }