From 10b7f6d581f04b284a8308d4c1c82a59dae36a6b Mon Sep 17 00:00:00 2001 From: iximeow Date: Wed, 15 Jan 2020 20:20:55 -0800 Subject: avoid needing to dynamically allocate in yaxpeax-x86 ffi this makes ffi builds also no-std, and significantly smaller too --- ffi/src/lib.rs | 64 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index 12e077b..9d726d2 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -1,43 +1,55 @@ -use yaxpeax_arch::{Arch, Decoder, LengthedInstruction, Address}; +#![no_std] +#![feature(lang_items)] + +#[panic_handler] +#[cold] +fn panic(panic: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[lang = "eh_personality"] extern fn eh_personality() {} + +use yaxpeax_arch::{Arch, Decoder, LengthedInstruction, Address, AddressBase}; use yaxpeax_x86::x86_64; -use std::fmt::Write; +use core::fmt::Write; #[no_mangle] -pub unsafe extern "C" fn yaxpeax_decode_x86_64_optimistic(data: *const std::os::raw::c_char, length: std::os::raw::c_longlong, inst: *mut yaxpeax_x86::Instruction) -> bool { - let inst: &mut yaxpeax_x86::Instruction = std::mem::transmute(inst); - ::Decoder::default().decode_into(inst, std::slice::from_raw_parts(data as *const u8, length as usize).iter().cloned()).is_err() +pub unsafe extern "C" fn yaxpeax_decode_x86_64_optimistic(data: *const u8, length: u64, inst: *mut yaxpeax_x86::Instruction) -> bool { + let inst: &mut yaxpeax_x86::Instruction = core::mem::transmute(inst); + ::Decoder::default().decode_into(inst, core::slice::from_raw_parts(data as *const u8, length as usize).iter().cloned()).is_err() } #[no_mangle] pub unsafe extern "C" fn yaxpeax_instr_length_x86_64(inst: *mut yaxpeax_x86::Instruction) -> usize { - let inst: &mut yaxpeax_x86::Instruction = std::mem::transmute(inst); + let inst: &mut yaxpeax_x86::Instruction = core::mem::transmute(inst); inst.len().to_linear() } -#[no_mangle] -pub unsafe extern "C" fn yaxpeax_instr_fmt(inst: *mut yaxpeax_x86::Instruction, size: *mut u64, capacity: *mut u64) -> *mut u8 { - let inst: &mut yaxpeax_x86::Instruction = std::mem::transmute(inst); - let mut res = String::with_capacity(128); - - write!(res, "{}", inst).unwrap(); - - let mut bytes = res.into_bytes(); - let ptr = bytes.as_mut_ptr(); - *capacity = bytes.capacity() as u64; - *size = bytes.len() as u64; - std::mem::forget(bytes); - ptr +struct InstructionSink<'buf> { + buf: &'buf mut [u8], + offs: usize, } -#[no_mangle] -pub unsafe extern "C" fn yaxpeax_instr_x86_64_blank() -> *mut yaxpeax_x86::Instruction { - Box::leak(Box::new(yaxpeax_x86::Instruction::invalid())) +impl<'a> core::fmt::Write for InstructionSink<'a> { + fn write_str(&mut self, s: &str) -> core::fmt::Result { + for b in s.bytes() { + if self.offs < self.buf.len() { + self.buf[self.offs] = b; + self.offs += 1; + } else { + break; + } + } + + Ok(()) + } } #[no_mangle] -pub unsafe extern "C" fn yaxpeax_str_drop(data: *mut u8, size: u64, capacity: u64) { - std::mem::drop( - Vec::from_raw_parts(data, size as usize, capacity as usize) - ); +pub unsafe extern "C" fn yaxpeax_instr_fmt(inst: *mut yaxpeax_x86::Instruction, text: *mut u8, len: usize) { + let inst: &mut yaxpeax_x86::Instruction = core::mem::transmute(inst); + let mut res = core::slice::from_raw_parts_mut(text, len); + + write!(InstructionSink { buf: res, offs: 0 }, "{}", inst).unwrap(); } -- cgit v1.1