[Lldb-commits] [lldb] 6f2ba12 - [lldb] Synthesize data symbols for plain C globals on WebAssembly (#211301)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Jul 22 11:56:17 PDT 2026
Author: Jonas Devlieghere
Date: 2026-07-22T13:56:12-05:00
New Revision: 6f2ba122cbd047c77ec6ab26598523c7aa4ef853
URL: https://github.com/llvm/llvm-project/commit/6f2ba122cbd047c77ec6ab26598523c7aa4ef853
DIFF: https://github.com/llvm/llvm-project/commit/6f2ba122cbd047c77ec6ab26598523c7aa4ef853.diff
LOG: [lldb] Synthesize data symbols for plain C globals on WebAssembly (#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.
Added:
lldb/test/Shell/SymbolFile/DWARF/wasm-data-symbol.yaml
Modified:
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp
Removed:
################################################################################
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
+...
More information about the lldb-commits
mailing list