use std::io::Read; use std::ffi::CStr; unsafe extern "C" { fn decode_op(address: u32, op: u32, str: *mut u8, len: u32) -> i32; } fn rpcs3_dis(address: u32, code: u32) -> Option { let mut instr_str = [0u8; 128]; let res = unsafe { decode_op(address, code, instr_str.as_mut_ptr(), instr_str.len() as u32) }; if res != 0 { return None; } let cstr = unsafe { CStr::from_ptr(instr_str.as_ptr() as *const _) }; let s = cstr.to_str().expect("can unwrap"); Some(s.to_string()) } pub fn main() { let mut args = std::env::args(); args.next().expect("exists"); let hex0 = args.next().expect("byte 0"); if hex0.trim() == "-" { dis_stdin(); return; } let hex1 = args.next().expect("byte 1"); let hex2 = args.next().expect("byte 2"); let hex3 = args.next().expect("byte 3"); let bs: [u8; 4] = [ u8::from_str_radix(&hex0, 16).expect("byte 0 parses"), u8::from_str_radix(&hex1, 16).expect("byte 1 parses"), u8::from_str_radix(&hex2, 16).expect("byte 2 parses"), u8::from_str_radix(&hex3, 16).expect("byte 3 parses"), ]; dis_bytes(bs); } fn dis_stdin() { let mut buf = Vec::new(); std::io::stdin().read_to_end(&mut buf).expect("can read"); for i in 0..buf.len() / 4 { let bs: [u8; 4] = buf[i * 4..][..4].try_into().expect("four bytes"); dis_bytes(u32::from_le_bytes(bs).to_be_bytes()); } } fn dis_bytes(bs: [u8; 4]) { let word = u32::from_be_bytes(bs); if let Some(ok) = rpcs3_dis(0x00000004, word) { println!("{}", ok.as_str()); } else { println!(".long 0x{:08x}", word); } }