-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit for NIF inspection tool
- Loading branch information
Showing
6 changed files
with
269 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[target.x86_64-unknown-linux-gnu] | ||
rustflags = [ "-C", "link-args=-Wl,-export-dynamic" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "rustler_tool" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
clap = { version = "4.5", features = [ "derive" ] } | ||
libloading = "0.8" | ||
rustler_sys = { version = "2.4.0", path = "../rustler_sys" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#[no_mangle] | ||
pub static enif_alloc: usize = 0; | ||
#[no_mangle] | ||
pub static enif_alloc_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_alloc_env: usize = 0; | ||
#[no_mangle] | ||
pub static enif_binary_to_term: usize = 0; | ||
#[no_mangle] | ||
pub static enif_clear_env: usize = 0; | ||
#[no_mangle] | ||
pub static enif_compare: usize = 0; | ||
#[no_mangle] | ||
pub static enif_consume_timeslice: usize = 0; | ||
#[no_mangle] | ||
pub static enif_free: usize = 0; | ||
#[no_mangle] | ||
pub static enif_free_env: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_atom: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_atom_length: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_double: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_int: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_list_cell: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_list_length: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_local_pid: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_long: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_map_size: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_map_value: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_resource: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_tuple: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_uint: usize = 0; | ||
#[no_mangle] | ||
pub static enif_get_ulong: usize = 0; | ||
#[no_mangle] | ||
pub static enif_hash: usize = 0; | ||
#[no_mangle] | ||
pub static enif_inspect_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_inspect_iolist_as_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_atom: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_empty_list: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_fun: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_identical: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_list: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_map: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_number: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_pid: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_port: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_process_alive: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_ref: usize = 0; | ||
#[no_mangle] | ||
pub static enif_is_tuple: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_atom_len: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_badarg: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_copy: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_double: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_existing_atom_len: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_int: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_list_cell: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_list_from_array: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_long: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_map_from_arrays: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_map_put: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_map_remove: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_map_update: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_new_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_new_map: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_reverse_list: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_sub_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_tuple_from_array: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_uint: usize = 0; | ||
#[no_mangle] | ||
pub static enif_make_ulong: usize = 0; | ||
#[no_mangle] | ||
pub static enif_map_iterator_create: usize = 0; | ||
#[no_mangle] | ||
pub static enif_map_iterator_destroy: usize = 0; | ||
#[no_mangle] | ||
pub static enif_map_iterator_get_pair: usize = 0; | ||
#[no_mangle] | ||
pub static enif_map_iterator_next: usize = 0; | ||
#[no_mangle] | ||
pub static enif_map_iterator_prev: usize = 0; | ||
#[no_mangle] | ||
pub static enif_open_resource_type: usize = 0; | ||
#[no_mangle] | ||
pub static enif_raise_exception: usize = 0; | ||
#[no_mangle] | ||
pub static enif_realloc_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_release_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_schedule_nif: usize = 0; | ||
#[no_mangle] | ||
pub static enif_self: usize = 0; | ||
#[no_mangle] | ||
pub static enif_snprintf: usize = 0; | ||
#[no_mangle] | ||
pub static enif_term_to_binary: usize = 0; | ||
#[no_mangle] | ||
pub static enif_term_type: usize = 0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
mod nif; | ||
#[cfg(unix)] | ||
mod fake_symbols; | ||
|
||
use std::path::PathBuf; | ||
|
||
use clap::{Parser, Subcommand}; | ||
|
||
use crate::nif::NifLibrary; | ||
|
||
#[derive(Parser)] | ||
#[command(version, about, long_about = None)] | ||
struct Cli { | ||
#[command(subcommand)] | ||
command: Option<Commands>, | ||
} | ||
|
||
#[derive(Subcommand)] | ||
enum Commands { | ||
/// does testing things | ||
Nif { path: PathBuf }, | ||
} | ||
|
||
fn main() { | ||
let cli = Cli::parse(); | ||
|
||
match &cli.command { | ||
Some(Commands::Nif { path }) => { | ||
println!("Extracting nifs from {:?}", path); | ||
|
||
let lib = NifLibrary::load(&path).unwrap(); | ||
|
||
println!("Found library {} with nifs", lib.name); | ||
for nif in lib.nifs { | ||
println!(" {}/{}", nif.name, nif.arity); | ||
} | ||
} | ||
None => { | ||
panic!("No command given") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use libloading::{Library, Symbol}; | ||
use rustler_sys::ErlNifEntry; | ||
use std::ffi::CStr; | ||
use std::path::{Path, PathBuf}; | ||
|
||
pub struct Nif { | ||
pub name: String, | ||
pub arity: usize, | ||
pub flags: usize, | ||
} | ||
|
||
pub struct NifLibrary { | ||
pub path: PathBuf, | ||
pub name: String, | ||
pub nifs: Vec<Nif>, | ||
} | ||
|
||
#[cfg(unix)] | ||
unsafe fn maybe_call_nif_init( | ||
lib: &Library, | ||
) -> Result<*const ErlNifEntry, Box<dyn std::error::Error>> { | ||
let func: Symbol<unsafe extern "C" fn() -> *const ErlNifEntry> = lib.get(b"nif_init")?; | ||
|
||
Ok(func()) | ||
} | ||
|
||
#[cfg(windows)] | ||
unsafe fn maybe_call_nif_init( | ||
lib: &Library, | ||
) -> Result<*const ErlNifEntry, Box<dyn std::error::Error>> { | ||
use rustler_sys::TWinDynNifCallbacks; | ||
static NULL_CALLBACKS: TWinDynNifCallbacks = TWinDynNifCallbacks {}; | ||
let func: Symbol<unsafe extern "C" fn(*mut TWinDynNifCallbacks) -> *const ErlNifEntry> = | ||
lib.get(b"nif_init")?; | ||
|
||
func(&NULL_CALLBACKS) | ||
} | ||
|
||
impl NifLibrary { | ||
pub fn load(path: &Path) -> Result<NifLibrary, Box<dyn std::error::Error>> { | ||
unsafe { | ||
let lib = Library::new(&path)?; | ||
let entry = maybe_call_nif_init(&lib)?; | ||
|
||
let name = CStr::from_ptr((*entry).name).to_str()?.to_string(); | ||
let nif_array = | ||
std::slice::from_raw_parts((*entry).funcs, (*entry).num_of_funcs as usize); | ||
|
||
let nifs = nif_array | ||
.into_iter() | ||
.filter_map(|f| { | ||
Some(Nif { | ||
name: CStr::from_ptr((*f).name).to_str().ok()?.to_string(), | ||
arity: (*f).arity as usize, | ||
flags: (*f).flags as usize, | ||
}) | ||
}) | ||
.collect(); | ||
|
||
Ok(NifLibrary { | ||
path: path.to_path_buf(), | ||
name, | ||
nifs, | ||
}) | ||
} | ||
} | ||
} |