Pluggable formatting engine (#8)

This commit is contained in:
Richard Patel 2021-08-15 03:53:38 +02:00 committed by GitHub
parent 9e5fa58e3e
commit fb7bf08a06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 739 additions and 380 deletions

View File

@ -2,6 +2,7 @@ use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use std::time::{Duration, Instant};
use ppc750cl::formatter::SimpleFormatter;
use ppc750cl::Ins;
use std::ops::Range;
@ -95,9 +96,10 @@ impl Fuzzer {
}
fn disasm(x: u32) {
let mut devnull = DevNull;
let devnull = DevNull;
let mut formatter = SimpleFormatter { writer: devnull };
let ins = Ins::disasm(x);
ins.write_string(&mut devnull).unwrap();
ins.write_string(&mut formatter).unwrap();
}
struct DevNull;

152
lib/src/formatter.rs Normal file
View File

@ -0,0 +1,152 @@
use crate::Ins;
use num_traits::PrimInt;
use std::fmt::{LowerHex, UpperHex};
use std::io::Write;
type IOResult = std::io::Result<()>;
pub trait AsmFormatter<W>
where
W: Write,
{
fn writer(&mut self) -> &mut W;
fn before_instruction(&mut self, _: &Ins) -> IOResult {
Ok(())
}
fn after_instruction(&mut self, _: &Ins) -> IOResult {
Ok(())
}
fn write_mnemonic(&mut self, name: &str) -> IOResult {
write!(self.writer(), "{}", name)
}
fn write_opcode_separator(&mut self) -> IOResult {
write!(self.writer(), " ")
}
fn write_operand_separator(&mut self) -> IOResult {
write!(self.writer(), ", ")
}
fn write_gpr(&mut self, reg: u8) -> IOResult {
write!(self.writer(), "r{}", reg)
}
fn write_fpr(&mut self, reg: u8) -> IOResult {
write!(self.writer(), "f{}", reg)
}
fn write_cr(&mut self, reg: u8) -> IOResult {
write!(self.writer(), "cr{}", reg)
}
fn write_qr(&mut self, reg: u8) -> IOResult {
write!(self.writer(), "qr{}", reg)
}
fn write_oe(&mut self, oe: u8) -> IOResult {
if oe != 0 {
write!(self.writer(), "o")?;
}
Ok(())
}
fn write_aa(&mut self, aa: u8) -> IOResult {
if aa != 0 {
write!(self.writer(), "a")?;
}
Ok(())
}
fn write_lk(&mut self, lk: u8) -> IOResult {
if lk != 0 {
write!(self.writer(), "l")?;
}
Ok(())
}
fn write_rc(&mut self, rc: u8) -> IOResult {
if rc != 0 {
write!(self.writer(), ".")?;
}
Ok(())
}
fn write_uimm(&mut self, uimm: u16) -> IOResult {
write!(self.writer(), "{:#x}", uimm)
}
fn write_simm(&mut self, simm: i16) -> IOResult {
write!(self.writer(), "{:#x}", ReallySigned(simm))
}
fn write_fm(&mut self, fm: u16) -> IOResult {
write!(self.writer(), "{}", fm)
}
fn write_offset_unsigned_open(&mut self, offset: u16) -> IOResult {
write!(self.writer(), "{:#x}(", offset)
}
fn write_offset_open(&mut self, offset: i16) -> IOResult {
write!(self.writer(), "{:#x}(", ReallySigned(offset))
}
fn write_offset_close(&mut self) -> IOResult {
write!(self.writer(), ")")
}
}
pub struct SimpleFormatter<W: Write> {
pub writer: W,
}
impl<W: Write> AsmFormatter<W> for SimpleFormatter<W> {
fn writer(&mut self) -> &mut W {
&mut self.writer
}
}
pub struct DoldecompFormatter<W: Write> {
pub writer: W,
}
impl<W: Write> AsmFormatter<W> for DoldecompFormatter<W> {
fn writer(&mut self) -> &mut W {
&mut self.writer
}
fn before_instruction(&mut self, ins: &Ins) -> IOResult {
write!(
&mut self.writer,
"/* TODO */ {:X} {:X} {:X} {:X}\t",
(ins.code >> 24) as u8,
(ins.code >> 16) as u8,
(ins.code >> 8) as u8,
ins.code as u8
)
}
}
// https://stackoverflow.com/questions/44711012/how-do-i-format-a-signed-integer-to-a-sign-aware-hexadecimal-representation
struct ReallySigned<N: PrimInt>(N);
impl<N: PrimInt> LowerHex for ReallySigned<N> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let num = self.0.to_i32().unwrap();
let prefix = if f.alternate() { "0x" } else { "" };
let bare_hex = format!("{:x}", num.abs());
f.pad_integral(num >= 0, prefix, &bare_hex)
}
}
impl<N: PrimInt> UpperHex for ReallySigned<N> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let num = self.0.to_i32().unwrap();
let prefix = if f.alternate() { "0x" } else { "" };
let bare_hex = format!("{:X}", num.abs());
f.pad_integral(num >= 0, prefix, &bare_hex)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
use rand_core::{RngCore, SeedableRng};
use sfmt::SFMT;
use ppc750cl::formatter::SimpleFormatter;
use ppc750cl::{Ins, Opcode};
use std::io::{BufWriter, Write};
@ -8,16 +9,17 @@ fn main() {
let mut rng = SFMT::seed_from_u64(42);
let stdout = std::io::stdout();
let stdout_lock = stdout.lock();
let mut stream = BufWriter::with_capacity(1_000_000, stdout_lock);
let stream = BufWriter::with_capacity(1_000_000, stdout_lock);
let mut formatter = SimpleFormatter { writer: stream };
loop {
let ins = Ins::disasm(rng.next_u32());
if ins.op == Opcode::Illegal {
continue;
}
if ins.write_string(&mut stream).is_err() {
if ins.write_string(&mut formatter).is_err() {
return;
}
if stream.write_all("\n".as_ref()).is_err() {
if formatter.writer.write_all("\n".as_ref()).is_err() {
return;
}
}