diff --git a/crates/molotov-core/src/dynamic.rs b/crates/molotov-core/src/dynamic.rs new file mode 100644 index 0000000..6063992 --- /dev/null +++ b/crates/molotov-core/src/dynamic.rs @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub struct ElfSymbol { + pub name_offset: u32, + pub info: u8, + pub other: u8, + pub shndx: u16, + pub value: u64, + pub size: u64, +} + +#[derive(Debug, Clone, Default)] +pub struct DynamicSection<'a> { + pub strtab: &'a [u8], + pub symbols: Vec, + pub name_to_index: HashMap, +} + +impl<'a> DynamicSection<'a> { + pub fn new_with_strtab(strtab: &'a [u8]) -> Self { + Self { + strtab, + symbols: Vec::new(), + name_to_index: HashMap::new(), + } + } + + pub fn lookup_string(&self, offset: usize) -> Option<&'a str> { + if offset >= self.strtab.len() { + return None; + } + + let slice = &self.strtab[offset..]; + let null_pos = slice.iter().position(|&b| b == 0)?; + std::str::from_utf8(&slice[..null_pos]).ok() + } + + pub fn register_symbol(&mut self, sym: ElfSymbol) { + if let Some(name) = self.lookup_string(sym.name_offset as usize) { + self.name_to_index.insert(name.to_string(), self.symbols.len()); + } + self.symbols.push(sym); + } + + pub fn find_symbol(&self, name: &str) -> Option<&ElfSymbol> { + let idx = self.name_to_index.get(name)?; + self.symbols.get(*idx) + } +} diff --git a/crates/molotov-core/src/lib.rs b/crates/molotov-core/src/lib.rs index 4e6eb81..3c8563b 100644 --- a/crates/molotov-core/src/lib.rs +++ b/crates/molotov-core/src/lib.rs @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later +pub mod dynamic; pub mod elf; pub mod mmap; pub mod symbols; diff --git a/crates/molotov-core/tests/dynamic_test.rs b/crates/molotov-core/tests/dynamic_test.rs new file mode 100644 index 0000000..d2af14c --- /dev/null +++ b/crates/molotov-core/tests/dynamic_test.rs @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +use molotov_core::dynamic::DynamicSection; + +#[test] +fn test_string_table_lookup() { + let strtab = b"\0JNI_OnLoad\0ANativeActivity_onCreate\0"; + let dynamic = DynamicSection::new_with_strtab(strtab); + + assert_eq!(dynamic.lookup_string(1), Some("JNI_OnLoad")); + assert_eq!(dynamic.lookup_string(12), Some("ANativeActivity_onCreate")); + assert_eq!(dynamic.lookup_string(999), None); +}