pub mod ghidra;
pub mod ghidra_csv;
pub mod json;
pub mod sym;
pub mod symgen_yml;
use std::error::Error;
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use ghidra::GhidraFormatter;
use ghidra_csv::CsvLoader;
use json::JsonFormatter;
use sym::SymFormatter;
pub use symgen_yml::Generate;
use symgen_yml::{Load, LoadParams, Subregion, SymGen, Symbol};
#[derive(Debug, Clone, Copy)]
pub enum OutFormat {
Ghidra,
Sym,
Json,
}
impl Generate for OutFormat {
fn generate<W: Write>(
&self,
writer: W,
symgen: &SymGen,
version: &str,
) -> Result<(), Box<dyn Error>> {
match self {
Self::Ghidra => GhidraFormatter {}.generate(writer, symgen, version),
Self::Sym => SymFormatter {}.generate(writer, symgen, version),
Self::Json => JsonFormatter {}.generate(writer, symgen, version),
}
}
}
impl OutFormat {
pub fn from(name: &str) -> Option<Self> {
match name {
"ghidra" => Some(Self::Ghidra),
"sym" => Some(Self::Sym),
"json" => Some(Self::Json),
_ => None,
}
}
pub fn extension(&self) -> String {
match self {
Self::Ghidra => String::from("ghidra"),
Self::Sym => String::from("sym"),
Self::Json => String::from("json"),
}
}
pub fn all() -> impl Iterator<Item = OutFormat> {
[Self::Ghidra, Self::Sym, Self::Json].iter().copied()
}
}
#[derive(Debug, Clone, Copy)]
pub enum InFormat {
Yaml,
Csv,
}
impl InFormat {
pub fn from(name: &str) -> Option<Self> {
match name {
"yml" => Some(Self::Yaml),
"csv" => Some(Self::Csv),
_ => None,
}
}
pub fn extension(&self) -> String {
match self {
Self::Yaml => String::from("yml"),
Self::Csv => String::from("csv"),
}
}
pub fn all() -> impl Iterator<Item = InFormat> {
[Self::Yaml, Self::Csv].iter().copied()
}
pub fn merge<R, P>(
&self,
symgen: &mut SymGen,
rdr: R,
file_name: Option<P>,
params: &LoadParams,
) -> Result<Vec<Symbol>, Box<dyn Error>>
where
R: Read,
P: AsRef<Path>,
{
let unmerged = match self {
Self::Yaml => {
let mut other = SymGen::read_no_init(rdr)?;
if let Some(file_name) = file_name {
other
.resolve_subregions(Subregion::subregion_dir(file_name.as_ref()), |p| {
File::open(p)
})?;
}
symgen.merge_symgen(&other)?;
Vec::new()
}
Self::Csv => symgen.merge_symbols(CsvLoader::load(rdr, params)?)?,
};
Ok(unmerged)
}
}