minor cleanups
This commit is contained in:
parent
a9a808373b
commit
3a84b868f0
|
@ -672,7 +672,3 @@ dependencies = [
|
|||
"serde_derive",
|
||||
"yaxpeax-arch",
|
||||
]
|
||||
|
||||
[[patch.unused]]
|
||||
name = "lightning-sys"
|
||||
version = "0.2.2"
|
||||
|
|
|
@ -4,7 +4,6 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
# lightning-sys = "0.2.2"
|
||||
lightning-sys = { git = "https://github.com/petelliott/lightning-sys" }
|
||||
yaxpeax-arm = "0.1"
|
||||
yaxpeax-arch = "0.2"
|
||||
|
@ -12,8 +11,7 @@ structopt = "0.3"
|
|||
hex = "0.4"
|
||||
num-traits = "0.2"
|
||||
elf-utilities = "0.2"
|
||||
# llama = "0.9"
|
||||
syscall-numbers = "2.0"
|
||||
|
||||
[patch.crates-io]
|
||||
lightning-sys = { path = "../lightning-sys" }
|
||||
#lightning-sys = "0.2.2"
|
||||
#[patch.crates-io]
|
||||
#lightning-sys = { path = "../lightning-sys" }
|
||||
|
|
132
src/main.rs
132
src/main.rs
|
@ -13,7 +13,6 @@ use yaxpeax_arm::armv8::a64::{Opcode, Operand, SizeCode, ShiftStyle};
|
|||
use num_traits::identities::Zero;
|
||||
|
||||
use lightning_sys::{Jit, JitState, JitWord, Reg};
|
||||
use std::collections::HashMap;
|
||||
|
||||
mod _arch {
|
||||
pub use yaxpeax_arm::armv8::a64::ARMv8;
|
||||
|
@ -42,7 +41,7 @@ fn main() -> Result<()> {
|
|||
//println!("entry: {}", elf.ehdr.e_entry);
|
||||
let text_section = elf.first_section_by(|p| p.name == ".text")
|
||||
.ok_or("No .text section in ELF")?;
|
||||
println!("text_section header: {:?}", text_section.header);
|
||||
println!("text_section header: {:?}\n", text_section.header);
|
||||
if let Contents64::Raw(bytes) = &text_section.contents {
|
||||
decode_input::<_arch::ARMv8>(&bytes[..], opt.verbose);
|
||||
} else {
|
||||
|
@ -57,17 +56,13 @@ struct ExtJitState<'a> {
|
|||
reg_checkouts: [Option<Reg>; GP_REG_COUNT], // index is guest reg id
|
||||
reg_recency: Vec<(Reg, usize)>,
|
||||
regs_free: Vec<Reg>,
|
||||
stack_base: i64,
|
||||
stack_ptr: i64,
|
||||
}
|
||||
|
||||
const STACK_WORDS: usize = 64;
|
||||
// baker's 32. need a spare for ARM's barrel shifter.
|
||||
const GP_REG_COUNT: usize = 33;
|
||||
const REG_BARREL_TMP: usize = 32; // index
|
||||
impl<'a> ExtJitState<'a> {
|
||||
fn new(mut js: JitState<'a>) -> Self {
|
||||
let stack = js.allocai(size_of::<[JitWord; STACK_WORDS]>() as i32) as i64;
|
||||
let reg_storage = js.allocai(size_of::<[JitWord; GP_REG_COUNT]>() as i32) as i64;
|
||||
let reg_checkouts = [None; GP_REG_COUNT];
|
||||
let mut reg_recency = Vec::new();
|
||||
|
@ -82,26 +77,6 @@ impl<'a> ExtJitState<'a> {
|
|||
reg_checkouts,
|
||||
reg_recency,
|
||||
regs_free,
|
||||
stack_base: stack,
|
||||
stack_ptr: stack,
|
||||
}
|
||||
}
|
||||
|
||||
fn reg_from_operand(&mut self, operand: &Operand) -> Result<Reg> {
|
||||
match operand {
|
||||
Operand::RegisterOrSP(_, value)
|
||||
| Operand::Register(_, value) => self.reg(*value),
|
||||
_ => Err(format!("non-register operand: {:?}", operand).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn imm_from_operand(&self, operand: &Operand) -> Result<JitWord> {
|
||||
match operand {
|
||||
Operand::Immediate(value) => Ok((*value).into()),
|
||||
Operand::Imm64(value) => Ok(*value as JitWord),
|
||||
Operand::Imm16(value) => Ok((*value).into()),
|
||||
Operand::ImmShift(base, shift) => Ok((*base as JitWord) << shift),
|
||||
_ => Err(format!("non-immediate operand: {:?}", operand).into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,30 +116,6 @@ impl<'a> ExtJitState<'a> {
|
|||
Err("not enough host registers to support this architecture?".into())
|
||||
}
|
||||
}
|
||||
|
||||
fn push(&mut self, reg: Reg) -> Result<()> {
|
||||
let sp = self.stack_ptr;
|
||||
self.stxi(sp, Reg::FP, reg);
|
||||
self.stack_ptr += size_of::<JitWord>() as i64;
|
||||
|
||||
if self.stack_ptr > self.stack_base + size_of::<[JitWord; STACK_WORDS]>() as i64 {
|
||||
Err(format!("stack overflow trying to push {:?}", reg).into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn pop(&mut self, reg: Reg) -> Result<()> {
|
||||
self.stack_ptr -= size_of::<JitWord>() as i64;
|
||||
let sp = self.stack_ptr;
|
||||
self.ldxi(reg, Reg::FP, sp);
|
||||
|
||||
if self.stack_ptr < self.stack_base {
|
||||
Err(format!("compiler stack underflow trying to pop {:?}", reg).into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for ExtJitState<'a> {
|
||||
|
@ -181,58 +132,91 @@ impl<'a> DerefMut for ExtJitState<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
trait OperandHelpers {
|
||||
fn reg_id(&self) -> Result<usize>;
|
||||
fn immediate(&self) -> Result<JitWord>;
|
||||
}
|
||||
|
||||
impl OperandHelpers for Operand {
|
||||
fn reg_id(&self) -> Result<usize> {
|
||||
match self {
|
||||
Operand::RegisterOrSP(_, value)
|
||||
| Operand::Register(_, value) => Ok(*value as usize),
|
||||
_ => Err(format!("non-register operand: {:?}", self).into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn immediate(&self) -> Result<JitWord> {
|
||||
match self {
|
||||
Operand::Immediate(value) => Ok((*value).into()),
|
||||
Operand::Imm64(value) => Ok(*value as JitWord),
|
||||
Operand::Imm16(value) => Ok((*value).into()),
|
||||
Operand::ImmShift(base, shift) => Ok((*base as JitWord) << shift),
|
||||
_ => Err(format!("non-immediate operand: {:?}", self).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait ToLightning {
|
||||
fn translate(&self, js: &mut ExtJitState);
|
||||
fn translate(&self, js: &mut ExtJitState) -> Result<()>;
|
||||
}
|
||||
|
||||
impl ToLightning for _arch::ARMv8_Instr {
|
||||
fn translate(&self, js: &mut ExtJitState) {
|
||||
fn translate(&self, js: &mut ExtJitState) -> Result<()> {
|
||||
let _arch::ARMv8_Instr { opcode, operands } = self;
|
||||
match opcode {
|
||||
Opcode::Invalid => { panic!("Invalid ARMv8 instruction: {:?}", self); }
|
||||
Opcode::Invalid => return Err(format!("Invalid ARMv8 instruction: {:?}", self).into()),
|
||||
Opcode::MOVZ => {
|
||||
let [dest, src, _, _] = operands;
|
||||
let dest = js.reg_from_operand(dest).expect("dest");
|
||||
let src = js.imm_from_operand(src).expect("src");
|
||||
js.movi(dest, src);
|
||||
let [dest_orig, src, _, _] = operands;
|
||||
match dest_orig {
|
||||
Operand::Register(size, id)
|
||||
| Operand::RegisterOrSP(size, id) => {
|
||||
let dest = js.reg(*id)?;
|
||||
js.movi(dest, src.immediate()?);
|
||||
if *size == SizeCode::W {
|
||||
js.extr_i(dest, dest);
|
||||
}
|
||||
}
|
||||
_ => return Err(format!("Invalid target for MOVZ: {:?}", dest_orig).into()),
|
||||
}
|
||||
}
|
||||
Opcode::ADD => {
|
||||
let [dest_orig, src1_orig, src2_orig, _] = operands;
|
||||
let src1 = js.reg_from_operand(src1_orig).expect("src1");
|
||||
let src1 = js.reg(src1_orig.reg_id()?)?;
|
||||
// we decode dest last for correctness in super-scarce register situations where
|
||||
// our register LRU cache may need to evict a jit register for it.
|
||||
// we return it from this match statement for later sign-extension in 32-bit ops.
|
||||
let dest = match src2_orig {
|
||||
Operand::Register(_, id)
|
||||
| Operand::RegisterOrSP(_, id) => {
|
||||
let src2 = js.reg(*id).expect("src2");
|
||||
let dest = js.reg_from_operand(dest_orig).expect("dest");
|
||||
let src2 = js.reg(*id)?;
|
||||
let dest = js.reg(dest_orig.reg_id()?)?;
|
||||
js.addr(dest, src1, src2);
|
||||
dest
|
||||
}
|
||||
Operand::RegShift(shift_style, shift, _, id) => {
|
||||
let src2 = js.reg(*id).expect("src2");
|
||||
let src2_tmp = js.reg(REG_BARREL_TMP).expect("src2_tmp");
|
||||
let src2 = js.reg(*id)?;
|
||||
let src2_tmp = js.reg(REG_BARREL_TMP)?;
|
||||
match shift_style {
|
||||
ShiftStyle::LSL => js.lshi(src2_tmp, src2, (*shift).into()),
|
||||
ShiftStyle::LSR => js.rshi_u(src2_tmp, src2, (*shift).into()),
|
||||
ShiftStyle::ASR => js.rshi(src2_tmp, src2, (*shift).into()),
|
||||
_ => panic!("invalid shift style for ADD"),
|
||||
_ => return Err(format!("invalid shift style for ADD").into()),
|
||||
};
|
||||
let dest = js.reg_from_operand(dest_orig).expect("dest");
|
||||
let dest = js.reg(dest_orig.reg_id()?)?;
|
||||
js.addr(dest, src1, src2_tmp);
|
||||
dest
|
||||
}
|
||||
Operand::Immediate(_)
|
||||
| Operand::Imm64(_)
|
||||
| Operand::Imm16(_)
|
||||
Operand::Immediate(..)
|
||||
| Operand::Imm64(..)
|
||||
| Operand::Imm16(..)
|
||||
| Operand::ImmShift(..) => {
|
||||
let src2 = js.imm_from_operand(src2_orig).expect("src2");
|
||||
let dest = js.reg_from_operand(dest_orig).expect("dest");
|
||||
let src2 = src2_orig.immediate()?;
|
||||
let dest = js.reg(dest_orig.reg_id()?)?;
|
||||
js.addi(dest, src1, src2);
|
||||
dest
|
||||
}
|
||||
_ => { panic!("Invalid second operand to ADD: {:?}", src2_orig); }
|
||||
_ => return Err(format!("Invalid second operand to ADD: {:?}", src2_orig).into()),
|
||||
};
|
||||
|
||||
// sign-extend if it's a 32-bit operation
|
||||
|
@ -354,7 +338,7 @@ impl ToLightning for _arch::ARMv8_Instr {
|
|||
Opcode::PACIA => {}
|
||||
Opcode::PACIZA => {}
|
||||
}
|
||||
()
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,9 +368,9 @@ where
|
|||
let mut reader = U8Reader::new(&buf[addr.to_linear()..]);
|
||||
match decoder.decode(&mut reader) {
|
||||
Ok(inst) => {
|
||||
inst.translate(&mut ejs);
|
||||
inst.translate(&mut ejs).unwrap();
|
||||
println!(
|
||||
"{:#010x}: {:14}: {}",
|
||||
"{:#06x}: {:8}: {}",
|
||||
addr.to_linear(),
|
||||
hex::encode(
|
||||
&buf[addr.to_linear()..]
|
||||
|
@ -417,5 +401,5 @@ where
|
|||
let code: extern fn() -> JitWord = unsafe { ejs.cast_emit() };
|
||||
ejs.clear_state();
|
||||
|
||||
println!("exit code of jit: {}", code());
|
||||
println!("\nreturn value of jit execution: {}", code());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue