use core::{mem, slice};
use types::{BytesOrWideString, c_void};
use libc::{self, Dl_info};
use symbolize::ResolveWhat;
use SymbolName;
pub struct Symbol {
inner: Dl_info,
}
impl Symbol {
pub fn name(&self) -> Option<SymbolName> {
if self.inner.dli_sname.is_null() {
None
} else {
let ptr = self.inner.dli_sname as *const u8;
unsafe {
let len = libc::strlen(self.inner.dli_sname);
Some(SymbolName::new(slice::from_raw_parts(ptr, len)))
}
}
}
pub fn addr(&self) -> Option<*mut c_void> {
Some(self.inner.dli_saddr as *mut _)
}
pub fn filename_raw(&self) -> Option<BytesOrWideString> {
None
}
#[cfg(feature = "std")]
pub fn filename(&self) -> Option<&::std::path::Path> {
None
}
pub fn lineno(&self) -> Option<u32> {
None
}
}
pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) {
let addr = what.address_or_ip();
let mut info: super::Symbol = super::Symbol {
inner: Symbol {
inner: mem::zeroed(),
},
};
if libc::dladdr(addr as *mut _, &mut info.inner.inner) != 0 {
cb(&info)
}
}