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 data symbols such as 
C++ vtables have no entry in the symbol table. The Itanium C++ runtime resolves 
a dynamic type by looking up the symbol at an object's vtable pointer and 
reading its "vtable for X" name. With no such symbol, dynamic type resolution 
fails and falls back to the static type.

The vtable's address and mangled name are available in the DWARF as a 
DW_TAG_variable with a DW_OP_addr location and a DW_AT_linkage_name. Extend 
SymbolFileWasm::AddSymbols to synthesize a data symbol for every global 
variable of that shape, so its address resolves back to the mangled name such 
as "vtable for X". The size is computed by Symtab to from the gap to the next 
symbol.

Assisted-by: Claude

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


1 Files Affected:

- (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp (+63-10) 


``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp
index 0443d18953e1c..b568e104874a4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileWasm.cpp
@@ -11,6 +11,10 @@
 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
 #include "Utility/WasmVirtualRegisters.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Symbol/Symtab.h"
 #include "lldb/Utility/LLDBLog.h"
@@ -29,9 +33,15 @@ SymbolFileWasm::~SymbolFileWasm() = default;
 void SymbolFileWasm::AddSymbols(Symtab &symtab) {
   SymbolFileDWARF::AddSymbols(symtab);
 
-  // Copy each function's mangled name from its DWARF DW_AT_linkage_name onto
-  // the matching symbol. The match is by file address: a subprogram's
-  // DW_AT_low_pc resolves to the same code-section file address as its symbol.
+  // 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.
+  ModuleSP module_sp = GetObjectFile()->GetModule();
+  SectionList *section_list = module_sp ? module_sp->GetSectionList() : 
nullptr;
+
   DWARFDebugInfo &debug_info = DebugInfo();
   const size_t num_units = debug_info.GetNumUnits();
   for (size_t i = 0; i < num_units; ++i) {
@@ -40,7 +50,8 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) {
       continue;
 
     for (const DWARFDebugInfoEntry &entry : unit->dies()) {
-      if (entry.Tag() != DW_TAG_subprogram)
+      const dw_tag_t tag = entry.Tag();
+      if (tag != DW_TAG_subprogram && tag != DW_TAG_variable)
         continue;
 
       DWARFDIE die(unit, &entry);
@@ -49,14 +60,56 @@ void SymbolFileWasm::AddSymbols(Symtab &symtab) {
       if (!mangled)
         continue;
 
-      const addr_t file_addr =
-          die.GetAttributeValueAsAddress(DW_AT_low_pc, LLDB_INVALID_ADDRESS);
-      if (file_addr == LLDB_INVALID_ADDRESS)
+      if (tag == DW_TAG_subprogram) {
+        const addr_t file_addr =
+            die.GetAttributeValueAsAddress(DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+        if (file_addr == LLDB_INVALID_ADDRESS)
+          continue;
+        Symbol *symbol = symtab.FindSymbolAtFileAddress(file_addr);
+        if (symbol && !symbol->GetMangled().GetMangledName())
+          symbol->GetMangled().SetMangledName(ConstString(mangled));
+        continue;
+      }
+
+      // A vtable's location is a plain DW_OP_addr.
+      if (!section_list)
+        continue;
+      DWARFAttributes attributes = die.GetAttributes();
+      DWARFFormValue location;
+      bool has_location = false;
+      for (size_t attr_idx = 0; attr_idx < attributes.Size(); ++attr_idx) {
+        if (attributes.AttributeAtIndex(attr_idx) == DW_AT_location) {
+          has_location = attributes.ExtractFormValueAtIndex(attr_idx, 
location);
+          break;
+        }
+      }
+      if (!has_location || !DWARFFormValue::IsBlockForm(location.Form()))
+        continue;
+
+      const DWARFDataExtractor &data = die.GetData();
+      DWARFExpression expr(
+          DataExtractor(data, location.BlockData() - data.GetDataStart(),
+                        location.Unsigned()));
+      llvm::Expected<addr_t> file_addr = expr.GetLocation_DW_OP_addr(unit);
+      if (!file_addr) {
+        llvm::consumeError(file_addr.takeError());
+        continue;
+      }
+
+      Address addr(*file_addr, section_list);
+      if (!addr.IsSectionOffset())
         continue;
 
-      Symbol *symbol = symtab.FindSymbolAtFileAddress(file_addr);
-      if (symbol && !symbol->GetMangled().GetMangledName())
-        symbol->GetMangled().SetMangledName(ConstString(mangled));
+      // Leave the size unset for Symtab to compute from the gap to the next
+      // symbol. Don't look the address up in the symtab here. That would build
+      // the address index before the remaining vtables are added, mis-sizing
+      // them.
+      symtab.AddSymbol(Symbol(
+          /*symID=*/0, Mangled(ConstString(mangled)), eSymbolTypeData,
+          /*external=*/true, /*is_debug=*/false, /*is_trampoline=*/false,
+          /*is_artificial=*/false, AddressRange(addr, 0),
+          /*size_is_valid=*/false, /*contains_linker_annotations=*/false,
+          /*flags=*/0));
     }
   }
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/207235
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to