Skip to content

Commit

Permalink
adding initial files
Browse files Browse the repository at this point in the history
  • Loading branch information
snf committed Sep 5, 2015
1 parent 98f0dc8 commit d4cc575
Show file tree
Hide file tree
Showing 7 changed files with 590 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Cargo.lock
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "llvm_assemble"
version = "0.1.0"
authors = ["snf <[email protected]>"]
build = "build.rs"

[dependencies]
libc = "*"
68 changes: 68 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//extern crate gcc;

use std::process::Command;
use std::env;
use std::path::Path;

fn llvm_config_get(llvm_config: &str, config: &str) -> String {
let cmd = Command::new(llvm_config).arg(config).output().unwrap();
String::from_utf8(cmd.stdout).unwrap().trim().to_string()
}

fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let llvm_config = {
if let Ok(v) = env::var("LLVM_CONFIG") {
v
} else {
"/home/asdf/local/bin/llvm-config".to_string()
}
};

macro_rules! get_flags {
($arg:expr) => (
{
let llvm_flags = llvm_config_get(&llvm_config, $arg);
let llvm_flags_args: Vec<String> =
llvm_flags
.split_whitespace()
.map(|s| s.to_owned())
.collect();
llvm_flags_args
}
)
}

let llvm_cxxflags = get_flags!("--cxxflags");
let llvm_ldflags = get_flags!("--ldflags");
let llvm_libs = get_flags!("--libs");
let llvm_syslibs = get_flags!("--system-libs");

let out_obj = format!("{}/assemble.o", out_dir);
let out_lib = format!("{}/libassemble.a", out_dir);

Command::new("g++").args(&["src/c/assemble.cc", "-c", "-fPIC", "-o"])
.arg(&out_obj)
.args(&llvm_cxxflags)
.status().unwrap();

Command::new("ar").args(&["crus", &out_lib, &out_obj])
.current_dir(&Path::new(&out_dir))
.status().unwrap();

print!("cargo:rustc-flags=");
for path in llvm_ldflags {
print!("-L {} ", &path[2..]);
}
for lib in llvm_libs {
print!("-l {} ", &lib[2..]);
}
for lib in llvm_syslibs {
print!("-l {} ", &lib[2..]);
}

println!("");
println!("cargo:rustc-link-lib=dylib=stdc++");
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static={}", "assemble");
}
74 changes: 74 additions & 0 deletions src/assembler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
mod extern_def {
/* automatically generated by rust-bindgen */

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 Enum_Arch = ::libc::c_uint;
pub const x86: ::libc::c_uint = 0;
pub const x86_64: ::libc::c_uint = 1;
pub const mips: ::libc::c_uint = 2;
pub const arm: ::libc::c_uint = 3;
pub const arm64: ::libc::c_uint = 4;
pub const thumb: ::libc::c_uint = 5;
pub const ppc32: ::libc::c_uint = 6;
#[link(name = "assemble")]
extern "C" {
pub fn assemble(arch: Enum_Arch, instructions: *const ::libc::c_char,
out: *mut byte, out_len: *mut size_t) -> ::libc::c_int;
}
}

#[allow(non_camel_case_types)]
pub enum Arch {
X86,
X86_64,
Mips,
Arm,
Arm64,
Thumb,
PPC32
}

impl Arch {
pub fn to_c(self) -> u32 {
match self {
Arch::X86 => extern_def::x86,
Arch::X86_64 => extern_def::x86_64,
Arch::Mips => extern_def::mips,
Arch::Arm => extern_def::arm,
Arch::Arm64 => extern_def::arm64,
Arch::Thumb => extern_def::thumb,
Arch::PPC32 => extern_def::ppc32
}
}
}

pub fn assemble(arch: Arch, input: &str) -> Option<Vec<u8>> {
use std::ffi::CString;
use std::slice;
use libc;

let e_arch = arch.to_c();
let ins = CString::new(input).unwrap();

unsafe {
let mut out_len = 0x100;
let out_arr: *mut u8 = libc::malloc(out_len) as (*mut u8);

let res = extern_def::assemble(e_arch, ins.as_ptr(), out_arr, &mut out_len);
if res == 0 {
Some(slice::from_raw_parts(out_arr, out_len as usize).to_vec())
} else {
None
}
}
}

#[test]
fn test_assemble() {
assert_eq!(assemble(Arch::X86, "int3").unwrap(), [0xcc]);
}
Loading

0 comments on commit d4cc575

Please sign in to comment.