nm_binutils/object/
elf.rs1use goblin::{elf, Object};
2use std::vec::Vec;
3use std::collections::HashMap;
4use crate::object::symbol::Symbol;
5
6pub struct ELF<'a> {
7 data_bytes: &'a Vec<u8>,
8 object: elf::Elf<'a>,
9}
10
11impl<'a> ELF<'a> {
12 pub fn new(data_bytes: &'a Vec<u8>) -> Self {
14 let elf = match Object::parse(&data_bytes).unwrap() {
15 Object::Elf(elf) => elf,
16 _ => unimplemented!(),
17 };
18
19 Self {
20 data_bytes,
21 object: elf
22 }
23 }
24
25 pub fn symbol_to_vec(&self) -> Vec<Symbol> {
27 let mut result = Vec::<Symbol>::new();
28 for sym in self.object.syms.iter() {
29 result.push(Symbol::new(&self.object, &sym));
30 }
31 result
32 }
33
34 pub fn symbol_to_map(&self) -> HashMap<String, Symbol> {
38 let mut result = HashMap::<String, Symbol>::new();
39
40 for sym in self.object.syms.iter() {
41 let symbol = Symbol::new(&self.object, &sym);
42 result.insert(symbol.name.to_string(), symbol);
43 }
44
45 result
46 }
47
48 pub fn get_symbol_by_name(&self, name: &str) -> Option<Symbol> {
49 for sym in self.object.syms.iter() {
50 if Symbol::name(&self.object, &sym) == name {
51 return Some(Symbol::new(&self.object, &sym));
52 }
53 }
54 None
55 }
56
57}
58
59#[cfg(test)]
60mod test {
61 use super::*;
62
63 #[test]
64 fn test_symbol_to_vec() {
65 let elf_bytes = include_bytes!("../../test/simple.amd64.elf").to_vec();
66 let elf = ELF::new(&elf_bytes);
67 for symbol in elf.symbol_to_vec() {
68 assert!(symbol.name != "main" || (symbol.address, symbol.size) == (4393, 15));
69 assert!(symbol.name != "a" || (symbol.address, symbol.size) == (4408, 11));
70 assert!(symbol.name != "b" || (symbol.address, symbol.size) == (4419, 11));
71 assert!(symbol.name != "c" || (symbol.address, symbol.size) == (4430, 11));
72 println!("{:?}", symbol);
73 }
74 }
75
76 #[test]
77 fn test_symbol_to_map() {
78 let elf_bytes = include_bytes!("../../test/simple.amd64.elf").to_vec();
79 let elf = ELF::new(&elf_bytes);
80 let symbol_map = elf.symbol_to_map();
81 {
82 let validate_sym = symbol_map.get("main").unwrap();
83 assert!((validate_sym.address, validate_sym.size) == (4393, 15));
84 }
85 {
86 let validate_sym = symbol_map.get("a").unwrap();
87 assert!((validate_sym.address, validate_sym.size) == (4408, 11));
88 }
89 {
90 let validate_sym = symbol_map.get("b").unwrap();
91 assert!((validate_sym.address, validate_sym.size) == (4419, 11));
92 }
93 {
94 let validate_sym = symbol_map.get("c").unwrap();
95 assert!((validate_sym.address, validate_sym.size) == (4430, 11));
96 }
97 }
98
99 #[test]
100 fn test_get_symbol_by_name() {
101 let elf_bytes = include_bytes!("../../test/simple.amd64.elf").to_vec();
102 let elf = ELF::new(&elf_bytes);
103 assert!(elf.get_symbol_by_name("a").is_some());
104 assert!(elf.get_symbol_by_name("d").is_none());
105 }
106}