Skip to content

Commit

Permalink
Add example illustrating normalization output post-processing
Browse files Browse the repository at this point in the history
Add an example illustrating how to post-process the output of address
normalization to have virtual offsets instead of file offsets available.

Refs: libbpf#835

Signed-off-by: Daniel Müller <deso@posteo.net>
  • Loading branch information
d-e-s-o authored and danielocfb committed Oct 3, 2024
1 parent 4d383c1 commit c1730b8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ name = "addr2ln_pid"
[[example]]
name = "backtrace"

[[example]]
name = "normalize-virt-offset"

[[example]]
name = "inspect-mangled"
required-features = ["demangle", "generate-unit-test-files"]
Expand Down
51 changes: 51 additions & 0 deletions examples/normalize-virt-offset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! An example illustrating usage of the library to produce virtual offsets as
//! opposed to file offsets from the normalization step by applying some
//! post-processing.

#![allow(clippy::fn_to_numeric_cast)]

use blazesym::helper::ElfResolver;
use blazesym::normalize::Normalizer;
use blazesym::symbolize::Elf;
use blazesym::symbolize::Input;
use blazesym::symbolize::Source;
use blazesym::symbolize::Symbolizer;
use blazesym::symbolize::TranslateFileOffset as _;
use blazesym::Addr;
use blazesym::Pid;


fn main() {
let normalizer = Normalizer::new();
let normalized = normalizer
.normalize_user_addrs(Pid::Slf, [main as Addr].as_slice())
.unwrap();
assert_eq!(normalized.outputs.len(), 1);

// Normalization reports file offsets, but there are cases where virtual
// addresses may be the more desirable output (e.g., when only split DWARF
// information is available for later symbolization, which may not directly
// be able to handle file offsets, but it does support virtual offsets).
// Hence, we post-process the output to convert from one to the other.
let (file_offset, meta_idx) = normalized.outputs[0];
// Find the meta data entry so that we can look at the binary to which
// the file offset belongs directly.
let meta = &normalized.meta[meta_idx];
let elf = meta.as_elf().unwrap();
let resolver = ElfResolver::open(&elf.path).unwrap();
// Translate the reported file offset into a virtual address.
let virt_offset = resolver
.file_offset_to_virt_offset(file_offset)
.unwrap()
.unwrap();

// Just for illustration purposes, symbolize the virtual offset now.
let symbolizer = Symbolizer::new();
let src = Source::Elf(Elf::new(&elf.path));
let sym = symbolizer
.symbolize_single(&src, Input::VirtOffset(virt_offset))
.unwrap()
.into_sym()
.unwrap();
assert_eq!(sym.name, "normalize_virt_offset::main");
}

0 comments on commit c1730b8

Please sign in to comment.