https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/211301
The Wasm name section names functions but not data, so LLDB recovers data symbols from the DWARF. It only did so for variables with a linkage name, such as a C++ vtable, so a plain C global, which has only a DW_AT_name, got no symbol and its address did not resolve back to a name. Use the source name when there is no linkage name. >From 5c7acf900b7c21da616f2e7498e789f42f45a32d Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <[email protected]> Date: Wed, 22 Jul 2026 08:29:56 -0700 Subject: [PATCH] [lldb] Synthesize data symbols for plain C globals on WebAssembly The Wasm name section names functions but not data, so LLDB recovers data symbols from the DWARF. It only did so for variables with a linkage name, such as a C++ vtable, so a plain C global, which has only a DW_AT_name, got no symbol and its address did not resolve back to a name. Use the source name when there is no linkage name. --- .../SymbolFile/DWARF/SymbolFileWasm.cpp | 34 +++++--- .../SymbolFile/DWARF/wasm-data-symbol.yaml | 84 +++++++++++++++++++ 2 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/wasm-data-symbol.yaml diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp index b568e104874a4..e9afda8a59aa8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp @@ -33,12 +33,13 @@ SymbolFileWasm::~SymbolFileWasm() = default; void SymbolFileWasm::AddSymbols(Symtab &symtab) { SymbolFileDWARF::AddSymbols(symtab); - // The Wasm "name" section names functions but not data, so data symbols such - // as C++ vtables are absent from the symbol table. Recover them from the - // DWARF. A subprogram's mangled name goes onto its existing code symbol. A - // global variable at a static DW_OP_addr, such as a vtable, gets a - // synthesized data symbol so its address resolves back to "vtable for X", - // which is how the Itanium C++ runtime recovers a dynamic type. + // The Wasm "name" section names functions but not data, so data symbols are + // absent from the symbol table. Recover them from the DWARF. A subprogram's + // mangled name goes onto its existing code symbol. A global variable at a + // static DW_OP_addr gets a synthesized data symbol so that its address + // resolves back to the variable's name. This is how the Itanium C++ runtime + // recovers a dynamic type from a vtable ("vtable for X"), and it also lets a + // plain C global resolve back to its name. ModuleSP module_sp = GetObjectFile()->GetModule(); SectionList *section_list = module_sp ? module_sp->GetSectionList() : nullptr; @@ -55,12 +56,14 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) { continue; DWARFDIE die(unit, &entry); - const char *mangled = - die.GetMangledName(/*substitute_name_allowed=*/false); - if (!mangled) - continue; if (tag == DW_TAG_subprogram) { + // Only a mangled (linkage) name is worth putting onto a code symbol. + // The source name is already carried by the Wasm name section. + const char *mangled = + die.GetMangledName(/*substitute_name_allowed=*/false); + if (!mangled) + continue; const addr_t file_addr = die.GetAttributeValueAsAddress(DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (file_addr == LLDB_INVALID_ADDRESS) @@ -71,7 +74,14 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) { continue; } - // A vtable's location is a plain DW_OP_addr. + // A global variable has no symbol at all. Use its linkage name, or the + // source name when there is none (plain C globals have only a + // DW_AT_name). + const char *name = die.GetMangledName(/*substitute_name_allowed=*/true); + if (!name) + continue; + + // A global's location is a plain DW_OP_addr. if (!section_list) continue; DWARFAttributes attributes = die.GetAttributes(); @@ -105,7 +115,7 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) { // the address index before the remaining vtables are added, mis-sizing // them. symtab.AddSymbol(Symbol( - /*symID=*/0, Mangled(ConstString(mangled)), eSymbolTypeData, + /*symID=*/0, Mangled(ConstString(name)), eSymbolTypeData, /*external=*/true, /*is_debug=*/false, /*is_trampoline=*/false, /*is_artificial=*/false, AddressRange(addr, 0), /*size_is_valid=*/false, /*contains_linker_annotations=*/false, diff --git a/lldb/test/Shell/SymbolFile/DWARF/wasm-data-symbol.yaml b/lldb/test/Shell/SymbolFile/DWARF/wasm-data-symbol.yaml new file mode 100644 index 0000000000000..42a2ee1c25aad --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/wasm-data-symbol.yaml @@ -0,0 +1,84 @@ +# A plain C global has a DW_AT_name but no DW_AT_linkage_name, and the +# WebAssembly "name" section names only functions, not data. LLDB must still +# synthesize a data symbol from the DWARF so the global's address resolves back +# to its name (e.g. so a pointer into it can be symbolicated). Previously only +# variables with a linkage name (such as a C++ vtable) were recovered. +# +# The global g_global lives at linear-memory address 0x10000 and the pointer +# g_keep at 0x10004. + +# RUN: yaml2obj %s -o %t +# RUN: %lldb %t \ +# RUN: -o "image lookup -a 0x10000" \ +# RUN: -o "image lookup -a 0x10004" \ +# RUN: -o exit 2>&1 | FileCheck %s + +# CHECK-LABEL: image lookup -a 0x10000 +# CHECK: Summary: {{.*}}g_global +# CHECK-LABEL: image lookup -a 0x10004 +# CHECK: Summary: {{.*}}g_keep + +--- !WASM +FileHeader: + Version: 0x1 +Sections: + - Type: TYPE + Signatures: + - Index: 0 + ParamTypes: [] + ReturnTypes: [] + - Type: FUNCTION + FunctionTypes: [ 0 ] + - Type: MEMORY + Memories: + - Minimum: 0x2 + - Type: GLOBAL + Globals: + - Index: 0 + Type: I32 + Mutable: true + InitExpr: + Opcode: I32_CONST + Value: 65536 + - Type: EXPORT + Exports: + - Name: memory + Kind: MEMORY + Index: 0 + - Type: CODE + Functions: + - Index: 0 + Locals: [] + Body: 0B + - Type: DATA + Segments: + - SectionOffset: 8 + InitFlags: 0 + Offset: + Opcode: I32_CONST + Value: 65536 + Content: 2A00000000000100 + - Type: CUSTOM + Name: .debug_abbrev + Payload: 011101250E1305030E10171B0E0000023400030E49133F193A0B3B0B02180000032400030E3E0B0B0B0000040F004913000000 + - Type: CUSTOM + Name: .debug_info + Payload: 4900000004000000000004012A0000001D0023000000000000000B000000021A0000002F0000000101050300000100030000000005040204000000470000000102050304000100042F00000000 + - Type: CUSTOM + Name: .debug_str + Payload: 696E7400675F6B656570002F746D702F7761736D726570726F00675F676C6F62616C00676C6F622E6300636C616E672076657273696F6E2032322E312E302D776173692D73646B202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A65637420343433346461626236393931363835366238323466363861363462303239633637313735653533322900 + - Type: CUSTOM + Name: .debug_line + Payload: 2400000004001E000000010101FB0E0D00010101010000000100000100676C6F622E630000000000 + - Type: CUSTOM + Name: name + FunctionNames: + - Index: 0 + Name: __wasm_call_ctors + GlobalNames: + - Index: 0 + Name: __stack_pointer + DataSegmentNames: + - Index: 0 + Name: .data +... _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
