diff --git a/Cargo.toml b/Cargo.toml index e1ba8a00ca263efeb4d48cccb53bdbacc5182439..9f573ee780ad062c853c111b2e49172e7324b4b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0" serde = { version = "1", features = ["derive"] } serde_json = "1.0" gimli = "0.16" diff --git a/src/main.rs b/src/main.rs index 6fadc6b5adb200c40c8a942f6aeead3624026515..8c87687be91b063aafd35fb9c6e4914abec00322 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,76 +1,15 @@ // Based on the gimli 0.16.1 dwarfdump.rs example -// Allow clippy lints when building without clippy. +use anyhow::{anyhow, Result}; use fallible_iterator::FallibleIterator; use gimli::{Endianity, Reader}; use object::Object; use serde::Serialize; use std::borrow::{Borrow, Cow}; -use std::error; -use std::fmt::{self, Debug}; use std::fs; -use std::io; use std::path::PathBuf; -use std::result; use structopt::StructOpt; use typed_arena::Arena; -#[derive(Debug)] -pub enum Error { - GimliError(gimli::Error), - IoError(io::Error), - MissingDIE, - Message(String), - SerdeError(serde_json::Error), -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> { - match self { - Error::GimliError(err) => write!(f, "Gimli error: {}", err), - Error::IoError(e) => write!(f, "I/O error: {}", e), - Error::MissingDIE => write!(f, "Expected a DIE but none was found"), - Error::Message(m) => write!(f, "Error: {}", m), - Error::SerdeError(err) => write!(f, "Serde error: {}", err), - } - } -} - -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match *self { - Error::GimliError(ref err) => Some(err), - Error::SerdeError(ref err) => Some(err), - _ => None, - } - } -} - -impl From<gimli::Error> for Error { - fn from(err: gimli::Error) -> Self { - Error::GimliError(err) - } -} - -impl From<io::Error> for Error { - fn from(e: io::Error) -> Self { - Error::IoError(e) - } -} - -impl From<&str> for Error { - fn from(m: &str) -> Self { - Error::Message(m.to_owned()) - } -} - -impl From<serde_json::Error> for Error { - fn from(e: serde_json::Error) -> Self { - Error::SerdeError(e) - } -} - -pub type Result<T> = result::Result<T, Error>; - fn list_file<E: Endianity>(file: &object::File, endian: E) -> Result<Vec<Unit>> { let arena = Arena::new(); @@ -140,13 +79,13 @@ fn list_entries<R: Reader>( .and_then(|attr| attr.string_value(debug_str)) .map::<Result<String>, _>(|s| Ok(s.to_string()?.into_owned())) .transpose()? - .ok_or("Missing DW_AT_comp_dir")?; + .ok_or_else(|| anyhow!("Missing DW_AT_comp_dir"))?; let comp_name = entry .attr(gimli::DW_AT_name)? .and_then(|attr| attr.string_value(debug_str)) .map::<Result<String>, _>(|s| Ok(s.to_string()?.into_owned())) .transpose()? - .ok_or("Missing DW_AT_name")?; + .ok_or_else(|| anyhow!("Missing DW_AT_name"))?; v.push(Unit { comp_dir, @@ -178,7 +117,7 @@ fn main() -> Result<()> { let opt = Opt::from_args(); let file = fs::File::open(&opt.file)?; let file = unsafe { memmap::Mmap::map(&file) }?; - let file = object::File::parse(&*file)?; + let file = object::File::parse(&*file).map_err( | e | anyhow!(e))?; let endian = if file.is_little_endian() { gimli::RunTimeEndian::Little @@ -204,6 +143,7 @@ fn main() -> Result<()> { } else { units }; + let d = Data { file: opt.file, units,