use std::env;
use std::ffi::CString;
use std::ptr;
use idakit_sys::*;
fn func_label(address: Address) -> String {
func_name(address).unwrap_or_default()
}
fn references_to(address: Address) -> Vec<(Address, i32, bool)> {
xrefs_build(address, true, false)
.into_iter()
.map(|r| (r.from, r.type_, r.iscode))
.collect()
}
fn main() {
let db = env::args()
.nth(1)
.expect("usage: bytesxref <db.i64> (a COPY; opened save=false)");
unsafe {
assert_eq!(init_library(0, ptr::null_mut()), 0, "init_library failed");
let cpath = CString::new(db).unwrap();
assert_eq!(
open_database(cpath.as_ptr(), false, ptr::null()),
0,
"open_database failed"
);
}
let nf = func_qty();
assert!(nf > 0, "no functions in db");
let address = func_ea(7);
let bytes = get_bytes(address, 16).unwrap_or_default();
println!("function[7] {address:#012x} {}", func_label(address));
print!(" first {} bytes:", bytes.len());
for b in &bytes {
print!(" {b:02x}");
}
println!();
let mut target = address;
let mut refs = references_to(target);
if refs.is_empty() {
for i in 0..nf {
let e = func_ea(i);
let r = references_to(e);
if !r.is_empty() {
target = e;
refs = r;
break;
}
}
}
println!(
"\nxrefs_to {target:#012x} {} (total {})",
func_label(target),
refs.len()
);
for (from, ty, iscode) in &refs {
let kind = if *iscode { "code" } else { "data" };
println!(
" from {from:#012x} {kind} type={ty:<2} in {}",
func_label(*from)
);
}
unsafe {
close_database(false);
}
println!("\nBYTESXREF OK");
}