il2cpp_bridge_rs/memory/info/
symbol.rs1use dashmap::DashMap;
4use once_cell::sync::Lazy;
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8pub enum SymbolError {
10 #[error("Symbol not found: {0}")]
12 NotFound(String),
13 #[error("CString error")]
15 StringError,
16}
17
18static CACHE: Lazy<DashMap<String, usize>> = Lazy::new(DashMap::new);
19
20pub fn resolve_symbol(symbol: &str) -> Result<usize, SymbolError> {
28 if let Some(entry) = CACHE.get(symbol) {
29 return Ok(*entry);
30 }
31
32 let addr = platform::raw_resolve(symbol)?;
33 CACHE.insert(symbol.into(), addr);
34 Ok(addr)
35}
36
37pub fn cache_symbol(s: &str, a: usize) {
45 CACHE.insert(s.into(), a);
46}
47
48pub fn clear_cache() {
50 CACHE.clear();
51}
52
53#[cfg(any(target_os = "macos", target_os = "ios"))]
55mod platform {
56 use super::SymbolError;
57 use std::ffi::CString;
58
59 pub fn raw_resolve(symbol: &str) -> Result<usize, SymbolError> {
60 let c_str = CString::new(symbol).map_err(|_| SymbolError::StringError)?;
61 unsafe {
62 let addr_ptr = libc::dlsym(libc::RTLD_DEFAULT, c_str.as_ptr());
63 if addr_ptr.is_null() {
64 Err(SymbolError::NotFound(symbol.into()))
65 } else {
66 Ok(addr_ptr as usize)
67 }
68 }
69 }
70}
71
72#[cfg(any(target_os = "linux", target_os = "android"))]
74mod platform {
75 use super::SymbolError;
76 use std::ffi::CString;
77
78 pub fn raw_resolve(symbol: &str) -> Result<usize, SymbolError> {
79 let c_str = CString::new(symbol).map_err(|_| SymbolError::StringError)?;
80 unsafe {
81 let addr_ptr = libc::dlsym(libc::RTLD_DEFAULT, c_str.as_ptr());
82 if addr_ptr.is_null() {
83 Err(SymbolError::NotFound(symbol.into()))
84 } else {
85 Ok(addr_ptr as usize)
86 }
87 }
88 }
89}
90
91#[cfg(target_os = "windows")]
93mod platform {
94 use super::SymbolError;
95 use std::ffi::CString;
96 use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};
97
98 pub fn raw_resolve(symbol: &str) -> Result<usize, SymbolError> {
99 let c_str = CString::new(symbol).map_err(|_| SymbolError::StringError)?;
100 unsafe {
101 let handle = GetModuleHandleA(std::ptr::null());
103 if handle == 0 {
104 return Err(SymbolError::NotFound(symbol.into()));
105 }
106 let addr = GetProcAddress(handle, c_str.as_ptr() as *const u8);
107 match addr {
108 Some(f) => Ok(f as usize),
109 None => Err(SymbolError::NotFound(symbol.into())),
110 }
111 }
112 }
113}
114
115#[cfg(not(any(
117 target_os = "macos",
118 target_os = "ios",
119 target_os = "linux",
120 target_os = "android",
121 target_os = "windows",
122)))]
123mod platform {
124 use super::SymbolError;
125
126 pub fn raw_resolve(symbol: &str) -> Result<usize, SymbolError> {
127 Err(SymbolError::NotFound(format!(
128 "{} (unsupported platform)",
129 symbol
130 )))
131 }
132}