Extract global variable RAM locations from an ELF file's DWARF debug info and list them in a human-readable way — with struct and class members expanded to their absolute addresses:
PATH ADDRESS TYPE SIZE DECL FILE
g_motor 0x00009030 MotorData 12 test_firmware.c
g_motor.current 0x00009030 float 4 test_firmware.c
g_motor.voltage 0x00009034 float 4 test_firmware.c
g_motor.rpm 0x00009038 int32_t 4 test_firmware.c
g_system.motor.current 0x0000903c float 4 test_firmware.c
Typical use: embedded debugging and tracing workflows where you need the
exact RAM address of g_globalData.field2 to peek/poke/sample it over
SWD/JTAG.
- DWARF 4 and 5, GCC and Clang output
- C: globals, file-scope statics (with cross-TU collision
disambiguation as
file.c::name), nested structs, unions, enums, arrays - C++: namespaces, class static data members, inheritance (base-class members flattened into the derived layout), template instantiations
- Rust (best-effort): module-qualified statics, payload-carrying enums
- Output as aligned table (default), JSON, CSV, or IAR-style
MRD (
X:2005A3B3H MyVariable … 0x2) - Filter by substring, or resolve a single dotted path like
g_system.motor.rpm
Requires Rust 1.85+ (edition 2024). Works on Linux, Windows, and macOS — pure Rust, no native dependencies.
cargo build --release
# binary: target/release/var2addr (.exe on Windows)Or install into your cargo bin dir:
cargo install --path .# Full listing (table)
var2addr firmware.elf
# Only paths containing "motor"
var2addr firmware.elf --filter motor
# One variable in detail
var2addr firmware.elf --resolve g_system.motor.rpm
# Machine-readable
var2addr firmware.elf --format json
var2addr firmware.elf --format csv -o variables.csv
# IAR-style MRD file
var2addr firmware.elf --format mrd -o firmware.mrdExit codes: 0 success, 1 runtime error (no debug info, variable not
found, …), 2 usage error.
Full documentation lives in docs/ (MkDocs):
cd docs && mkdocs serve- Arrays are listed as one row with base address, element type and
count (
uint16_t[8]) — elements are not expanded individually. - Variables without a fixed address (optimized out, register-allocated, location lists) are reported as errors when resolved directly and omitted from listings.
- Virtual C++ base classes are skipped (vtable-relative, not statically resolvable).
- The ELF must be compiled with
-g(any optimization level works, but higher levels optimize more variables out).
The ELF/DWARF parsing core is vendored from the
debug_tracing_tool project (crates elf-parser and variable-model,
commit 663861d3), stripped of its frontend/TypeScript bindings and
adapted into a standalone CLI. MSRV 1.85.