Extract code from main.rs to separate files

This commit is contained in:
pjht 2022-10-18 10:56:08 -05:00
parent 615c3cfd8b
commit c508062168
4 changed files with 172 additions and 148 deletions

72
src/error.rs Normal file
View File

@ -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<BusError>),
Misc(&'static str),
MiscDyn(Box<dyn error::Error>),
InvalidSymbolTable,
InvalidSymbolName,
Io(io::Error),
}
impl From<io::Error> for Error {
fn from(v: io::Error) -> Self {
Self::Io(v)
}
}
impl From<Box<dyn error::Error>> for Error {
fn from(v: Box<dyn error::Error>) -> Self {
Self::MiscDyn(v)
}
}
impl From<DisassemblyError<BusError>> for Error {
fn from(v: DisassemblyError<BusError>) -> Self {
Self::Disassembly(v)
}
}
impl From<BusError> for Error {
fn from(v: BusError) -> Self {
Self::Bus(v)
}
}
impl From<ReplError> for Error {
fn from(v: ReplError) -> Self {
Self::Repl(v)
}
}
impl From<ParseIntError> 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),
}
}
}

45
src/location.rs Normal file
View File

@ -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)),
}
}
}

View File

@ -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<BusError>),
Misc(&'static str),
MiscDyn(Box<dyn error::Error>),
InvalidSymbolTable,
InvalidSymbolName,
Io(io::Error),
}
impl From<io::Error> for Error {
fn from(v: io::Error) -> Self {
Self::Io(v)
}
}
impl From<Box<dyn error::Error>> for Error {
fn from(v: Box<dyn error::Error>) -> Self {
Self::MiscDyn(v)
}
}
impl From<DisassemblyError<BusError>> for Error {
fn from(v: DisassemblyError<BusError>) -> Self {
Self::Disassembly(v)
}
}
impl From<BusError> for Error {
fn from(v: BusError) -> Self {
Self::Bus(v)
}
}
impl From<ReplError> for Error {
fn from(v: ReplError) -> Self {
Self::Repl(v)
}
}
impl From<ParseIntError> 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<String, HashMap<String, Symbol>>;
#[derive(Copy, Clone, Debug)]
enum PeekFormat {
@ -187,75 +120,6 @@ impl TryFrom<char> 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<ElfSymbol> 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<String, HashMap<String, Symbol>>;
struct EmuState {
cpu: M68K,
symbol_tables: SymbolTables,
@ -599,11 +463,10 @@ fn main() -> Result<(), ReplError> {
}
fn read_symbol_table(path: &str) -> Result<HashMap<String, Symbol>, Error> {
let file =
elf::File::open_stream(&mut File::open(path)?).map_err(<Box<dyn error::Error>>::from)?;
let file = elf::File::open_stream(&mut File::open(path)?).map_err(<Box<dyn StdError>>::from)?;
let (symtab, symstrtab) = file
.symbol_table()
.map_err(<Box<dyn error::Error>>::from)?
.map_err(<Box<dyn StdError>>::from)?
.ok_or(Error::Misc("No symbol table in file"))?;
Ok(symtab
.iter()

44
src/symbol.rs Normal file
View File

@ -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<ElfSymbol> 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
))
}
}