Skip to content

Commit

Permalink
Start with flattening
Browse files Browse the repository at this point in the history
  • Loading branch information
d-e-s-o committed Sep 15, 2023
1 parent f0f88f1 commit 535e221
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 70 deletions.
2 changes: 1 addition & 1 deletion src/c_api/symbolize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ pub unsafe extern "C" fn blaze_symbolizer_free(symbolizer: *mut blaze_symbolizer
///
/// The returned pointer should be released using [`blaze_result_free`] once
/// usage concluded.
fn convert_symbolizedresults_to_c(results: Vec<Vec<Sym>>) -> *const blaze_result {
fn convert_symbolizedresults_to_c(results: Vec<Option<Sym>>) -> *const blaze_result {
// Allocate a buffer to contain a blaze_result, all
// blaze_sym, and C strings of symbol and path.
let strtab_size = results.iter().flatten().fold(0, |acc, result| {
Expand Down
6 changes: 3 additions & 3 deletions src/dwarf/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl DwarfResolver {
}

/// Lookup the symbol(s) at an address.
pub(crate) fn find_syms(&self, addr: Addr) -> Result<Vec<IntSym<'_>>, Error> {
pub(crate) fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>, Error> {
// TODO: This conditional logic is weird and potentially
// unnecessary. Consider removing it or moving it higher
// in the call chain.
Expand All @@ -151,9 +151,9 @@ impl DwarfResolver {
addr,
lang: language.into(),
};
Ok(vec![sym])
Ok(Some(sym))
} else {
Ok(Vec::new())
Ok(None)
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/elf/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl ElfResolver {

impl SymResolver for ElfResolver {
#[cfg_attr(feature = "tracing", crate::log::instrument(fields(addr = format_args!("{addr:#x}"))))]
fn find_syms(&self, addr: Addr) -> Result<Vec<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
let parser = self.get_parser();
if let Some((name, addr)) = parser.find_sym(addr, STT_FUNC)? {
// ELF does not carry any source code language information.
Expand All @@ -65,13 +65,14 @@ impl SymResolver for ElfResolver {
// TODO: Long term we probably want a different heuristic here, as
// there can be valid differences between the two formats
// (e.g., DWARF could contain more symbols).
return Ok(vec![IntSym { name, addr, lang }])
let sym = IntSym { name, addr, lang };
return Ok(Some(sym))
}

match &self.backend {
#[cfg(feature = "dwarf")]
ElfBackend::Dwarf(dwarf) => dwarf.find_syms(addr),
ElfBackend::Elf(_) => Ok(Vec::new()),
ElfBackend::Dwarf(dwarf) => dwarf.find_sym(addr),
ElfBackend::Elf(_) => Ok(None),
}
}

Expand Down
12 changes: 5 additions & 7 deletions src/gsym/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,14 @@ impl<'dat> GsymResolver<'dat> {
}

impl SymResolver for GsymResolver<'_> {
fn find_syms(&self, addr: Addr) -> Result<Vec<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
if let Some(idx) = self.ctx.find_addr(addr) {
let found = self
.ctx
.addr_at(idx)
.ok_or_invalid_data(|| format!("failed to read address table entry {idx}"))?;
if addr < found {
return Ok(Vec::new())
return Ok(None)
}

let info = self
Expand All @@ -171,9 +171,9 @@ impl SymResolver for GsymResolver<'_> {
lang,
};

Ok(vec![sym])
Ok(Some(sym))
} else {
Ok(Vec::new())
Ok(None)
}
}

Expand Down Expand Up @@ -353,9 +353,7 @@ mod tests {
// always fall into the inlined region, no matter toolchain. If not, add
// padding bytes/dummy instructions and adjust some more.
let addr = 0x200020a;
let syms = resolver.find_syms(addr).unwrap();
assert_eq!(syms.len(), 1);
let sym = &syms[0];
let sym = resolver.find_sym(addr).unwrap();
assert_eq!(sym.name, "factorial_inline_test");

let info = resolver.find_line_info(addr).unwrap().unwrap();
Expand Down
6 changes: 3 additions & 3 deletions src/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ impl KernelResolver {
}

impl SymResolver for KernelResolver {
fn find_syms(&self, addr: Addr) -> Result<Vec<IntSym<'_>>> {
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
if let Some(ksym_resolver) = self.ksym_resolver.as_ref() {
ksym_resolver.find_syms(addr)
ksym_resolver.find_sym(addr)
} else {
self.elf_resolver.as_ref().unwrap().find_syms(addr)
self.elf_resolver.as_ref().unwrap().find_sym(addr)
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/ksym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl KSymResolver {
}
}

pub fn find_addresses_ksym(&self, addr: Addr) -> impl Iterator<Item = &Ksym> {
pub fn find_ksym(&self, addr: Addr) -> Option<&Ksym> {
let mut l = 0;
let mut r = self.syms.len();

Expand All @@ -125,6 +125,7 @@ impl KSymResolver {
.iter()
.rev()
.take_while(move |sym| sym.addr == self.syms[l - 1].addr)
.next()
}

#[cfg(test)]
Expand All @@ -146,9 +147,9 @@ impl KSymResolver {
}

impl SymResolver for KSymResolver {
fn find_syms(&self, addr: Addr) -> Result<Vec<IntSym<'_>>> {
let syms = self.find_addresses_ksym(addr).map(IntSym::from).collect();
Ok(syms)
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>> {
let sym = self.find_ksym(addr).map(IntSym::from);
Ok(sym)
}

fn find_addr(&self, name: &str, opts: &FindAddrOpts) -> Result<Vec<SymInfo>> {
Expand Down
5 changes: 2 additions & 3 deletions src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ pub(crate) trait SymResolver
where
Self: Debug,
{
/// Find the names and the start addresses of a symbol found for
/// the given address.
fn find_syms(&self, addr: Addr) -> Result<Vec<IntSym<'_>>>;
/// Find the symbol corresponding to the given address.
fn find_sym(&self, addr: Addr) -> Result<Option<IntSym<'_>>>;
/// Find the address and size of a symbol name.
fn find_addr(&self, name: &str, opts: &FindAddrOpts) -> Result<Vec<SymInfo>>;
/// Find the file name and the line number of an address.
Expand Down
95 changes: 50 additions & 45 deletions src/symbolize/symbolizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,70 +249,75 @@ impl Symbolizer {

/// Symbolize an address using the provided [`SymResolver`].
#[cfg_attr(feature = "tracing", crate::log::instrument(skip_all, fields(addr = format_args!("{addr:#x}"), resolver = ?resolver)))]
fn symbolize_with_resolver(&self, addr: Addr, resolver: &dyn SymResolver) -> Result<Vec<Sym>> {
let syms = resolver.find_syms(addr)?;
if syms.is_empty() {
return Ok(Vec::new())
}
fn symbolize_with_resolver(
&self,
addr: Addr,
resolver: &dyn SymResolver,
) -> Result<Option<Sym>> {
let sym = if let Some(sym) = resolver.find_sym(addr)? {
sym
} else {
return Ok(None)
};

let src_loc = if self.src_location {
resolver.find_line_info(addr)?
} else {
None
};

let mut results = Vec::with_capacity(syms.len());
for sym in syms {
let code_info = src_loc.as_ref().map(|src_loc| CodeInfo {
dir: Some(src_loc.direct.dir.to_path_buf()),
file: src_loc.direct.file.to_os_string(),
line: src_loc.direct.line,
column: src_loc.direct.column,
_non_exhaustive: (),
});

let IntSym {
name,
addr: sym_addr,
lang,
} = sym;

let sym = Sym {
name: self.maybe_demangle(name, lang),
addr: sym_addr,
offset: addr - sym_addr,
code_info,
inlined: Vec::new(),
_non_exhaustive: (),
};
let () = results.push(sym);
}
Ok(results)
let code_info = src_loc.as_ref().map(|src_loc| CodeInfo {
dir: Some(src_loc.direct.dir.to_path_buf()),
file: src_loc.direct.file.to_os_string(),
line: src_loc.direct.line,
column: src_loc.direct.column,
_non_exhaustive: (),
});

let IntSym {
name,
addr: sym_addr,
lang,
} = sym;

let sym = Sym {
name: self.maybe_demangle(name, lang),
addr: sym_addr,
offset: addr - sym_addr,
code_info,
inlined: Vec::new(),
_non_exhaustive: (),
};
Ok(Some(sym))
}

/// Symbolize a list of addresses using the provided [`SymResolver`].
fn symbolize_addrs(&self, addrs: &[Addr], resolver: &dyn SymResolver) -> Result<Vec<Vec<Sym>>> {
fn symbolize_addrs(
&self,
addrs: &[Addr],
resolver: &dyn SymResolver,
) -> Result<Vec<Option<Sym>>> {
addrs
.iter()
.map(|addr| self.symbolize_with_resolver(*addr, resolver))
.collect()
}

fn resolve_addr_in_elf(&self, addr: Addr, path: &Path) -> Result<Vec<Sym>> {
fn resolve_addr_in_elf(&self, addr: Addr, path: &Path) -> Result<Option<Sym>> {
let backend = self.elf_cache.find(path)?;
let resolver = ElfResolver::with_backend(path, backend)?;
let symbols = self.symbolize_with_resolver(addr, &resolver)?;
Ok(symbols)
let symbol = self.symbolize_with_resolver(addr, &resolver)?;
Ok(symbol)
}

/// Symbolize the given list of user space addresses in the provided
/// process.
fn symbolize_user_addrs(&self, addrs: &[Addr], pid: Pid) -> Result<Vec<Vec<Sym>>> {
fn symbolize_user_addrs(&self, addrs: &[Addr], pid: Pid) -> Result<Vec<Option<Sym>>> {
struct SymbolizeHandler<'sym> {
/// The "outer" `Symbolizer` instance.
symbolizer: &'sym Symbolizer,
/// Symbols representing the symbolized addresses.
all_symbols: Vec<Vec<Sym>>,
all_symbols: Vec<Option<Sym>>,
}

impl SymbolizeHandler<'_> {
Expand All @@ -325,17 +330,17 @@ impl Symbolizer {
let backend = ElfBackend::Elf(Rc::new(elf_parser));

let resolver = ElfResolver::with_backend(&apk_elf_path, backend)?;
let symbols = self
let symbol = self
.symbolizer
.symbolize_with_resolver(norm_addr, &resolver)?;
let () = self.all_symbols.push(symbols);
let () = self.all_symbols.push(symbol);
Ok(())
}

fn handle_elf_addr(&mut self, addr: Addr, entry: &PathMapsEntry) -> Result<()> {
let path = &entry.path.maps_file;
let norm_addr = normalize_elf_addr(addr, entry)?;
let symbols = self
let symbol = self
.symbolizer
.resolve_addr_in_elf(norm_addr, path)
.with_context(|| {
Expand All @@ -344,15 +349,15 @@ impl Symbolizer {
path.display()
)
})?;
let () = self.all_symbols.push(symbols);
let () = self.all_symbols.push(symbol);
Ok(())
}
}

impl normalize::Handler for SymbolizeHandler<'_> {
#[cfg_attr(feature = "tracing", crate::log::instrument(skip_all, fields(addr = format_args!("{_addr:#x}"))))]
fn handle_unknown_addr(&mut self, _addr: Addr) -> Result<()> {
let () = self.all_symbols.push(Vec::new());
let () = self.all_symbols.push(None);
Ok(())
}

Expand Down Expand Up @@ -383,7 +388,7 @@ impl Symbolizer {
Ok(handler.all_symbols)
}

fn symbolize_kernel_addrs(&self, addrs: &[Addr], src: &Kernel) -> Result<Vec<Vec<Sym>>> {
fn symbolize_kernel_addrs(&self, addrs: &[Addr], src: &Kernel) -> Result<Vec<Option<Sym>>> {
let Kernel {
kallsyms,
kernel_image,
Expand Down Expand Up @@ -460,7 +465,7 @@ impl Symbolizer {
/// Symbolize a list of addresses according to the configuration
/// provided via `src`.
#[cfg_attr(feature = "tracing", crate::log::instrument(skip_all, fields(src = ?src, addrs = format_args!("{addrs:#x?}"))))]
pub fn symbolize(&self, src: &Source, addrs: &[Addr]) -> Result<Vec<Vec<Sym>>> {
pub fn symbolize(&self, src: &Source, addrs: &[Addr]) -> Result<Vec<Option<Sym>>> {
match src {
Source::Elf(Elf {
path,
Expand Down

0 comments on commit 535e221

Please sign in to comment.