use dashmap::DashMap;
use once_cell::sync::Lazy;
use std::ffi::CString;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum SymbolError {
#[error("Symbol not found: {0}")]
NotFound(String),
#[error("CString error")]
StringError,
}
static CACHE: Lazy<DashMap<String, usize>> = Lazy::new(DashMap::new);
pub fn resolve_symbol(symbol: &str) -> Result<usize, SymbolError> {
if let Some(entry) = CACHE.get(symbol) {
return Ok(*entry);
}
let c_str = CString::new(symbol).map_err(|_| SymbolError::StringError)?;
unsafe {
let addr_ptr = libc::dlsym(libc::RTLD_DEFAULT, c_str.as_ptr());
if addr_ptr.is_null() {
return Err(SymbolError::NotFound(symbol.into()));
}
let addr = addr_ptr as usize;
CACHE.insert(symbol.into(), addr);
Ok(addr)
}
}
pub fn cache_symbol(s: &str, a: usize) {
CACHE.insert(s.into(), a);
}
pub fn clear_cache() {
CACHE.clear();
}