Skip to content

Repository files navigation

gsym-rs detective crab mascot
Pure-Rust reading, writing, and Linux ELF/DWARF conversion for LLVM GSYM.
Documentation

Checks Coverage CodSpeed crates.io docs.rs

Install

Use the library from Cargo:

[dependencies]
gsym-rs = "0.1"

Install the command-line tool:

cargo install gsym-rs --locked

This installs gsymtool with ELF/DWARF conversion, memory mapping, and debuginfod discovery enabled.

Read

use gsym::Gsym;

let gsym = Gsym::open("app.gsym")?;
if let Some(symbol) = gsym.lookup(0x401120)? {
    for frame in symbol.frames() {
        println!("{}", String::from_utf8_lossy(frame.name));
    }
}
# Ok::<(), gsym::Error>(())

Write

use gsym::{AddressRange, FileEntry, Function, Gsym, GsymBuilder, LineEntry};

let mut builder = GsymBuilder::new().base_address(0x4000);
let source = builder.add_file(FileEntry::new(b"src", b"main.rs"))?;
builder.add_function(Function {
    lines: vec![LineEntry::new(0x4010, source, 12)],
    ..Function::new(AddressRange::new(0x4010, 0x4020), b"example")
})?;

let bytes = builder.to_bytes()?;
let gsym = Gsym::parse(bytes)?;
let symbol = gsym.lookup(0x4014)?.expect("address is covered");
assert_eq!(symbol.frames()[0].name, b"example");
# Ok::<(), gsym::Error>(())

Convert ELF

# #[cfg(feature = "convert")]
# {
use gsym::convert::ElfConverter;

let report = ElfConverter::default().convert_path("./app")?;
std::fs::write("./app.gsym", report.builder.to_bytes()?)?;
# }
# Ok::<(), gsym::Error>(())
gsymtool convert ./app -o ./app.gsym
gsymtool convert ./app -o ./app.gsym --version v2
gsymtool convert ./app -o ./app.gsym --dwp ./app.dwp
gsymtool convert ./bin --output-dir ./gsym --recursive --jobs 8

Cache generated files

The workspace also contains gsym-cache, a Linux-only, build-ID-addressed cache with a lock-free read path and optional process-safe population and pruning support.

Query and inspect

gsymtool lookup ./app.gsym 0x401120 0x40113a
gsymtool dump ./app.gsym --functions
gsymtool verify ./app.gsym
gsymtool transcode ./app.gsym -o ./app-v2.gsym --version v2 --endian big
gsymtool segment ./app-v2.gsym -o ./app-shard.gsym --size 64MiB

lookup accepts the unslid virtual addresses stored in the ELF image. Subtract the load bias from runtime addresses in PIE executables and shared libraries.

Performance

ELF and DWARF conversion throughput

Initialized GSYM lookup throughput

Peak resident memory during conversion

Support

Input or format Support
GSYM v1 and v2, little-endian and big-endian
Linux x86-64 and AArch64
Linked ELF ET_EXEC and ET_DYN
Relocatable ELF ET_REL
DWARF Versions 2 through 5, lines, inline frames, and call sites
Separate debug files Explicit paths, .gnu_debuglink, and GNU build-ID trees
Compressed debug data SHF-compressed sections and .gnu_debugdata
Split DWARF .dwo and .dwp
Supplementary DWARF .gnu_debugaltlink
Remote debug files debuginfod

Cargo features

Feature Default Provides
mmap Yes Memory-mapped GSYM files
convert Yes Linux ELF and DWARF conversion
debuginfod Yes Remote separate-debug discovery
cli Yes gsymtool and its command-line dependencies

Reader and writer only:

[dependencies]
gsym-rs = { version = "0.1", default-features = false }

License

Licensed under either Apache-2.0 or MIT, at your option.

About

Pure-Rust GSYM reader, writer, and Linux ELF/DWARF converter

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages