[Lldb-commits] [lldb] [lldb] Synthesize data symbols for plain C globals on WebAssembly (PR #211301)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jul 22 14:56:36 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/211301.diff


2 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp (+22-12) 
- (added) lldb/test/Shell/SymbolFile/DWARF/wasm-data-symbol.yaml (+84) 


``````````diff
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
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/211301


More information about the lldb-commits mailing list