Make SymbolTable.{symbols, breakpoints} private
This commit is contained in:
parent
d0f1b588f7
commit
78596ae117
@ -3,16 +3,51 @@ use anyhow::anyhow;
|
|||||||
use elf::gabi::{STT_FILE, STT_SECTION};
|
use elf::gabi::{STT_FILE, STT_SECTION};
|
||||||
use elf::CachedReadBytes;
|
use elf::CachedReadBytes;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
use itertools::Itertools;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Display;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
pub struct SymbolDisplayer<'a>(&'a SymbolTable);
|
||||||
|
|
||||||
|
impl Display for SymbolDisplayer<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!(
|
||||||
|
"{}",
|
||||||
|
self.0
|
||||||
|
.symbols
|
||||||
|
.iter()
|
||||||
|
.format_with("\n", |(name, symbol), g| {
|
||||||
|
g(&format_args!("{name}: {symbol}"))
|
||||||
|
})
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Error)]
|
||||||
|
#[error("Invalid symbol table")]
|
||||||
|
struct InvalidSymbolTable;
|
||||||
|
|
||||||
|
pub struct BreakpointDisplayer<'a>(&'a SymbolTable);
|
||||||
|
|
||||||
|
impl Display for BreakpointDisplayer<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{}", self.0.breakpoints.iter().format("\n")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SymbolTable {
|
pub struct SymbolTable {
|
||||||
pub symbols: HashMap<String, Symbol>,
|
symbols: HashMap<String, Symbol>,
|
||||||
pub breakpoints: IndexSet<String>,
|
breakpoints: IndexSet<String>,
|
||||||
pub active: bool,
|
pub active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Error)]
|
||||||
|
#[error("Invalid symbol name")]
|
||||||
|
pub struct InvalidSymbolName;
|
||||||
|
|
||||||
impl SymbolTable {
|
impl SymbolTable {
|
||||||
pub fn new(symbols: HashMap<String, Symbol>) -> Self {
|
pub fn new(symbols: HashMap<String, Symbol>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -41,14 +76,14 @@ impl SymbolTable {
|
|||||||
Ok(Self::new(symbols))
|
Ok(Self::new(symbols))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_symbols(&mut self, symbols: HashMap<String, Symbol>) {
|
pub fn update_symbols_from(&mut self, table: Self) {
|
||||||
self.breakpoints = self
|
self.breakpoints = self
|
||||||
.breakpoints
|
.breakpoints
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.filter(|sym| symbols.contains_key(sym))
|
.filter(|sym| table.symbols.contains_key(sym))
|
||||||
.collect::<IndexSet<_>>();
|
.collect::<IndexSet<_>>();
|
||||||
self.symbols = symbols;
|
self.symbols = table.symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn breakpoint_set_at(&self, addr: u32) -> bool {
|
pub fn breakpoint_set_at(&self, addr: u32) -> bool {
|
||||||
@ -57,6 +92,14 @@ impl SymbolTable {
|
|||||||
.any(|sym| self.symbols[sym].value() == addr)
|
.any(|sym| self.symbols[sym].value() == addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_breakpoint(&mut self, symbol: String) {
|
||||||
|
self.breakpoints.insert(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_breakpoint(&mut self, symbol: &str) -> bool {
|
||||||
|
self.breakpoints.shift_remove(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn address_to_symbol(&self, addr: u32) -> Option<(&String, u32)> {
|
pub fn address_to_symbol(&self, addr: u32) -> Option<(&String, u32)> {
|
||||||
self.symbols
|
self.symbols
|
||||||
.iter()
|
.iter()
|
||||||
@ -64,4 +107,20 @@ impl SymbolTable {
|
|||||||
.map(|(sym_name, sym)| (sym_name, addr - sym.value()))
|
.map(|(sym_name, sym)| (sym_name, addr - sym.value()))
|
||||||
.min_by_key(|(_, offset)| *offset)
|
.min_by_key(|(_, offset)| *offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_symbol(&self, symbol: &str) -> anyhow::Result<&Symbol> {
|
||||||
|
Ok(self.symbols.get(symbol).ok_or(InvalidSymbolName)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains_symbol(&self, symbol: &str) -> bool {
|
||||||
|
self.symbols.contains_key(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn symbol_displayer(&self) -> SymbolDisplayer<'_> {
|
||||||
|
SymbolDisplayer(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn breakpoint_displayer(&self) -> BreakpointDisplayer {
|
||||||
|
BreakpointDisplayer(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
use std::{fmt::Display, path::Path};
|
use std::{fmt::Display, path::Path};
|
||||||
|
|
||||||
use crate::{location::Location, symbol::Symbol, symbol_table::SymbolTable};
|
use crate::{
|
||||||
|
location::Location,
|
||||||
|
symbol::Symbol,
|
||||||
|
symbol_table::{InvalidSymbolName, SymbolTable},
|
||||||
|
};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use parse_int::parse;
|
use parse_int::parse;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub struct SymbolDisplayer<'a>(&'a SymbolTables);
|
|
||||||
|
|
||||||
fn displayer_common<'a, F, T: Display>(
|
fn displayer_common<'a, F, T: Display>(
|
||||||
symbol_tables: &'a SymbolTables,
|
symbol_tables: &'a SymbolTables,
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
@ -31,13 +33,11 @@ where
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SymbolDisplayer<'a>(&'a SymbolTables);
|
||||||
|
|
||||||
impl Display for SymbolDisplayer<'_> {
|
impl Display for SymbolDisplayer<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
displayer_common(self.0, f, |table| {
|
displayer_common(self.0, f, |table| table.symbol_displayer())
|
||||||
table.symbols.iter().format_with("\n", |(name, symbol), g| {
|
|
||||||
g(&format_args!("{name}: {symbol}"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,15 +45,11 @@ impl Display for SymbolDisplayer<'_> {
|
|||||||
#[error("Invalid symbol table")]
|
#[error("Invalid symbol table")]
|
||||||
struct InvalidSymbolTable;
|
struct InvalidSymbolTable;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Error)]
|
|
||||||
#[error("Invalid symbol name")]
|
|
||||||
struct InvalidSymbolName;
|
|
||||||
|
|
||||||
pub struct BreakpointDisplayer<'a>(&'a SymbolTables);
|
pub struct BreakpointDisplayer<'a>(&'a SymbolTables);
|
||||||
|
|
||||||
impl Display for BreakpointDisplayer<'_> {
|
impl Display for BreakpointDisplayer<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
displayer_common(self.0, f, |table| table.breakpoints.iter().format("\n"))
|
displayer_common(self.0, f, |table| table.breakpoint_displayer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +93,7 @@ impl SymbolTables {
|
|||||||
let new_table = SymbolTable::read_from_file(path)?;
|
let new_table = SymbolTable::read_from_file(path)?;
|
||||||
let table_name = Path::new(&path).file_name().unwrap().to_str().unwrap();
|
let table_name = Path::new(&path).file_name().unwrap().to_str().unwrap();
|
||||||
if let Some(table) = self.tables.get_mut(table_name) {
|
if let Some(table) = self.tables.get_mut(table_name) {
|
||||||
table.update_symbols(new_table.symbols);
|
table.update_symbols_from(new_table);
|
||||||
} else {
|
} else {
|
||||||
self.tables.insert(table_name.to_string(), new_table);
|
self.tables.insert(table_name.to_string(), new_table);
|
||||||
};
|
};
|
||||||
@ -110,12 +106,12 @@ impl SymbolTables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_breakpoint(&mut self, table: &str, symbol: String) -> anyhow::Result<()> {
|
pub fn set_breakpoint(&mut self, table: &str, symbol: String) -> anyhow::Result<()> {
|
||||||
self.get_table_mut(table)?.breakpoints.insert(symbol);
|
self.get_table_mut(table)?.set_breakpoint(symbol);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_breakpoint(&mut self, table: &str, symbol: &str) -> anyhow::Result<bool> {
|
pub fn delete_breakpoint(&mut self, table: &str, symbol: &str) -> anyhow::Result<bool> {
|
||||||
Ok(self.get_table_mut(table)?.breakpoints.shift_remove(symbol))
|
Ok(self.get_table_mut(table)?.delete_breakpoint(symbol))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol_displayer(&self) -> SymbolDisplayer<'_> {
|
pub fn symbol_displayer(&self) -> SymbolDisplayer<'_> {
|
||||||
@ -131,11 +127,7 @@ impl SymbolTables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, table: &str, symbol: &str) -> anyhow::Result<&Symbol> {
|
pub fn get(&self, table: &str, symbol: &str) -> anyhow::Result<&Symbol> {
|
||||||
Ok(self
|
self.get_table(table)?.get_symbol(symbol)
|
||||||
.get_table(table)?
|
|
||||||
.symbols
|
|
||||||
.get(symbol)
|
|
||||||
.ok_or(InvalidSymbolName)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_location(&self, location: &str) -> anyhow::Result<Location> {
|
pub fn parse_location(&self, location: &str) -> anyhow::Result<Location> {
|
||||||
@ -145,16 +137,10 @@ impl SymbolTables {
|
|||||||
table_name = self
|
table_name = self
|
||||||
.tables
|
.tables
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, table)| table.symbols.contains_key(symbol_name))
|
.find(|(_, table)| table.contains_symbol(symbol_name))
|
||||||
.ok_or(InvalidSymbolName)?
|
.ok_or(InvalidSymbolName)?
|
||||||
.0;
|
.0;
|
||||||
} else if !self
|
} else if !self.get_table(table_name)?.contains_symbol(symbol_name) {
|
||||||
.tables
|
|
||||||
.get(table_name)
|
|
||||||
.ok_or(InvalidSymbolTable)?
|
|
||||||
.symbols
|
|
||||||
.contains_key(symbol_name)
|
|
||||||
{
|
|
||||||
return Err(InvalidSymbolName.into());
|
return Err(InvalidSymbolName.into());
|
||||||
}
|
}
|
||||||
Ok(Location::Symbol((
|
Ok(Location::Symbol((
|
||||||
|
Loading…
Reference in New Issue
Block a user