Symbol Library (zxdb/symbols)

Overview

//src/developer/debug/zxdb/symbols is the DWARF and ELF symbol indexing and lookup subsystem (Layer 2) for zxdb. It decodes DWARF Debug Information Entries (DIEs), line tables, and ELF symbols into a reference-counted object graph, and evaluates DWARF location expressions (DwarfExprEval).

Interface

Public headers expose these symbol classes, factories, and evaluators:

  • zxdb::Symbol (symbol.h): Reference-counted base class (fxl::RefCountedThreadSafe<Symbol>) for DWARF DIE symbols with manual RTTI (As<T>()). Exposes GetLazySymbol, GetDieRef, parent, GetAssignedName, GetFullName, GetIdentifier, GetCompileUnit, GetDwarfUnit, GetModuleSymbols, GetSymbolContext, and GetLanguage.
  • zxdb::Type (type.h, collection.h): Base type symbol (StripCV, StripCVT, is_declaration, byte_size). Subclasses include BaseType, ModifiedType, Collection (struct, class, union, and Rust enum or tuple), ArrayType, FunctionType, Enumeration, MemberPtr, VariantPart, and Variant.
  • zxdb::Value, zxdb::Variable, zxdb::DataMember: Named data symbols with type, is_external, artificial, const_value, and VariableLocation metadata (value.h, variable.h, data_member.h).
  • zxdb::CodeBlock, zxdb::Function, zxdb::CompileUnit: Lexical scopes, functions, inlined routines, and compilation units (code_block.h, function.h, compile_unit.h). Exposes address range queries (code_ranges, GetAbsoluteCodeRanges, ContainsAddress) and scope traversal (GetMostSpecificChild, GetContainingFunction, GetInlineChain, GetAmbiguousInlineChain).
  • zxdb::LazySymbolBase, zxdb::LazySymbol, zxdb::UncachedLazySymbol, zxdb::SymbolFactory, zxdb::DwarfSymbolFactory: Lazy DIE reference wrappers and factories that decode DwarfDieRef entries into Symbol objects on demand (lazy_symbol.h, symbol_factory.h, dwarf_symbol_factory.h).
  • zxdb::SystemSymbols, zxdb::TargetSymbols, zxdb::ProcessSymbols, zxdb::ModuleSymbols, zxdb::ModuleSymbolsImpl, zxdb::LoadedModuleSymbols: Symbol containers from global BuildIDIndex caches down to loaded modules with SymbolContext address translation (system_symbols.h, target_symbols.h, process_symbols.h, module_symbols.h, loaded_module_symbols.h).
  • zxdb::DwarfExpr, zxdb::DwarfExprEval, zxdb::SymbolDataProvider: Asynchronous stack-based DWARF expression evaluator and target memory/register provider interface (dwarf_expr.h, dwarf_expr_eval.h, symbol_data_provider.h).
  • Binary readers, symbol indices, line tables, and scope visitors: zxdb::DwarfBinary, zxdb::DwarfUnit, zxdb::DwarfDieDecoder, zxdb::DwarfDieScanner, zxdb::ElfSymbol, zxdb::Index, and zxdb::IndexNode. Also exposes zxdb::Identifier, zxdb::Location, zxdb::InputLocation, zxdb::LineTable, zxdb::LineDetails, zxdb::VariableLocation, and zxdb::VisitScopes.

Invariants

Callers and implementations must preserve these invariants:

  • Symbol objects use fxl::RefCountedThreadSafe<Symbol> and do not globally cache or deduplicate instances by DIE offset. Never compare Symbol* pointers to test semantic symbol equality.
  • Downward edges in the symbol graph (parent to child) must use cached LazySymbol instances. Upward edges (such as Symbol::parent() and Function::containing_block()) must use UncachedLazySymbol to prevent reference-counting cycles and memory leaks.
  • SymbolFactory::CreateSymbol(), LazySymbol::Get(), and UncachedLazySymbol::Get() never return nullptr. On failure or unloaded modules, they return an empty Symbol with DwarfTag::kNone.
  • Symbol, CodeBlock, and ModuleSymbols store module-relative addresses. Pass a SymbolContext bound to a loaded module's base address to convert to or from absolute process addresses.
  • TargetSymbols::ResolveInputLocation rejects address-based locations (InputLocation::Type::kAddress) because address resolution requires a running process via ProcessSymbols.
  • Use Symbol::As<Derived>() instead of C++ dynamic_cast because the build disables compiler RTTI.
  • DWARF unit offsets and type signatures of 0 are valid DWARF values (DwarfDieRef, UnitSymbolFactory, DwarfSymbolFactory). Never use 0 as an invalid sentinel. Use std::optional<uint64_t> and guard accessors with DCHECK(is_valid()).
  • DwarfSymbolFactory handles DwarfTag::kTypeUnit alongside DwarfTag::kCompileUnit so child DIEs can reach llvm::DWARFUnit via CompileUnit. DwarfBinaryImpl queries both normal compilation units (getNormalUnitsVector()) and split-DWARF DWO units (getDWOUnitsVector()).
  • When resolving a DWARF type signature whose target DwarfDieRef is invalid (!sig_ref.is_valid()), return an empty fxl::RefPtr<Symbol>() instead of crashing with FX_CHECK.

Side Effects

Using zxdb/symbols produces these disk, cache, and IPC side effects:

  • Calling Get() on a LazySymbol or UncachedLazySymbol decodes DWARF DIE records from the binary or .dwo file via SymbolFactory and caches LazySymbol::symbol_.
  • Calling Symbol::GetFullName(), Symbol::GetIdentifier(), or Collection::GetSpecialType() lazily computes and caches the formatted name, Identifier, or SpecialType on the Symbol.
  • SystemSymbols::GetModule() loads ELF and DWARF files from disk via BuildIDIndex and builds the symbol Index, or calls RequestDownloadFunction when local symbols are missing.
  • ProcessSymbols::SetModules() and RetryLoadBuildID() load and unload module symbols, update TargetSymbols, and invoke ProcessSymbols::Notifications callbacks.
  • DwarfExprEval::Eval() and SymbolDataProvider methods issue asynchronous register and memory reads and writes against the target process.

Verification

Run these commands to build and test zxdb/symbols:

  • Build: fx build //src/developer/debug/zxdb/symbols
  • Test: fx test zxdb_tests