diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..7125776 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,72 @@ +use crate::{disas::DisassemblyError, m68k::BusError}; +use reedline_repl_rs::Error as ReplError; +use std::{error, fmt::Display, io, num::ParseIntError}; + +#[derive(Debug)] +pub enum Error { + Repl(ReplError), + InvalidCard(u8), + Bus(BusError), + InvalidPeekFormat, + InvalidPeekSize, + Disassembly(DisassemblyError), + Misc(&'static str), + MiscDyn(Box), + InvalidSymbolTable, + InvalidSymbolName, + Io(io::Error), +} + +impl From for Error { + fn from(v: io::Error) -> Self { + Self::Io(v) + } +} + +impl From> for Error { + fn from(v: Box) -> Self { + Self::MiscDyn(v) + } +} + +impl From> for Error { + fn from(v: DisassemblyError) -> Self { + Self::Disassembly(v) + } +} + +impl From for Error { + fn from(v: BusError) -> Self { + Self::Bus(v) + } +} + +impl From for Error { + fn from(v: ReplError) -> Self { + Self::Repl(v) + } +} + +impl From for Error { + fn from(v: ParseIntError) -> Self { + Self::Repl(v.into()) + } +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Repl(e) => e.fmt(f), + Self::InvalidCard(n) => f.write_fmt(format_args!("Card {} does not exist", n)), + Self::Bus(e) => e.fmt(f), + Self::InvalidPeekFormat => f.write_str("Invalid peek format"), + Self::InvalidPeekSize => f.write_str("Invalid peek size"), + Self::Disassembly(e) => e.fmt(f), + Self::Misc(s) => f.write_str(s), + Self::MiscDyn(e) => e.fmt(f), + Self::InvalidSymbolTable => f.write_str("Invalid symbol table"), + Self::InvalidSymbolName => f.write_str("Invalid symbol name"), + Self::Io(e) => e.fmt(f), + } + } +} diff --git a/src/location.rs b/src/location.rs new file mode 100644 index 0000000..eccc4e5 --- /dev/null +++ b/src/location.rs @@ -0,0 +1,45 @@ +use std::fmt::Display; + +use crate::SymbolTables; + +pub enum Location { + Symbol((String, String)), + Address(u32), +} + +impl Location { + pub fn addr(&self, symbol_tables: &SymbolTables) -> u32 { + match self { + Self::Symbol((table, sym)) => { + symbol_tables.get(table).unwrap().get(sym).unwrap().value() + } + Self::Address(addr) => *addr, + } + } + + pub fn displayer<'a>(&'a self, symbol_tables: &'a SymbolTables) -> LocationDisplayer<'a> { + LocationDisplayer { + location: self, + symbol_tables, + } + } +} + +pub struct LocationDisplayer<'a> { + location: &'a Location, + symbol_tables: &'a SymbolTables, +} + +impl<'a> Display for LocationDisplayer<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.location { + Location::Symbol((table, sym)) => f.write_fmt(format_args!( + "{}:{} ({:#x})", + table, + sym, + self.location.addr(self.symbol_tables) + )), + Location::Address(addr) => f.write_fmt(format_args!("{:#x}", addr)), + } + } +} diff --git a/src/main.rs b/src/main.rs index 6ef4be9..f13e883 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,21 +3,24 @@ mod backplane; mod card; mod disas; +mod error; mod instruction; +mod location; mod m68k; mod ram; mod rom; mod storage; +mod symbol; mod term; use crate::{ backplane::Backplane, + error::Error, + location::Location, m68k::{BusError, M68K}, + symbol::Symbol, }; use disas::DisassemblyError; -use elf::{ - gabi::{STT_FILE, STT_SECTION}, - symbol::Symbol as ElfSymbol, -}; +use elf::gabi::{STT_FILE, STT_SECTION}; use itertools::Itertools; use parse_int::parse; use reedline_repl_rs::{ @@ -28,83 +31,13 @@ use serde_yaml::Mapping; use std::{ collections::HashMap, convert::TryFrom, - error, - fmt::Display, + error::Error as StdError, fs::{self, File}, - io, - num::ParseIntError, path::Path, process, }; -#[derive(Debug)] -enum Error { - Repl(ReplError), - InvalidCard(u8), - Bus(BusError), - InvalidPeekFormat, - InvalidPeekSize, - Disassembly(DisassemblyError), - Misc(&'static str), - MiscDyn(Box), - InvalidSymbolTable, - InvalidSymbolName, - Io(io::Error), -} - -impl From for Error { - fn from(v: io::Error) -> Self { - Self::Io(v) - } -} - -impl From> for Error { - fn from(v: Box) -> Self { - Self::MiscDyn(v) - } -} - -impl From> for Error { - fn from(v: DisassemblyError) -> Self { - Self::Disassembly(v) - } -} - -impl From for Error { - fn from(v: BusError) -> Self { - Self::Bus(v) - } -} - -impl From for Error { - fn from(v: ReplError) -> Self { - Self::Repl(v) - } -} - -impl From for Error { - fn from(v: ParseIntError) -> Self { - Self::Repl(v.into()) - } -} - -impl Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Repl(e) => e.fmt(f), - Self::InvalidCard(n) => f.write_fmt(format_args!("Card {} does not exist", n)), - Self::Bus(e) => e.fmt(f), - Self::InvalidPeekFormat => f.write_str("Invalid peek format"), - Self::InvalidPeekSize => f.write_str("Invalid peek size"), - Self::Disassembly(e) => e.fmt(f), - Self::Misc(s) => f.write_str(s), - Self::MiscDyn(e) => e.fmt(f), - Self::InvalidSymbolTable => f.write_str("Invalid symbol table"), - Self::InvalidSymbolName => f.write_str("Invalid symbol name"), - Self::Io(e) => e.fmt(f), - } - } -} +pub type SymbolTables = HashMap>; #[derive(Copy, Clone, Debug)] enum PeekFormat { @@ -187,75 +120,6 @@ impl TryFrom for PeekSize { } } -enum Location { - Symbol((String, String)), - Address(u32), -} - -impl Location { - pub fn addr(&self, symbol_tables: &SymbolTables) -> u32 { - match self { - Self::Symbol((table, sym)) => { - symbol_tables.get(table).unwrap().get(sym).unwrap().value as u32 - } - Self::Address(addr) => *addr, - } - } - - pub fn displayer<'a>(&'a self, symbol_tables: &'a SymbolTables) -> LocationDisplayer<'a> { - LocationDisplayer { - location: self, - symbol_tables, - } - } -} - -struct LocationDisplayer<'a> { - location: &'a Location, - symbol_tables: &'a SymbolTables, -} - -impl<'a> Display for LocationDisplayer<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.location { - Location::Symbol((table, sym)) => f.write_fmt(format_args!( - "{}:{} ({:#x})", - table, - sym, - self.location.addr(self.symbol_tables) - )), - Location::Address(addr) => f.write_fmt(format_args!("{:#x}", addr)), - } - } -} - -struct Symbol { - section: u16, - value: u32, - size: u32, -} - -impl From for Symbol { - fn from(sym: ElfSymbol) -> Self { - Self { - section: sym.st_shndx, - value: sym.st_value as u32, - size: sym.st_size as u32, - } - } -} - -impl Display for Symbol { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!( - "Value: {:#010x} Size: {:#06x} Section: {}", - self.value, self.size, self.section - )) - } -} - -type SymbolTables = HashMap>; - struct EmuState { cpu: M68K, symbol_tables: SymbolTables, @@ -599,11 +463,10 @@ fn main() -> Result<(), ReplError> { } fn read_symbol_table(path: &str) -> Result, Error> { - let file = - elf::File::open_stream(&mut File::open(path)?).map_err(>::from)?; + let file = elf::File::open_stream(&mut File::open(path)?).map_err(>::from)?; let (symtab, symstrtab) = file .symbol_table() - .map_err(>::from)? + .map_err(>::from)? .ok_or(Error::Misc("No symbol table in file"))?; Ok(symtab .iter() diff --git a/src/symbol.rs b/src/symbol.rs new file mode 100644 index 0000000..a267000 --- /dev/null +++ b/src/symbol.rs @@ -0,0 +1,44 @@ +use std::fmt::Display; + +use elf::symbol::Symbol as ElfSymbol; + +pub struct Symbol { + section: u16, + value: u32, + size: u32, +} + +impl Symbol { + #[allow(unused)] + pub fn section(&self) -> u16 { + self.section + } + + pub fn value(&self) -> u32 { + self.value + } + + #[allow(unused)] + pub fn size(&self) -> u32 { + self.size + } +} + +impl From for Symbol { + fn from(sym: ElfSymbol) -> Self { + Self { + section: sym.st_shndx, + value: sym.st_value as u32, + size: sym.st_size as u32, + } + } +} + +impl Display for Symbol { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!( + "Value: {:#010x} Size: {:#06x} Section: {}", + self.value, self.size, self.section + )) + } +}