From 501fe3ec7a63a534fca3926a5fc4267f6886f089 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Sun, 7 Dec 2025 15:03:44 -0500 Subject: [Rust] Move architecture module code into more reasonable files To keep backwards compatibility for commonly referenced code we re-export them within the architecture module. Also does some light refactoring of some newly added APIs to keep them more consistent with other parts of the codebase. --- rust/src/llvm.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 3 deletions(-) (limited to 'rust/src/llvm.rs') diff --git a/rust/src/llvm.rs b/rust/src/llvm.rs index 1296db65..d2a0292a 100644 --- a/rust/src/llvm.rs +++ b/rust/src/llvm.rs @@ -1,8 +1,102 @@ -use binaryninjacore_sys::BNLlvmServicesDisasmInstruction; +use binaryninjacore_sys::{ + BNLlvmServicesAssemble, BNLlvmServicesAssembleFree, BNLlvmServicesDisasmInstruction, + BNLlvmServicesInit, +}; use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_int}; -pub fn disas_instruction(triplet: &str, data: &[u8], address64: u64) -> Option<(usize, String)> { +#[repr(i32)] +pub enum LlvmServicesDialect { + Unspecified = 0, + Att = 1, + Intel = 2, +} + +#[repr(i32)] +pub enum LlvmServicesCodeModel { + Default = 0, + Small = 1, + Kernel = 2, + Medium = 3, + Large = 4, +} + +#[repr(i32)] +pub enum LlvmServicesRelocMode { + Static = 0, + PIC = 1, + DynamicNoPIC = 2, +} + +pub fn llvm_assemble( + code: &str, + dialect: LlvmServicesDialect, + triplet: &str, + code_model: LlvmServicesCodeModel, + reloc_mode: LlvmServicesRelocMode, +) -> Result, String> { + let code = CString::new(code).map_err(|_| "Invalid encoding in code string".to_string())?; + let arch_triple = CString::new(triplet) + .map_err(|_| "Invalid encoding in architecture triple string".to_string())?; + let mut out_bytes: *mut std::ffi::c_char = std::ptr::null_mut(); + let mut out_bytes_len: std::ffi::c_int = 0; + let mut err_bytes: *mut std::ffi::c_char = std::ptr::null_mut(); + let mut err_len: std::ffi::c_int = 0; + + unsafe { + BNLlvmServicesInit(); + } + + let result = unsafe { + BNLlvmServicesAssemble( + code.as_ptr(), + dialect as i32, + arch_triple.as_ptr(), + code_model as i32, + reloc_mode as i32, + &mut out_bytes as *mut *mut std::ffi::c_char, + &mut out_bytes_len as *mut std::ffi::c_int, + &mut err_bytes as *mut *mut std::ffi::c_char, + &mut err_len as *mut std::ffi::c_int, + ) + }; + + let out = if out_bytes_len == 0 { + Vec::new() + } else { + unsafe { + std::slice::from_raw_parts( + out_bytes as *const std::ffi::c_char as *const u8, + out_bytes_len as usize, + ) + } + .to_vec() + }; + + let errors = if err_len == 0 { + "".into() + } else { + String::from_utf8_lossy(unsafe { + std::slice::from_raw_parts( + err_bytes as *const std::ffi::c_char as *const u8, + err_len as usize, + ) + }) + .into_owned() + }; + + unsafe { + BNLlvmServicesAssembleFree(out_bytes, err_bytes); + } + + if result == 0 { + Ok(out) + } else { + Err(errors) + } +} + +pub fn llvm_disassemble(triplet: &str, data: &[u8], address: u64) -> Option<(usize, String)> { unsafe { let triplet = CString::new(triplet).ok()?; let mut src = data.to_vec(); @@ -11,7 +105,7 @@ pub fn disas_instruction(triplet: &str, data: &[u8], address64: u64) -> Option<( triplet.as_ptr(), src.as_mut_ptr(), src.len() as c_int, - address64, + address, buf.as_mut_ptr() as *mut c_char, buf.len(), ); -- cgit v1.3.1