[PATCH 0/3] perf annotate: Data type profiling support for C++ classes and virtual calls
From: Yanbo Zhao
Date: Fri Aug 21 2026 - 01:02:58 EST
Data type profiling currently only understands C struct/union types.
For C++ workloads, member accesses on classes cannot be resolved, and
virtual function calls (indirect calls through the vtable) break the
instruction type tracking entirely: the call target is unknown, so the
return type is lost and register states get invalidated.
This series extends data type profiling to C++:
Patch 1 introduces die_is_compound_type() covering
DW_TAG_structure_type, DW_TAG_union_type and DW_TAG_class_type, and
converts all existing open-coded struct/union checks in dwarf-aux.c
and annotate-data.c to use it. It also accepts DW_TAG_inheritance in
the member lookup callbacks so offset-based lookup descends into base
class subobjects.
Patch 2 adds the C++-specific DWARF helpers: CU language detection,
base class and vtable index inspection, virtual function lookup by
vtable index (recursing into base classes), and vtable pointer
(_vptr) member identification. Fallback definitions are provided for
DW_AT_vtable_elem_index and DW_LANG_C_plus_plus_17/20 so the code
builds against older elfutils.
Patch 3 wires it up in the disassembler and the x86 instruction
tracking: a load of a '_vptr' member marks the destination register
as TSR_KIND_VTABLE_PTR, and an indirect call through such a register
is resolved statically via the vtable index, recovering the return
type and updating the receiver ('this' pointer) register to the class
type. The receiver register number comes from the new
type_state::arg0_reg field initialized per arch like ret_reg.
Caller-saved register invalidation is moved after the target operands
are read so the state needed for resolution is not lost.
Only the primary vtable is handled for now; multiple inheritance is
left as a TODO. Updating the receiver register for any method call
that passes a 'this' pointer (not only resolved virtual calls) needs
a callee DIE lookup by linkage name and is planned as a follow-up on
top of this series.
Verified on an x86-64 C++ workload with virtual calls in a hot loop
(built with -O2 -g): the vptr loads are tracked, the indirect calls
are resolved, and 'perf report -s type,typeoff' attributes the
samples to 'struct Base +0 (_vptr.Base)'. Also passed 'perf test'
annotate basic tests and checkpatch on all three patches.
Yanbo Zhao (3):
perf dwarf-aux: Add die_is_compound_type() to handle C++ class types
perf dwarf-aux: Add C++ class, inheritance and vtable helpers
perf disasm & annotate x86: Track C++ vptr and resolve virtual
function calls
tools/perf/util/annotate-arch/annotate-x86.c | 103 +++++++--
tools/perf/util/annotate-data.c | 36 ++--
tools/perf/util/annotate-data.h | 3 +
tools/perf/util/annotate.c | 4 +
tools/perf/util/disasm.c | 1 +
tools/perf/util/dwarf-aux.c | 209 ++++++++++++++++++-
tools/perf/util/dwarf-aux.h | 27 +++
7 files changed, 342 insertions(+), 41 deletions(-)
--
2.25.1