diff --git a/atorsl/src/data/error.rs b/atorsl/src/data/error.rs index e5ee1fc..523dab6 100644 --- a/atorsl/src/data/error.rs +++ b/atorsl/src/data/error.rs @@ -19,9 +19,6 @@ pub enum Error { #[error("vmaddr: __TEXT segment not found")] VmAddrTextSegmentNotFound, - #[error("Compilation unit for address has no name: {0}")] - CompUnitNameMissing(Addr), - #[error("Compilation unit for address has no path: {0}")] CompUnitDirMissing(Addr), diff --git a/atorsl/src/demangler.rs b/atorsl/src/demangler.rs index 126109b..b5c65f7 100644 --- a/atorsl/src/demangler.rs +++ b/atorsl/src/demangler.rs @@ -1,11 +1,20 @@ use crate::IsOkAnd; -use gimli::DwLang; +use msvc_demangler::DemangleFlags; use std::convert::identity; use swift::Scope; -pub fn language_of(s: &str) -> DwLang { +pub enum Lang { + C, + Cpp, + ObjC, + ObjCpp, + Rust, + Swift, +} + +pub fn language_of(s: &str) -> Option { if (s.starts_with("-[") || s.starts_with("+[")) && s.ends_with(']') { - gimli::DW_LANG_ObjC + Some(Lang::ObjC) } else if s.starts_with("_Z") || s.starts_with("__Z") || s.starts_with("___Z") @@ -13,57 +22,47 @@ pub fn language_of(s: &str) -> DwLang { || s.starts_with('?') || s.starts_with("@?") { - gimli::DW_LANG_C_plus_plus + Some(Lang::Cpp) } else if s.starts_with("_R") { - gimli::DW_LANG_Rust + Some(Lang::Rust) } else if swift::is_mangled(s).is_ok_and(identity) { - gimli::DW_LANG_Swift + Some(Lang::Swift) } else { - DwLang(0) + None } } -pub fn demangle(sym: &str, lang: Option) -> String { - match lang.unwrap_or_else(|| language_of(sym)) { - gimli::DW_LANG_C - | gimli::DW_LANG_C89 - | gimli::DW_LANG_C99 - | gimli::DW_LANG_C11 - | gimli::DW_LANG_C17 - | gimli::DW_LANG_C_plus_plus - | gimli::DW_LANG_C_plus_plus_03 - | gimli::DW_LANG_C_plus_plus_11 - | gimli::DW_LANG_C_plus_plus_14 - | gimli::DW_LANG_C_plus_plus_17 - | gimli::DW_LANG_C_plus_plus_20 => { - if sym.starts_with('?') || sym.starts_with("@?") { - msvc_demangler::demangle(sym, msvc_demangler::DemangleFlags::llvm()).ok() +pub fn demangle(symbol: &str) -> String { + match language_of(symbol) { + Some(Lang::C | Lang::Cpp) => { + if symbol.starts_with('?') || symbol.starts_with("@?") { + msvc_demangler::demangle(symbol, DemangleFlags::llvm()).ok() } else { - cpp_demangle::Symbol::new(sym) - .ok() + cpp_demangle::Symbol::new(symbol) .map(|s| s.to_string()) + .ok() } } - gimli::DW_LANG_ObjC | gimli::DW_LANG_ObjC_plus_plus => { - if (sym.starts_with("-[") || sym.starts_with("+[")) && sym.ends_with(']') { + Some(Lang::ObjC | Lang::ObjCpp) => { + if (symbol.starts_with("-[") || symbol.starts_with("+[")) && symbol.ends_with(']') { None } else { - cpp_demangle::Symbol::new(sym) + cpp_demangle::Symbol::new(symbol) .ok() .map(|s| s.to_string()) } } - gimli::DW_LANG_Swift => swift::try_demangle(sym, Scope::Compact).ok(), + Some(Lang::Swift) => swift::try_demangle(symbol, Scope::Compact).ok(), - gimli::DW_LANG_Rust => rustc_demangle::try_demangle(sym) - .ok() - .map(|s| s.to_string()), + Some(Lang::Rust) => rustc_demangle::try_demangle(symbol) + .map(|s| s.to_string()) + .ok(), - _ => None, + None => None, } - .unwrap_or_else(|| sym.to_string()) + .unwrap_or_else(|| symbol.to_string()) } pub mod swift { diff --git a/atorsl/src/symbolicator.rs b/atorsl/src/symbolicator.rs index f43bb01..0a5f85e 100644 --- a/atorsl/src/symbolicator.rs +++ b/atorsl/src/symbolicator.rs @@ -16,32 +16,12 @@ pub fn atos_dwarf(dwarf: &Dwarf, addr: Addr, include_inlined: bool) -> Result builder.name( - dwarf - .attr_lossy_string(&unit, attr.value())? - .into_owned(), - ), - gimli::DW_AT_comp_dir => builder.dir(PathBuf::from( - &*dwarf.attr_lossy_string(&unit, attr.value())?, - )), - gimli::DW_AT_language => match attr.value() { - AttrValue::Language(dw_lang) => builder.lang(dw_lang), - _ => builder, - }, - _ => builder, - }) - })? - .build()?; + let comp_dir = PathBuf::from( + &*unit + .comp_dir + .ok_or(Error::CompUnitDirMissing(addr))? + .to_string_lossy(), + ); let mut debug_line_rows = unit .line_program @@ -67,10 +47,10 @@ pub fn atos_dwarf(dwarf: &Dwarf, addr: Addr, include_inlined: bool) -> Result Result Result Result, Error> { Ok(vec![Symbol { addr: Addr::from(symbol.address()), - name: demangler::demangle(symbol.name(), None), + name: demangler::demangle(symbol.name()), loc: Either::Right(addr - symbol.address()), }]) } @@ -210,23 +185,14 @@ impl DwarfExt for Dwarf<'_> { if row.address() == addr { let path = row .file(header) - .ok_or_else(|| Error::AddrFileInfoMissing(*addr)) - .and_then(|file| { - let mut path = match file.directory(header) { - Some(dir) if file.directory_index() != 0 => { - PathBuf::from(&*self.attr_lossy_string(unit, dir)?) - } - _ => comp_dir.to_path_buf(), - }; - - path.push(&*self.attr_lossy_string(unit, file.path_name())?); - - Ok(path) - })?; + .ok_or_else(|| Error::AddrFileInfoMissing(*addr))? + .path_name(); break SourceLoc { - file: path, + file: comp_dir.join(&*self.attr_lossy_string(unit, path)?), + line: row.line().map(|l| l.get()).unwrap_or_default() as u16, + col: match row.column() { ColumnType::LeftEdge => Some(0), ColumnType::Column(c) => Some(c.get() as u16),