Skip to content

Commit

Permalink
adding label support inside the assembly
Browse files Browse the repository at this point in the history
adding assemble2 which supports external labels/relocations
changing debug output to use llvm::errs/nulls
  • Loading branch information
snf committed Mar 14, 2016
1 parent 04c398a commit 29668a1
Show file tree
Hide file tree
Showing 4 changed files with 342 additions and 48 deletions.
86 changes: 81 additions & 5 deletions src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,38 @@
mod extern_def {
/* automatically generated by rust-bindgen */

pub type int8_t = ::libc::c_char;
pub type int16_t = ::libc::c_short;
pub type int32_t = ::libc::c_int;
pub type int64_t = ::libc::c_long;
pub type uint8_t = ::libc::c_uchar;
pub type uint16_t = ::libc::c_ushort;
pub type uint32_t = ::libc::c_uint;
pub type uint64_t = ::libc::c_ulong;
pub type int_least8_t = ::libc::c_char;
pub type int_least16_t = ::libc::c_short;
pub type int_least32_t = ::libc::c_int;
pub type int_least64_t = ::libc::c_long;
pub type uint_least8_t = ::libc::c_uchar;
pub type uint_least16_t = ::libc::c_ushort;
pub type uint_least32_t = ::libc::c_uint;
pub type uint_least64_t = ::libc::c_ulong;
pub type int_fast8_t = ::libc::c_char;
pub type int_fast16_t = ::libc::c_long;
pub type int_fast32_t = ::libc::c_long;
pub type int_fast64_t = ::libc::c_long;
pub type uint_fast8_t = ::libc::c_uchar;
pub type uint_fast16_t = ::libc::c_ulong;
pub type uint_fast32_t = ::libc::c_ulong;
pub type uint_fast64_t = ::libc::c_ulong;
pub type intptr_t = ::libc::c_long;
pub type uintptr_t = ::libc::c_ulong;
pub type intmax_t = ::libc::c_long;
pub type uintmax_t = ::libc::c_ulong;
pub type ptrdiff_t = ::libc::c_long;
pub type size_t = ::libc::c_ulong;
pub type wchar_t = ::libc::c_int;
pub type byte = ::libc::c_uchar;
pub type byte = uint8_t;
pub type Enum_Arch = ::libc::c_uint;
pub const x86: ::libc::c_uint = 0;
pub const x86_64: ::libc::c_uint = 1;
Expand All @@ -15,11 +43,25 @@ mod extern_def {
pub const arm64: ::libc::c_uint = 4;
pub const thumb: ::libc::c_uint = 5;
pub const ppc32: ::libc::c_uint = 6;
#[link(name = "assemble")]
#[repr(C)]
#[derive(Copy)]
pub struct Struct_Unnamed1 {
pub name: *const ::libc::c_char,
pub addr: uint64_t,
}
impl ::std::clone::Clone for Struct_Unnamed1 {
fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for Struct_Unnamed1 {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type Reloc_A = Struct_Unnamed1;
extern "C" {
pub fn free_vec(vec: *mut byte) -> ();
pub fn assemble(arch: Enum_Arch, instructions: *const ::libc::c_char,
out: *mut *mut byte, out_len: *mut size_t) -> ::libc::c_int;
pub fn free_vec(vec: *mut byte);
addr: uint64_t, relocs: *const Reloc_A, n_relocs: size_t,
out: *mut *mut byte, out_len: *mut size_t)
-> ::libc::c_int;
}
}

Expand Down Expand Up @@ -48,7 +90,35 @@ impl Arch {
}
}

pub struct Reloc {
name: String,
addr: u64
}

impl Reloc {
pub fn to_c(&self) -> extern_def::Reloc_A {
use std::ffi::CString;
let c_name = CString::new(self.name.as_str()).unwrap();

extern_def::Reloc_A {
name: c_name.as_ptr(),
addr: self.addr
}
}

pub fn new(name: &str, addr: u64) -> Reloc {
Reloc { name: name.to_string(), addr: addr }
}
}

pub fn assemble(arch: Arch, input: &str) -> Option<Vec<u8>> {
assemble2(arch, input, 0x1000, &[])
}


pub fn assemble2(arch: Arch, input: &str, addr: u64, relocs: &[Reloc])
-> Option<Vec<u8>>
{
use std::ffi::CString;
use std::slice;
use std::mem;
Expand All @@ -57,13 +127,19 @@ pub fn assemble(arch: Arch, input: &str) -> Option<Vec<u8>> {
let e_arch = arch.to_c();
let ins = CString::new(input).unwrap();

let n_relocs = relocs.len();
let c_relocs: Vec<extern_def::Reloc_A> = relocs.iter().map(|r| r.to_c()).collect();
let p_relocs = c_relocs.as_ptr();

unsafe {
let mut out_len = 0;
let out_arr: *mut *mut u8 =
libc::malloc(mem::size_of::<usize>() as libc::size_t)
as *mut *mut u8;

let res = extern_def::assemble(e_arch, ins.as_ptr(), out_arr, &mut out_len);
let res = extern_def::assemble(e_arch, ins.as_ptr(),
addr, p_relocs, n_relocs as u64,
out_arr, &mut out_len);
if res == 0 {
let vec = Some(
slice::from_raw_parts(*out_arr, out_len as usize).to_vec());
Expand Down
Loading

0 comments on commit 29668a1

Please sign in to comment.