Skip to content

Commit

Permalink
Start Disassembler
Browse files Browse the repository at this point in the history
  • Loading branch information
chorman0773 committed Sep 23, 2022
1 parent 6bc76c6 commit 42a6d19
Show file tree
Hide file tree
Showing 14 changed files with 211 additions and 21 deletions.
123 changes: 108 additions & 15 deletions arch-ops/src/clever.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
};

use crate::traits::{Address, InsnRead, InsnWrite, RelocCode, Reloc};
use crate::{traits::{Address, InsnRead, InsnWrite, RelocCode, Reloc}, disasm::OpcodePrinter};

#[derive(Debug)]
pub struct CleverExtensionFromStrError;
Expand Down Expand Up @@ -963,6 +963,27 @@ macro_rules! gpr_specializations{
_ => None
}
}

pub fn is_gpr_left_spec(&self) -> bool{
match self{
$(Self::$left_spec {..} => {true},)*
_ => false
}
}
pub fn is_gpr_right_spec(&self) -> bool{
match self{
$($(Self::$right_spec {..} => {true},)?)*
_ => false
}
}

pub fn get_spec_register(&self) -> Option<CleverRegister>{
match self{
$(Self::$left_spec {r} => {Some(*r)},)*
$($(Self::$right_spec {r} => {Some(*r)},)?)*
_ => None
}
}
}
}
}
Expand Down Expand Up @@ -996,6 +1017,28 @@ macro_rules! nop_instructions{

nop_instructions!(NOP0: Nop10, NOP1: Nop11, NOP2: Nop12, NOP3: Nop13);


macro_rules! print_h_field{
[$(($enum:ident {$($h:pat,)* $(, ..)?} => |$fmt:pat| $e:expr)),* $(,)?] => {
impl core::fmt::Display for CleverOpcode{
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result{
f.write_str(self.name())?;

match self{
$(Self:: $enum {$($h,)* ..} => (match f{
$fmt => $e
}),)*
_ => Ok(())
}
}
}
}
}

print_h_field![

];

impl CleverOpcode {
pub fn is_branch(&self) -> bool {
(self.opcode() < 0xFD80) && (self.opcode() & 0x7200 == 0x7000)
Expand Down Expand Up @@ -1451,6 +1494,57 @@ impl CleverInstruction {
}
}

impl core::fmt::Display for CleverInstruction{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.opcode().fmt(f)?;

match self.opcode().operands(){
CleverOperandKind::Size => {
let ss = self.opcode().opcode()&0x3;
match ss{
0 => f.write_str(" byte")?,
1 => f.write_str(" half")?,
2 => f.write_str(" single")?,
3 => f.write_str(" double")?,
_ => unreachable!()
}
}
CleverOperandKind::HImmediate => {
let h = self.opcode().opcode()&0xf;
f.write_str(" ")?;
h.fmt(f)?;
}
CleverOperandKind::HRegister => {
let h = self.opcode().opcode()&0xf;
let r = CleverRegister(h as u8);
f.write_str(" ")?;
r.fmt(f)?;
}
_ => {
let mut sep = " ";

if self.opcode().is_gpr_left_spec(){
sep = ", ";
f.write_str(" ")?;
self.opcode().get_spec_register().unwrap().fmt(f)?;
}
for opr in self.operands(){
f.write_str(sep)?;
sep = ", ";
opr.fmt(f)?;
}
if self.opcode().is_gpr_right_spec(){
f.write_str(sep)?;
self.opcode().get_spec_register().unwrap().fmt(f)?;
}
}
}


Ok(())
}
}

pub struct CleverEncoder<W> {
inner: W,
}
Expand Down Expand Up @@ -1817,25 +1911,24 @@ impl<R: InsnRead> CleverDecoder<R> {
}
}

pub struct CleverPrinter<W> {
inner: W,
#[non_exhaustive]
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct CleverPrinter{

}

impl<W> CleverPrinter<W> {
pub const fn new(inner: W) -> Self {
Self { inner }
impl CleverPrinter{
pub fn new() -> Self{
Self{}
}
}

pub fn into_inner(self) -> W {
self.inner
}
impl OpcodePrinter for CleverPrinter{
fn print_opcode(&self, f: &mut core::fmt::Formatter, read: &mut dyn InsnRead) -> std::io::Result<()> {
let insn = CleverDecoder::new(read).read_insn()?;

pub fn inner(&self) -> &W {
&self.inner
}

pub fn inner_mut(&mut self) -> &mut W {
&mut self.inner
<CleverInstruction as core::fmt::Display>::fmt(&insn,f).unwrap();
Ok(())
}
}

Expand Down
10 changes: 10 additions & 0 deletions arch-ops/src/disasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::traits::InsnRead;


pub trait OpcodePrinter{
fn print_opcode(&self, f: &mut core::fmt::Formatter, read: &mut dyn InsnRead) -> std::io::Result<()>;

fn handle_option(&mut self, _key: &str, _value: &str) -> bool{
false
}
}
4 changes: 4 additions & 0 deletions arch-ops/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

pub mod traits;


pub mod disasm;

#[cfg(feature = "w65")]
pub mod w65;

Expand All @@ -17,3 +20,4 @@ pub mod clever;

#[cfg(test)]
pub(crate) mod test;

9 changes: 9 additions & 0 deletions binfmt/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::io::{ErrorKind, SeekFrom};
use std::marker::PhantomData;
use std::mem::size_of;

use arch_ops::disasm::OpcodePrinter;
use bytemuck::{Pod, Zeroable};

use crate::debug::PrintHex;
Expand Down Expand Up @@ -886,6 +887,7 @@ pub struct ElfFormat<Class: ElfClass, Howto> {
name: &'static str,
_cl: PhantomData<Class>,
_howto: PhantomData<fn() -> Howto>,
disassembler: Option<Box<dyn OpcodePrinter + Sync + Send>>
}

impl<Class: ElfClass, Howto> ElfFormat<Class, Howto> {
Expand All @@ -894,12 +896,14 @@ impl<Class: ElfClass, Howto> ElfFormat<Class, Howto> {
data: consts::EiData,
name: &'static str,
create_header: Option<fn(&mut ElfHeader<Class>)>,
disassembler: Option<Box<dyn OpcodePrinter+Sync+Send>>
) -> Self {
Self {
em,
data,
create_header,
name,
disassembler,
_cl: PhantomData,
_howto: PhantomData,
}
Expand Down Expand Up @@ -1408,6 +1412,11 @@ impl<Class: ElfClass + 'static, Howto: HowTo + 'static> Binfmt for ElfFormat<Cla

Ok(true)
}

fn disassembler(&self) -> Option<&dyn OpcodePrinter> {
self.disassembler.as_deref()
.map(|d| d as &dyn OpcodePrinter)
}
}

pub struct ElfHowToUnknown;
Expand Down
2 changes: 2 additions & 0 deletions binfmt/src/elf32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod genericle {
super::consts::ELFDATA2LSB,
"elf32-genericle",
None,
None,
)
}
}
Expand All @@ -26,6 +27,7 @@ pub mod genericbe {
super::consts::ELFDATA2MSB,
"elf32-genericbe",
None,
None,
)
}
}
1 change: 1 addition & 0 deletions binfmt/src/elf32/w65.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,5 +272,6 @@ pub fn create_format() -> super::Elf32Format<Elf32W65HowTo> {
consts::ELFDATA2LSB,
"elf32-w65",
None,
None,
)
}
1 change: 1 addition & 0 deletions binfmt/src/elf32/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub fn create_format() -> super::Elf32Format<Elf64X86_64HowTo> {
consts::ELFDATA2LSB,
"elf32-x86_64",
None,
None,
)
}
2 changes: 2 additions & 0 deletions binfmt/src/elf64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod genericle {
super::consts::ELFDATA2LSB,
"elf64-genericle",
None,
None,
)
}
}
Expand All @@ -26,6 +27,7 @@ pub mod genericbe {
super::consts::ELFDATA2MSB,
"elf64-genericbe",
None,
None,
)
}
}
3 changes: 3 additions & 0 deletions binfmt/src/elf64/clever.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use arch_ops::clever::CleverPrinter;

use crate::howto::HowTo;

use super::Elf64Format;
Expand Down Expand Up @@ -157,5 +159,6 @@ pub fn create_format() -> Elf64Format<Elf64CleverHowTo> {
super::consts::ELFDATA2LSB,
"elf64-clever",
None,
Some(Box::new(CleverPrinter::new())),
)
}
1 change: 1 addition & 0 deletions binfmt/src/elf64/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,6 @@ pub fn create_format() -> super::Elf64Format<Elf64X86_64HowTo> {
consts::ELFDATA2LSB,
"elf64-x86_64",
None,
None,
)
}
4 changes: 3 additions & 1 deletion binfmt/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
traits::ReadSeek,
};

use arch_ops::traits::{Address, InsnWrite};
use arch_ops::{traits::{Address, InsnWrite}, disasm::OpcodePrinter};

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum CallbackError {
Expand All @@ -34,6 +34,8 @@ pub trait Binfmt {

fn has_sections(&self) -> bool;

fn disassembler(&self) -> Option<&dyn OpcodePrinter>{None}

fn create_section(&self, _section: &mut Section) -> Result<(), CallbackError> {
Ok(())
}
Expand Down
8 changes: 4 additions & 4 deletions lc-as/src/lcas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,10 @@ fn main() {
s
});

let name = args.next().unwrap();
let prg_name = args.next().unwrap();

if let Some(pos) = name.rfind("-") {
let begin = &name[..pos];
if let Some(pos) = prg_name.rfind("-") {
let begin = &prg_name[..pos];

targ = begin.parse::<Target>().ok();
}
Expand Down Expand Up @@ -263,7 +263,7 @@ fn main() {
std::process::exit(0);
}
"--help" => {
eprintln!("USAGE: lcas [OPTIONS] [--] [input files]..");
eprintln!("USAGE: {} [OPTIONS] [--] [input files]..",prg_name);
eprintln!("Assembles give assembly source files into binary files");
eprintln!("Options:");
eprintln!(
Expand Down
1 change: 1 addition & 0 deletions objdump/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license = "BSD-2-Clause-Patent"

[dependencies]
binfmt = {path="../binfmt", features=["all-archs"]}
target-tuples = "0.5.5"

[features]
elf = ["binfmt/elf"]
Expand Down
Loading

0 comments on commit 42a6d19

Please sign in to comment.