1use crate::unix::error::ElfError;
2use crate::unix::symbol::Symbol;
3use elf::endian::AnyEndian;
4use elf::file::FileHeader;
5use elf::ElfBytes;
6use std::collections::HashMap;
7use std::ffi::OsStr;
8use std::path::PathBuf;
9use tokio::fs;
10use crate::unix::{parse_got_from_elf, parse_plt_from_elf};
11
12pub struct Elf {
13 data: Vec<u8>,
14 header: FileHeader<AnyEndian>,
15 symbols: HashMap<String, Symbol>,
16 dynamic_symbols: HashMap<String, Symbol>,
17 got: HashMap<String, u64>,
18 plt: HashMap<String, u64>,
19}
20
21impl Elf {
22 pub async fn parse<T: ?Sized + AsRef<OsStr>>(path: &T) -> Result<Elf, ElfError> {
23 let path = PathBuf::from(path);
24 let file_data = fs::read(path).await?;
25 let file = ElfBytes::<AnyEndian>::minimal_parse(file_data.as_slice())?;
26 let symbols = Symbol::parse_symbol_table(&file)?;
27 let dynamic_symbols = Symbol::parse_dynamic_symbol_table(&file)?;
28 let got = parse_got_from_elf(&file, &dynamic_symbols)?;
29 let plt = parse_plt_from_elf(&file, &dynamic_symbols)?;
30 let symbols = symbols.into_iter()
31 .map(|s| (s.name.clone(), s))
32 .collect();
33 let dynamic_symbols = dynamic_symbols.into_iter()
34 .map(|s| (s.name.clone(), s))
35 .collect();
36 let header = file.ehdr;
37 Ok(Elf {
38 data: file_data,
39 header,
40 symbols,
41 dynamic_symbols,
42 got,
43 plt,
44 })
45 }
46
47 pub fn plt(&self) -> &HashMap<String, u64>
48 {
49 &self.plt
50 }
51
52 pub fn got(&self) -> &HashMap<String, u64>
53 {
54 &self.got
55 }
56
57 pub fn symbols(&self) -> &HashMap<String, Symbol>
58 {
59 &self.symbols
60 }
61
62 pub fn dynamic_symbols(&self) -> &HashMap<String, Symbol>
63 {
64 &self.dynamic_symbols
65 }
66
67 pub fn header(&self) -> &FileHeader<AnyEndian>
68 {
69 &self.header
70 }
71
72 pub fn data(&self) -> &[u8]
73 {
74 &self.data
75 }
76}