1use std::env;
5use std::ffi::CString;
6use std::ptr;
7
8use idakit_sys::*;
9
10fn func_label(address: Address) -> String {
11 func_name(address).unwrap_or_default()
12}
13
14fn references_to(address: Address) -> Vec<(Address, i32, bool)> {
16 xrefs_build(address, true)
17 .into_iter()
18 .map(|r| (r.from, r.type_, r.iscode))
19 .collect()
20}
21
22fn main() {
23 let db = env::args()
24 .nth(1)
25 .expect("usage: bytesxref <db.i64> (a COPY; opened save=false)");
26
27 unsafe {
29 assert_eq!(init_library(0, ptr::null_mut()), 0, "init_library failed");
30 let cpath = CString::new(db).unwrap();
31 assert_eq!(
32 open_database(cpath.as_ptr(), false, ptr::null()),
33 0,
34 "open_database failed"
35 );
36 }
37
38 let nf = func_qty();
39 assert!(nf > 0, "no functions in db");
40
41 let address = func_ea(7);
43 let bytes = get_bytes(address, 16).unwrap_or_default();
44 println!("function[7] {address:#012x} {}", func_label(address));
45 print!(" first {} bytes:", bytes.len());
46 for b in &bytes {
47 print!(" {b:02x}");
48 }
49 println!();
50
51 let mut target = address;
54 let mut refs = references_to(target);
55 if refs.is_empty() {
56 for i in 0..nf {
57 let e = func_ea(i);
58 let r = references_to(e);
59 if !r.is_empty() {
60 target = e;
61 refs = r;
62 break;
63 }
64 }
65 }
66
67 println!(
68 "\nxrefs_to {target:#012x} {} (total {})",
69 func_label(target),
70 refs.len()
71 );
72 for (from, ty, iscode) in &refs {
73 let kind = if *iscode { "code" } else { "data" };
74 println!(
75 " from {from:#012x} {kind} type={ty:<2} in {}",
76 func_label(*from)
77 );
78 }
79
80 unsafe {
82 close_database(false);
83 }
84
85 println!("\nBYTESXREF OK");
86}