[PATCHES 00/12] pahole: Support more rust tags and references to dwz alternate debug files
Arnaldo Carvalho de Melo <[email protected]> Fri, 31 Jul 2026 16:30:48 -0300
| Newsgroups | org.kernel.vger.dwarves,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
Hi,
Add support for Rust discriminated unions (enums with explicit
discriminants).
Rust enums like Option<u32> and Result<i32,u8> are represented in DWARF
as DW_TAG_variant_part containing DW_TAG_variant children with
discriminant values. These patches:
- Load DW_TAG_variant_part containers with discriminant tracking
- Populate DW_TAG_variant children with discriminant values
- Handle DW_FORM_block encoding for discriminant values
- Handle DW_TAG_subprogram inside DW_TAG_enumeration (Rust methods)
- Encode variant parts as BTF_KIND_UNION members
Before: Rust Option<u32> showed as empty struct (0 members)
After: Shows None and Some variants with correct layout
=== pahole --expand_types output ===
struct Option<u32> {
struct None {
} __attribute__((__aligned__(4)));
struct Some {
/* XXX 4 bytes hole, try to pack */
u32 __0 __attribute__((__aligned__(4))); /* 4 4 */
} __attribute__((__aligned__(4)));
} __attribute__((__aligned__(4)));
BTF has no discriminated-union kind, so variant parts are tentatively
encoded as BTF_KIND_UNION with overlapping members at offset 0. Further
discussion is needed to see if we can keep that.
DW_FORM_block byte order fix: uses CU-recorded endianness instead of
assuming little-endian when decoding DW_AT_const_value and
DW_AT_default_value. Fixes cross-endian DWARF processing (e.g. reading
big-endian s390x debug info on x86).
Also add support for cross-CU type references and dwz alternate debug
files.
This is needed to improve the support for, among other things, Rust, as
noticed in the pretty printing or a perf binary that has rust objects
linked, built by clang/llvm that use cross-CU references.
DW_TAG_imported_unit support:
Handle same-file partial units where types are shared across CUs
via DW_TAG_imported_unit. Force-merge CUs that contain inter-CU
references (DW_FORM_ref_addr) so type lookups resolve correctly.
Fix cus__merging_cu failing to detect DW_FORM_ref_addr when
DW_FORM_implicit_const causes dwarf_getabbrevattr() to fail.
dwz alternate debug file support:
Handle DW_FORM_GNU_ref_alt references to dwz-compressed alternate
debug files (.dwz). Pre-processes all alternate partial units with
separate hash tables and dedup tracking.
Before (Firefox): 1774 "has no entry in cu" errors
After: processes cleanly with 0 errors
Firefox uses dwz compression which moves common types into a
separate .dwz file and replaces duplicates with DW_FORM_GNU_ref_alt
references. pahole now pre-loads the alternate file's partial units,
resolves all cross-file references, and processes Firefox DWARF
cleanly.
Includes inter-CU type reference comparison test and
vmlinux_comparison.py for DWARF/BTF analysis across kernel configs.
Known limitations:
- Pruning of unreferenced alt PUs is conservatively over-approximated
- Merged-CU path is single-threaded by design
This makes pahole to be able to support more of the CONFIG_DEBUG_ DWARF
options, including DWARF5 and compression, see the latest patch in the
series for more details about how this table is produced:
┌───────────────────────────┬─────────┬─────┬───────────────────────────────────┬─────────┬───────┬──────────┬────────┬──────────┬─────────┐
│ File │ Size │ Ver │ Producer │ DWARF │ BTF │ DW-Hash │ DW-Out │ BTF-Hash │ BTF-Out │
├───────────────────────────┼─────────┼─────┼───────────────────────────────────┼─────────┼───────┼──────────┼────────┼──────────┼─────────┤
│ vmlinux.dwarf4 │ 835.7MB │ 4 │ GNU C11 16.1.1 -gdwarf-4 │ 599.2MB │ 7.3MB │ 86e1b611 │ 7.6MB │ 52123c24 │ 7.4MB │
│ vmlinux.dwarf5 │ 736.3MB │ 5 │ GNU C11 16.1.1 -gdwarf-5 │ 499.7MB │ 7.3MB │ 86e1b611 │ 7.6MB │ 52123c24 │ 7.4MB │
│ vmlinux.dwarf5.zlib │ 497.8MB │ 5 │ GNU C11 16.1.1 -gdwarf-5 -gz=zlib │ 261.2MB │ 7.3MB │ 86e1b611 │ 7.6MB │ 52123c24 │ 7.4MB │
│ vmlinux.dwarf5.zstd │ 454.7MB │ 5 │ GNU C11 16.1.1 -gdwarf-5 -gz=zstd │ 218.1MB │ 7.3MB │ 86e1b611 │ 7.6MB │ 52123c24 │ 7.4MB │
│ vmlinux.toolchain_default │ 736.3MB │ 5 │ GNU C11 16.1.1 │ 499.7MB │ 7.3MB │ 86e1b611 │ 7.6MB │ 52123c24 │ 7.4MB │
└───────────────────────────┴─────────┴─────┴───────────────────────────────────┴─────────┴───────┴──────────┴────────┴──────────┴─────────┘
Split DWARF support (skeleton CUs) will be supported in upcoming work,
so as to cover all the possibilities the kernel build system offers
for generating DWARF.
- Arnaldo
Arnaldo Carvalho de Melo (12):
dwarf_loader: Initial support for DW_TAG_variant_part
dwarf_loader: Initial support for DW_TAG_subprogram in DW_TAG_enumeration
dwarf_loader: Populate DW_TAG_variant children in DW_TAG_variant_part
btf_encoder: Encode variant parts as union members in BTF
dwarf_loader: Handle DW_FORM_block in attr_numeric for Rust discriminant values
dwarf_loader: Allow forcing the merge of CUs for solving inter CU tag references
dwarf_loader: Support DW_TAG_imported_unit for same-file partial units
dwarf_loader: Fix cus__merging_cu failing to detect DW_FORM_ref_addr
dwarf_loader: Add cu parameter to tag__set_spec() and dwarf_tag__set_attr_type()
dwarf_loader: Support DW_FORM_GNU_ref_alt references to dwz alternate debug files
tests: Add inter-CU type reference comparison test
scripts: Add vmlinux_comparison.py for DWARF/BTF analysis
btf_encoder.c | 66 ++-
ctf_encoder.c | 34 +-
dwarf_loader.c | 873 ++++++++++++++++++++++++++++++----
dwarves.c | 77 ++-
dwarves.h | 63 ++-
dwarves_emit.c | 10 +-
dwarves_fprintf.c | 54 ++-
man-pages/pahole.1 | 18 +-
pahole.c | 20 +-
scripts/vmlinux_comparison.py | 367 ++++++++++++++
tests/block_endian.sh | 146 ++++++
tests/dwz_alt_file.sh | 204 ++++++++
tests/inter_cu_refs.sh | 50 ++
tests/prettify_perf.data.sh | 4 +-
14 files changed, 1854 insertions(+), 132 deletions(-)
create mode 100755 scripts/vmlinux_comparison.py
create mode 100755 tests/block_endian.sh
create mode 100755 tests/dwz_alt_file.sh
create mode 100755 tests/inter_cu_refs.sh
--
2.55.0