mirror of
https://github.com/radareorg/r2pipe.rs.git
synced 2026-11-09 04:29:32 -10:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c72b4cba60 | ||
|
|
391641f2ff |
No files matched your search
+5
-1
@@ -20,8 +20,12 @@ readme = "README.md"
|
||||
# License information
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[features]
|
||||
docsrs = []
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.81"
|
||||
libloading = "0.8"
|
||||
libc = "0.2"
|
||||
serde = "1.0.118"
|
||||
serde_json = "1.0.60"
|
||||
serde_derive = "1.0.118"
|
||||
|
||||
+19
-50
@@ -1,60 +1,29 @@
|
||||
use crate::{Error, Result};
|
||||
use libc::*;
|
||||
use crate::Result;
|
||||
use libloading::{Library, Symbol};
|
||||
use std::sync::Mutex;
|
||||
|
||||
// Contains a handle to the library.
|
||||
pub struct LibHandle(std::sync::Mutex<*mut c_void>);
|
||||
|
||||
pub fn to_cstr(s: &str) -> Result<*const c_char> {
|
||||
Ok(std::ffi::CString::new(s)
|
||||
.map_err(|_| Error::SharedLibraryLoadError)?
|
||||
.into_raw())
|
||||
}
|
||||
|
||||
pub fn free_cstr(ptr: *const c_char) {
|
||||
let _ = unsafe { std::ffi::CString::from_raw(ptr as *mut _) };
|
||||
}
|
||||
/// Contains a handle to the dynamically loaded library.
|
||||
pub struct LibHandle(Mutex<Library>);
|
||||
|
||||
impl LibHandle {
|
||||
/// Load a shared library by name with platform-specific extension.
|
||||
pub fn new(name: &str, end: Option<&str>) -> Result<LibHandle> {
|
||||
let name = to_cstr(&format!(
|
||||
"{}{}{}",
|
||||
name,
|
||||
if cfg!(windows) {
|
||||
".dll"
|
||||
} else if cfg!(macos) {
|
||||
".dylib"
|
||||
} else {
|
||||
".so"
|
||||
},
|
||||
end.unwrap_or("")
|
||||
))?;
|
||||
let ret = unsafe { dlopen(name, RTLD_LAZY) };
|
||||
free_cstr(name);
|
||||
if ret.is_null() {
|
||||
Err(Error::SharedLibraryLoadError)
|
||||
let ext = if cfg!(windows) {
|
||||
".dll"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
".dylib"
|
||||
} else {
|
||||
Ok(LibHandle(std::sync::Mutex::new(ret)))
|
||||
}
|
||||
".so"
|
||||
};
|
||||
let lib_name = format!("{}{}{}", name, ext, end.unwrap_or(""));
|
||||
let lib = unsafe { Library::new(&lib_name) }?;
|
||||
Ok(LibHandle(Mutex::new(lib)))
|
||||
}
|
||||
|
||||
/// Load a symbol from the library and transmute it to the desired type.
|
||||
pub unsafe fn load_sym<T>(&mut self, name: &str) -> Result<T> {
|
||||
let handle = *self.0.lock().unwrap();
|
||||
let name = to_cstr(name)?;
|
||||
let sym = dlsym(handle, name);
|
||||
free_cstr(name);
|
||||
if sym.is_null() {
|
||||
Err(Error::SharedLibraryLoadError)
|
||||
} else {
|
||||
Ok(std::mem::transmute_copy(&sym))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LibHandle {
|
||||
fn drop(&mut self) {
|
||||
let handle = *self.0.lock().unwrap();
|
||||
// In some cases, dlclose is not required to do anything. We allow it
|
||||
// to silently fail.
|
||||
let _ = unsafe { libc::dlclose(handle) };
|
||||
let lib = self.0.lock().unwrap();
|
||||
let sym: Symbol<T> = lib.get(name.as_bytes())?;
|
||||
Ok(std::mem::transmute_copy::<_, T>(&*sym))
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -42,6 +42,6 @@ pub enum Error {
|
||||
ChannelSendError(#[from] SendError<String>),
|
||||
|
||||
/// Error loading radare2 shared library.
|
||||
#[error("Shared library load error")]
|
||||
SharedLibraryLoadError,
|
||||
#[error("Shared library error: {0}")]
|
||||
SharedLibraryError(#[from] libloading::Error),
|
||||
}
|
||||
+1
-1
@@ -50,7 +50,7 @@
|
||||
//! The crate offers various methods to interact with r2pipe, eg. via process (multi-threadable), http or tcp.
|
||||
//! Check the examples/ dir for more complete examples.
|
||||
|
||||
#![cfg_attr(doc_cfg, feature(doc_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![doc(html_root_url = "https://radare.github.io/r2pipe.rs/")]
|
||||
|
||||
#[macro_use]
|
||||
|
||||
+10
-11
@@ -384,24 +384,23 @@ impl R2PipeNative {
|
||||
let r_core_cmd_str_handle = unsafe { lib.load_sym("r_core_cmd_str")? };
|
||||
let r_core = r_core_new();
|
||||
if r_core.is_null() {
|
||||
Err(Error::SharedLibraryLoadError)
|
||||
} else {
|
||||
let mut ret = R2PipeNative {
|
||||
lib,
|
||||
r_core: std::sync::Mutex::new(r_core),
|
||||
r_core_cmd_str_handle,
|
||||
};
|
||||
ret.cmd(&format!("o {}", file))?;
|
||||
Ok(ret)
|
||||
return Err(Error::EmptyResponse);
|
||||
}
|
||||
let mut ret = R2PipeNative {
|
||||
lib,
|
||||
r_core: std::sync::Mutex::new(r_core),
|
||||
r_core_cmd_str_handle,
|
||||
};
|
||||
ret.cmd(&format!("o {}", file))?;
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
impl Pipe for R2PipeNative {
|
||||
fn cmd(&mut self, cmd: &str) -> Result<String> {
|
||||
let r_core = *self.r_core.lock().unwrap();
|
||||
let cmd = dlfcn::to_cstr(cmd)?;
|
||||
let res = (self.r_core_cmd_str_handle)(r_core, cmd);
|
||||
let cmd = std::ffi::CString::new(cmd).map_err(|_| Error::ArgumentMismatch)?;
|
||||
let res = (self.r_core_cmd_str_handle)(r_core, cmd.as_ptr());
|
||||
if res.is_null() {
|
||||
Err(Error::EmptyResponse)
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user