Skip to content

Commit

Permalink
Show functions as demangled fully qualified names. (#34)
Browse files Browse the repository at this point in the history
Also, I have removed the trailing () from function names, which (to me)
implies that they are functions with no arguments, which is usually not
the case.
  • Loading branch information
cbiffle committed Oct 29, 2021
1 parent d8296e9 commit 11a91a2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 27 deletions.
7 changes: 5 additions & 2 deletions src/cmd/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn print_stack(
if let Some(ref inlined) = frame.inlined {
for inline in inlined {
println!(
"0x{:08x} 0x{:08x} {}()",
"0x{:08x} 0x{:08x} {}",
frame.cfa, inline.addr, inline.name
);
print!(" {} ", bar);
Expand All @@ -74,7 +74,10 @@ fn print_stack(
}

if let Some(sym) = frame.sym {
println!("0x{:08x} 0x{:08x} {}()", frame.cfa, *pc, sym.name);
println!(
"0x{:08x} 0x{:08x} {}",
frame.cfa, *pc, sym.demangled_name
);

if subargs.line {
if let Some(src) = hubris.lookup_src(sym.goff) {
Expand Down
70 changes: 45 additions & 25 deletions src/hubris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ pub struct HubrisArchive {
// DWARF source code: goff to file/line
src: HashMap<HubrisGoff, HubrisSrc>,

// DWARF symbols: address to name/length/goff tuple
dsyms: BTreeMap<u32, (String, u32, HubrisGoff)>,
// DWARF symbols: address to HubrisSymbol
dsyms: BTreeMap<u32, HubrisSymbol>,

// ELF symbols: address to name/length tuple
esyms: BTreeMap<u32, (String, u32)>,
Expand All @@ -99,7 +99,7 @@ pub struct HubrisArchive {
// Inlined: address/nesting tuple to length/goff/origin tuple
inlined: BTreeMap<(u32, isize), (u32, HubrisGoff, HubrisGoff)>,

// Subprograms: goff to name
// Subprograms: goff to demangled name
subprograms: HashMap<HubrisGoff, String>,

// Base types: goff to size
Expand Down Expand Up @@ -228,10 +228,8 @@ impl HubrisArchive {
* First, check our DWARF symbols.
*/
sym = match self.dsyms.range(..=addr).next_back() {
Some((&sym_addr, (name, sym_len, _goff)))
if addr < sym_addr + sym_len =>
{
Some((name, sym_addr))
Some((_, sym)) if addr < sym.addr + sym.size => {
Some((&sym.name, sym.addr))
}
_ => None,
};
Expand Down Expand Up @@ -617,7 +615,7 @@ impl HubrisArchive {
>,
) -> Result<()> {
let mut name = None;
let mut _linkage_name = None;
let mut linkage_name = None;
let mut addr = None;
let mut len = None;

Expand All @@ -640,7 +638,7 @@ impl HubrisArchive {
len = Some(value);
}
(gimli::constants::DW_AT_linkage_name, _) => {
_linkage_name = dwarf_name(dwarf, attr.value());
linkage_name = dwarf_name(dwarf, attr.value());
}
(gimli::constants::DW_AT_name, _) => {
name = dwarf_name(dwarf, attr.value());
Expand All @@ -650,23 +648,34 @@ impl HubrisArchive {
}

if let Some(name) = name {
let demangled_name = if let Some(ln) = linkage_name {
demangle_name(ln)
} else {
name.to_string()
};

self.subprograms.insert(goff, demangled_name.clone());

match (addr, len) {
(Some(addr), Some(len)) if addr != 0 => {
self.dsyms.insert(
addr as u32,
(String::from(name), len as u32, goff),
HubrisSymbol {
name: name.to_string(),
demangled_name,
size: len as u32,
addr: addr as u32,
goff,
},
);
}
_ => {}
}

self.subprograms.insert(goff, String::from(name));

Ok(())
} else {
trace!("no name found for {}", goff);
Ok(())
}

Ok(())
}

fn dwarf_basetype<R: gimli::Reader<Offset = usize>>(
Expand Down Expand Up @@ -838,7 +847,13 @@ impl HubrisArchive {
for &(addr, size) in syms {
if let btree_map::Entry::Vacant(e) = self.dsyms.entry(addr)
{
e.insert((String::from(name), size, goff));
e.insert(HubrisSymbol {
name: String::from(name),
demangled_name: demangle_name(&name),
size,
addr,
goff,
});
self.variables.insert(
String::from(name),
HubrisVariable {
Expand Down Expand Up @@ -2603,11 +2618,7 @@ impl HubrisArchive {
// Lookup the DWARF symbol associated with our PC
//
let sym = match self.dsyms.range(..=pc).next_back() {
Some(sym) if pc < *sym.0 + sym.1 .1 => Some(HubrisSymbol {
addr: *sym.0 as u32,
name: &sym.1 .0,
goff: sym.1 .2,
}),
Some((addr, sym)) if pc < *addr + sym.size => Some(sym),
_ => None,
};

Expand Down Expand Up @@ -3404,10 +3415,12 @@ impl fmt::Display for HubrisGoff {
}
}

#[derive(Copy, Clone, Debug)]
pub struct HubrisSymbol<'a> {
#[derive(Clone, Debug)]
pub struct HubrisSymbol {
pub addr: u32,
pub name: &'a str,
pub name: String,
pub demangled_name: String,
pub size: u32,
pub goff: HubrisGoff,
}

Expand Down Expand Up @@ -3746,7 +3759,7 @@ pub enum HubrisTarget {
#[derive(Clone, Debug)]
pub struct HubrisStackFrame<'a> {
pub cfa: u32,
pub sym: Option<HubrisSymbol<'a>>,
pub sym: Option<&'a HubrisSymbol>,
pub registers: HashMap<ARMRegister, u32>,
pub inlined: Option<Vec<HubrisInlined<'a>>>,
}
Expand Down Expand Up @@ -3826,3 +3839,10 @@ fn dwarf_name<'a>(
_ => None,
}
}

/// Demangles `name` as a Rust symbol.
fn demangle_name(name: &str) -> String {
// Note: "alternate mode" # causes rustc_demangle to leave off the ugly hash
// values on functions.
format!("{:#}", rustc_demangle::demangle(name))
}

0 comments on commit 11a91a2

Please sign in to comment.