xref: /DragonOS/tools/debugging/logmonitor/src/backend/loader.rs (revision 7b32f5080f42bcbf7d2421013f3ea53c776a063c)
1*7b32f508SLoGin use std::{ops::Deref, path::PathBuf};
2*7b32f508SLoGin 
3*7b32f508SLoGin use goblin::elf::Sym;
4*7b32f508SLoGin use log::info;
5*7b32f508SLoGin 
6*7b32f508SLoGin use crate::app::AppResult;
7*7b32f508SLoGin 
8*7b32f508SLoGin use super::error::{BackendError, BackendErrorKind};
9*7b32f508SLoGin 
10*7b32f508SLoGin #[derive(Debug)]
11*7b32f508SLoGin pub struct KernelLoader;
12*7b32f508SLoGin 
13*7b32f508SLoGin impl KernelLoader {
load(kernel: &PathBuf) -> AppResult<KernelMetadata>14*7b32f508SLoGin     pub fn load(kernel: &PathBuf) -> AppResult<KernelMetadata> {
15*7b32f508SLoGin         info!("Loading kernel: {:?}", kernel);
16*7b32f508SLoGin         let kernel_bytes = std::fs::read(kernel)?;
17*7b32f508SLoGin         let elf = goblin::elf::Elf::parse(&kernel_bytes).map_err(|e| {
18*7b32f508SLoGin             BackendError::new(
19*7b32f508SLoGin                 BackendErrorKind::KernelLoadError,
20*7b32f508SLoGin                 Some(format!("Failed to load kernel: {:?}", e)),
21*7b32f508SLoGin             )
22*7b32f508SLoGin         })?;
23*7b32f508SLoGin         let mut result = KernelMetadata::new(kernel.clone());
24*7b32f508SLoGin 
25*7b32f508SLoGin         info!("Parsing symbols...");
26*7b32f508SLoGin         for sym in elf.syms.iter() {
27*7b32f508SLoGin             let name = elf.strtab.get_at(sym.st_name).unwrap_or("");
28*7b32f508SLoGin             result.add_symbol(sym.clone(), name.to_string());
29*7b32f508SLoGin         }
30*7b32f508SLoGin         info!("Parsed {} symbols", result.symbols().len());
31*7b32f508SLoGin         info!("Loaded kernel: {:?}", kernel);
32*7b32f508SLoGin         return Ok(result);
33*7b32f508SLoGin     }
34*7b32f508SLoGin }
35*7b32f508SLoGin 
36*7b32f508SLoGin #[derive(Debug)]
37*7b32f508SLoGin pub struct KernelMetadata {
38*7b32f508SLoGin     pub kernel: PathBuf,
39*7b32f508SLoGin     sym_collection: SymbolCollection,
40*7b32f508SLoGin }
41*7b32f508SLoGin 
42*7b32f508SLoGin impl KernelMetadata {
new(kernel: PathBuf) -> Self43*7b32f508SLoGin     pub fn new(kernel: PathBuf) -> Self {
44*7b32f508SLoGin         Self {
45*7b32f508SLoGin             kernel,
46*7b32f508SLoGin             sym_collection: SymbolCollection::new(),
47*7b32f508SLoGin         }
48*7b32f508SLoGin     }
49*7b32f508SLoGin 
symbols(&self) -> &[Symbol]50*7b32f508SLoGin     pub fn symbols(&self) -> &[Symbol] {
51*7b32f508SLoGin         &self.sym_collection.symbols
52*7b32f508SLoGin     }
53*7b32f508SLoGin 
sym_collection(&self) -> &SymbolCollection54*7b32f508SLoGin     pub fn sym_collection(&self) -> &SymbolCollection {
55*7b32f508SLoGin         &self.sym_collection
56*7b32f508SLoGin     }
57*7b32f508SLoGin 
add_symbol(&mut self, sym: Sym, name: String)58*7b32f508SLoGin     pub fn add_symbol(&mut self, sym: Sym, name: String) {
59*7b32f508SLoGin         self.sym_collection.add_symbol(sym, name);
60*7b32f508SLoGin     }
61*7b32f508SLoGin }
62*7b32f508SLoGin 
63*7b32f508SLoGin #[derive(Debug)]
64*7b32f508SLoGin pub struct SymbolCollection {
65*7b32f508SLoGin     symbols: Vec<Symbol>,
66*7b32f508SLoGin }
67*7b32f508SLoGin 
68*7b32f508SLoGin impl SymbolCollection {
new() -> Self69*7b32f508SLoGin     pub fn new() -> Self {
70*7b32f508SLoGin         Self {
71*7b32f508SLoGin             symbols: Vec::new(),
72*7b32f508SLoGin         }
73*7b32f508SLoGin     }
74*7b32f508SLoGin 
add_symbol(&mut self, sym: Sym, name: String)75*7b32f508SLoGin     pub fn add_symbol(&mut self, sym: Sym, name: String) {
76*7b32f508SLoGin         self.symbols.push(Symbol::new(sym, name));
77*7b32f508SLoGin     }
78*7b32f508SLoGin 
79*7b32f508SLoGin     #[allow(dead_code)]
len(&self) -> usize80*7b32f508SLoGin     pub fn len(&self) -> usize {
81*7b32f508SLoGin         self.symbols.len()
82*7b32f508SLoGin     }
83*7b32f508SLoGin 
find_by_name(&self, name: &str) -> Option<&Symbol>84*7b32f508SLoGin     pub fn find_by_name(&self, name: &str) -> Option<&Symbol> {
85*7b32f508SLoGin         self.symbols.iter().find(|sym| sym.name() == name)
86*7b32f508SLoGin     }
87*7b32f508SLoGin }
88*7b32f508SLoGin 
89*7b32f508SLoGin #[derive(Debug, Clone)]
90*7b32f508SLoGin pub struct Symbol {
91*7b32f508SLoGin     sym: Sym,
92*7b32f508SLoGin     name: String,
93*7b32f508SLoGin }
94*7b32f508SLoGin 
95*7b32f508SLoGin impl Symbol {
new(sym: Sym, name: String) -> Self96*7b32f508SLoGin     pub fn new(sym: Sym, name: String) -> Self {
97*7b32f508SLoGin         Self { sym, name }
98*7b32f508SLoGin     }
99*7b32f508SLoGin 
name(&self) -> &str100*7b32f508SLoGin     pub fn name(&self) -> &str {
101*7b32f508SLoGin         &self.name
102*7b32f508SLoGin     }
103*7b32f508SLoGin 
104*7b32f508SLoGin     /// Returns the virtual address of the symbol.
105*7b32f508SLoGin     #[allow(dead_code)]
vaddr(&self) -> usize106*7b32f508SLoGin     pub fn vaddr(&self) -> usize {
107*7b32f508SLoGin         self.sym.st_value as usize
108*7b32f508SLoGin     }
109*7b32f508SLoGin 
110*7b32f508SLoGin     /// Returns the offset of the symbol in the kernel memory.
memory_offset(&self) -> u64111*7b32f508SLoGin     pub fn memory_offset(&self) -> u64 {
112*7b32f508SLoGin         self.sym.st_value & (!0xffff_8000_0000_0000)
113*7b32f508SLoGin     }
114*7b32f508SLoGin }
115*7b32f508SLoGin 
116*7b32f508SLoGin impl Deref for Symbol {
117*7b32f508SLoGin     type Target = Sym;
118*7b32f508SLoGin 
deref(&self) -> &Self::Target119*7b32f508SLoGin     fn deref(&self) -> &Self::Target {
120*7b32f508SLoGin         &self.sym
121*7b32f508SLoGin     }
122*7b32f508SLoGin }
123