loader.rs 2.8 KB

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