Skip to content

Commit

Permalink
AddressInfoObtainer fully implemented on unix
Browse files Browse the repository at this point in the history
  • Loading branch information
szymonwieloch committed Aug 16, 2019
1 parent 520e2a0 commit f827185
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 34 deletions.
5 changes: 3 additions & 2 deletions examples/raw_addr_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ extern crate libc;
mod commons;

use commons::{example_lib_path};
use dlopen::raw::{Library, address_info};
use dlopen::raw::{Library, AddressInfoObtainer};
use libc::{c_int};

fn main() {
let lib_path = example_lib_path();
let lib = Library::open(&lib_path).expect("Could not open library");
let c_fun_add_two: unsafe extern "C" fn(c_int) -> c_int =
unsafe { lib.symbol("c_fun_add_two") }.unwrap();
let ai = address_info(c_fun_add_two as * const ()).unwrap();
let aio = AddressInfoObtainer::new();
let ai = aio.obtain(c_fun_add_two as * const ()).unwrap();
println!("{:?}", &ai);
assert_eq!(&ai.dll_path, lib_path.to_str().unwrap());
let os = ai.overlapping_symbol.unwrap();
Expand Down
63 changes: 39 additions & 24 deletions src/raw/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,33 +164,48 @@ pub struct AddressInfo {
pub overlapping_symbol: Option<OverlappingSymbol>
}

/**
Obtains information about an address previously loaded from a dynamic load library.
# Example
```no_run
extern crate dlopen;
use dlopen::raw::{Library, address_info};
fn main() {
let lib = Library::open("libyourlib.so").unwrap();
let ptr: * const i32 = unsafe{ lib.symbol("symbolname") }.unwrap();
// now we can obtain information about the symbol - library, base address etc.
let addr_info = address_info(ptr as * const ()).unwrap();
println!("Library path: {}", &addr_info.dll_path);
println!("Library base address: {:?}", addr_info.dll_base_addr);
if let Some(os) = addr_info.overlapping_symbol{
println!("Overlapping symbol name: {}", &os.name);
println!("Overlapping symbol address: {:?}", os.addr);
///Obtains information about an address previously loaded from a dynamic load library.
pub struct AddressInfoObtainer {
}

impl AddressInfoObtainer {
pub fn new() -> AddressInfoObtainer {
unsafe{addr_info_init()};
AddressInfoObtainer{}
}

/**
Obtains information about an address previously loaded from a dynamic load library.
# Example
```no_run
extern crate dlopen;
use dlopen::raw::{Library, AddressInfoObtainer};
fn main() {
let lib = Library::open("libyourlib.so").unwrap();
let ptr: * const i32 = unsafe{ lib.symbol("symbolname") }.unwrap();
// now we can obtain information about the symbol - library, base address etc.
let aio = AddressInfoObtainer::new();
let addr_info = aio.obtain(ptr as * const ()).unwrap();
println!("Library path: {}", &addr_info.dll_path);
println!("Library base address: {:?}", addr_info.dll_base_addr);
if let Some(os) = addr_info.overlapping_symbol{
println!("Overlapping symbol name: {}", &os.name);
println!("Overlapping symbol address: {:?}", os.addr);
}
}
```
*/
pub fn obtain(&self, addr: * const ()) -> Result<AddressInfo, Error>{
unsafe {addr_info_obtain(addr)}
}
}
```
*/
pub fn address_info(addr: * const ()) -> Result<AddressInfo, Error> {
unsafe{addr_info_init()};
unsafe{addr_info_obtain(addr)}

impl Drop for AddressInfoObtainer{
fn drop(&mut self) {
unsafe{addr_info_cleanup()}
}
}
2 changes: 1 addition & 1 deletion src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ mod windows;
#[cfg(test)]
mod tests;

pub use self::common::{Library, AddressInfo, OverlappingSymbol, address_info};
pub use self::common::{Library, AddressInfo, OverlappingSymbol, AddressInfoObtainer};
14 changes: 9 additions & 5 deletions src/raw/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,13 @@ pub unsafe fn open_lib(name: &OsStr) -> Result<Handle, Error> {
}

#[inline]
pub fn addr_info(addr: * const ()) -> Result<AddressInfo, Error>{
let mut dlinfo: Dl_info = unsafe{uninitialized()};
let result = unsafe {dladdr(addr as * const c_void, & mut dlinfo)};
pub unsafe fn addr_info_init(){}
pub unsafe fn addr_info_cleanup(){}

#[inline]
pub unsafe fn addr_info_obtain(addr: * const ()) -> Result<AddressInfo, Error>{
let mut dlinfo: Dl_info = uninitialized();
let result = dladdr(addr as * const c_void, & mut dlinfo);
if result == 0 {
Err(Error::AddrNotMatchingDll(IoError::new(ErrorKind::NotFound, String::new())))
} else {
Expand All @@ -89,11 +93,11 @@ pub fn addr_info(addr: * const ()) -> Result<AddressInfo, Error>{
} else {
Some(OverlappingSymbol{
addr: dlinfo.dli_saddr as * const (),
name: unsafe{CStr::from_ptr(dlinfo.dli_sname)}.to_string_lossy().into_owned()
name: CStr::from_ptr(dlinfo.dli_sname).to_string_lossy().into_owned()
})
};
Ok(AddressInfo{
dll_path: unsafe{CStr::from_ptr(dlinfo.dli_fname)}.to_string_lossy().into_owned(),
dll_path: CStr::from_ptr(dlinfo.dli_fname).to_string_lossy().into_owned(),
dll_base_addr: dlinfo.dli_fbase as * const (),
overlapping_symbol: os
})
Expand Down
5 changes: 3 additions & 2 deletions tests/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
extern crate const_cstr;
extern crate dlopen;
extern crate libc;
use dlopen::raw::{Library, address_info};
use dlopen::raw::{Library, AddressInfoObtainer};
use libc::{c_char, c_int};
use std::ffi::CStr;

Expand Down Expand Up @@ -64,7 +64,8 @@ fn example_address_info(){
let lib = Library::open(&lib_path).expect("Could not open library");
let c_fun_add_two: unsafe extern "C" fn(c_int) -> c_int =
unsafe { lib.symbol("c_fun_add_two") }.unwrap();
let ai = address_info(c_fun_add_two as * const ()).unwrap();
let aio = AddressInfoObtainer::new();
let ai = aio.obtain(c_fun_add_two as * const ()).unwrap();
assert_eq!(&ai.dll_path, lib_path.to_str().unwrap());
let os = ai.overlapping_symbol.unwrap();
assert_eq!(os.name, "c_fun_add_two");
Expand Down

0 comments on commit f827185

Please sign in to comment.