paolosev updated this revision to Diff 238177.
paolosev added a comment.

Rebasing from D71575 <https://reviews.llvm.org/D71575>.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72650/new/

https://reviews.llvm.org/D72650

Files:
  lldb/source/API/SystemInitializerFull.cpp
  lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
  lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
  lldb/source/Plugins/SymbolVendor/CMakeLists.txt
  lldb/source/Plugins/SymbolVendor/wasm/CMakeLists.txt
  lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
  lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
  lldb/test/Shell/ObjectFile/wasm/Inputs/wasm-external_debug_info.yaml
  lldb/test/Shell/ObjectFile/wasm/Inputs/wasm-stripped-debug-info.yaml
  lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
  lldb/tools/lldb-test/SystemInitializerTest.cpp

Index: lldb/tools/lldb-test/SystemInitializerTest.cpp
===================================================================
--- lldb/tools/lldb-test/SystemInitializerTest.cpp
+++ lldb/tools/lldb-test/SystemInitializerTest.cpp
@@ -76,6 +76,7 @@
 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
 #include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
+#include "Plugins/SymbolVendor/wasm/SymbolVendorWasm.h"
 #include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h"
 #include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
 #include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
@@ -201,6 +202,7 @@
   SymbolFileDWARF::Initialize();
   SymbolFilePDB::Initialize();
   SymbolFileSymtab::Initialize();
+  wasm::SymbolVendorWasm::Initialize();
   UnwindAssemblyInstEmulation::Initialize();
   UnwindAssembly_x86::Initialize();
   EmulateInstructionARM64::Initialize();
@@ -288,6 +290,7 @@
   SymbolFileDWARF::Terminate();
   SymbolFilePDB::Terminate();
   SymbolFileSymtab::Terminate();
+  wasm::SymbolVendorWasm::Terminate();
   UnwindAssembly_x86::Terminate();
   UnwindAssemblyInstEmulation::Terminate();
   EmulateInstructionARM64::Terminate();
Index: lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
===================================================================
--- /dev/null
+++ lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
@@ -0,0 +1,50 @@
+# RUN: rm -rf %t.dir
+# RUN: mkdir %t.dir
+# RUN: cd %t.dir
+# RUN: yaml2obj %p/Inputs/wasm-external_debug_info.yaml > %t.dir/test.wasm
+# RUN: yaml2obj %p/Inputs/wasm-stripped-debug-info.yaml > %t.dir/test_sym.wasm
+# RUN: lldb-test object-file %t.dir/test.wasm | FileCheck %s
+
+# This test checks that SymbolVendorWasm correctly loads DWARF debug sections
+# that have been stripped out into a separated Wasm module. The original Wasm
+# module contains a "external_debug_info" custom section with the absolute or
+# relative path of the debug module.
+
+# CHECK: Plugin name: wasm
+# CHECK: Architecture: wasm32-unknown-unknown-wasm
+# CHECK: UUID: 
+# CHECK: Executable: true
+# CHECK: Stripped: true
+# CHECK: Type: executable
+# CHECK: Strata: user
+# CHECK: Base VM address: 0xa
+
+# CHECK: Name: code
+# CHECK: Type: code
+# CHECK: VM address: 0x0
+# CHECK: VM size: 56
+# CHECK: File size: 56
+
+# CHECK: Name: .debug_info
+# CHECK: Type: dwarf-info
+# CHECK: VM address: 0x0
+# CHECK: VM size: 0
+# CHECK: File size: 2
+
+# CHECK: Name: .debug_abbrev
+# CHECK: Type: dwarf-abbrev
+# CHECK: VM address: 0x0
+# CHECK: VM size: 0
+# CHECK: File size: 2
+
+# CHECK: Name: .debug_line
+# CHECK: Type: dwarf-line
+# CHECK: VM address: 0x0
+# CHECK: VM size: 0
+# CHECK: File size: 2
+
+# CHECK: Name: .debug_str
+# CHECK: Type: dwarf-str
+# CHECK: VM address: 0x0
+# CHECK: VM size: 0
+# CHECK: File size: 3
\ No newline at end of file
Index: lldb/test/Shell/ObjectFile/wasm/Inputs/wasm-stripped-debug-info.yaml
===================================================================
--- /dev/null
+++ lldb/test/Shell/ObjectFile/wasm/Inputs/wasm-stripped-debug-info.yaml
@@ -0,0 +1,18 @@
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+
+  - Type:            CUSTOM
+    Name:            .debug_info
+    Payload:         4C00
+  - Type:            CUSTOM
+    Name:            .debug_abbrev
+    Payload:         0111
+  - Type:            CUSTOM
+    Name:            .debug_line
+    Payload:         5100
+  - Type:            CUSTOM
+    Name:            .debug_str
+    Payload:         636CFF
+...
Index: lldb/test/Shell/ObjectFile/wasm/Inputs/wasm-external_debug_info.yaml
===================================================================
--- /dev/null
+++ lldb/test/Shell/ObjectFile/wasm/Inputs/wasm-external_debug_info.yaml
@@ -0,0 +1,15 @@
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+          - Type:            I32
+            Count:           6
+        Body:            238080808000210141102102200120026B21032003200036020C200328020C2104200328020C2105200420056C210620060F0B
+  - Type:            CUSTOM
+    Name:            external_debug_info
+    Payload:         0D746573745F73796D2E7761736D  # test_sym.wasm
+...
Index: lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h
@@ -0,0 +1,44 @@
+//===-- SymbolVendorWasm.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_SymbolVendorWasm_h_
+#define liblldb_SymbolVendorWasm_h_
+
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+namespace wasm {
+
+class SymbolVendorWasm : public lldb_private::SymbolVendor {
+public:
+  SymbolVendorWasm(const lldb::ModuleSP &module_sp);
+
+  static void Initialize();
+  static void Terminate();
+  static lldb_private::ConstString GetPluginNameStatic();
+  static const char *GetPluginDescriptionStatic();
+
+  static lldb_private::SymbolVendor *
+  CreateInstance(const lldb::ModuleSP &module_sp,
+                 lldb_private::Stream *feedback_strm);
+
+  /// PluginInterface protocol.
+  /// \{
+  lldb_private::ConstString GetPluginName() override;
+  uint32_t GetPluginVersion() override;
+  /// \}
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(SymbolVendorWasm);
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif // liblldb_SymbolVendorWasm_h_
Index: lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -0,0 +1,145 @@
+//===-- SymbolVendorWasm.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolVendorWasm.h"
+
+#include <string.h>
+
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::wasm;
+
+// SymbolVendorWasm constructor
+SymbolVendorWasm::SymbolVendorWasm(const lldb::ModuleSP &module_sp)
+    : SymbolVendor(module_sp) {}
+
+void SymbolVendorWasm::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void SymbolVendorWasm::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString SymbolVendorWasm::GetPluginNameStatic() {
+  static ConstString g_name("WASM");
+  return g_name;
+}
+
+const char *SymbolVendorWasm::GetPluginDescriptionStatic() {
+  return "Symbol vendor for WASM that looks for dwo files that match "
+         "executables.";
+}
+
+// CreateInstance
+//
+// Platforms can register a callback to use when creating symbol vendors to
+// allow for complex debug information file setups, and to also allow for
+// finding separate debug information files.
+SymbolVendor *
+SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
+                                 lldb_private::Stream *feedback_strm) {
+  if (!module_sp)
+    return nullptr;
+
+  ObjectFileWasm *obj_file =
+      llvm::dyn_cast_or_null<ObjectFileWasm>(module_sp->GetObjectFile());
+  if (!obj_file)
+    return nullptr;
+
+  // If the main object file already contains debug info, then we are done.
+  if (obj_file->GetSectionList()->FindSectionByType(
+          lldb::eSectionTypeDWARFDebugInfo, true))
+    return nullptr;
+
+  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+  Timer scoped_timer(func_cat, "SymbolVendorWasm::CreateInstance (module = %s)",
+                     module_sp->GetFileSpec().GetPath().c_str());
+
+  ModuleSpec module_spec;
+  module_spec.GetFileSpec() = obj_file->GetFileSpec();
+  FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+  module_spec.GetUUID() = obj_file->GetUUID();
+
+  // A Wasm module may have a custom section named "external_debug_info" whose
+  // content is the absolute or relative path of the Wasm module that contains
+  // debug symbols for this module.
+  llvm::Optional<FileSpec> symbol_file_spec =
+      obj_file->GetExternalDebugInfoFileSpec();
+  if (!symbol_file_spec)
+    return nullptr;
+  module_spec.GetSymbolFileSpec() = *symbol_file_spec;
+
+  FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
+  FileSpec sym_fspec =
+      Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+  if (!sym_fspec)
+    return nullptr;
+
+  DataBufferSP sym_file_data_sp;
+  lldb::offset_t sym_file_data_offset = 0;
+  ObjectFileSP sym_objfile_sp = ObjectFile::FindPlugin(
+      module_sp, &sym_fspec, 0, FileSystem::Instance().GetByteSize(sym_fspec),
+      sym_file_data_sp, sym_file_data_offset);
+  if (!sym_objfile_sp)
+    return nullptr;
+
+  // This objfile is for debugging purposes.
+  sym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
+
+  SymbolVendorWasm *symbol_vendor = new SymbolVendorWasm(module_sp);
+
+  // Get the module unified section list and add our debug sections to
+  // that.
+  SectionList *module_section_list = module_sp->GetSectionList();
+  SectionList *objfile_section_list = sym_objfile_sp->GetSectionList();
+
+  static const SectionType g_sections[] = {
+      eSectionTypeDWARFDebugAbbrev,   eSectionTypeDWARFDebugAddr,
+      eSectionTypeDWARFDebugAranges,  eSectionTypeDWARFDebugCuIndex,
+      eSectionTypeDWARFDebugFrame,    eSectionTypeDWARFDebugInfo,
+      eSectionTypeDWARFDebugLine,     eSectionTypeDWARFDebugLineStr,
+      eSectionTypeDWARFDebugLoc,      eSectionTypeDWARFDebugLocLists,
+      eSectionTypeDWARFDebugMacInfo,  eSectionTypeDWARFDebugMacro,
+      eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
+      eSectionTypeDWARFDebugRanges,   eSectionTypeDWARFDebugRngLists,
+      eSectionTypeDWARFDebugStr,      eSectionTypeDWARFDebugStrOffsets,
+      eSectionTypeDWARFDebugTypes};
+  for (SectionType section_type : g_sections) {
+    if (SectionSP section_sp =
+            objfile_section_list->FindSectionByType(section_type, true)) {
+      if (SectionSP module_section_sp =
+              module_section_list->FindSectionByType(section_type, true))
+        module_section_list->ReplaceSection(module_section_sp->GetID(),
+                                            section_sp);
+      else
+        module_section_list->AddSection(section_sp);
+    }
+  }
+
+  symbol_vendor->AddSymbolFileRepresentation(sym_objfile_sp);
+  return symbol_vendor;
+}
+
+// PluginInterface protocol
+ConstString SymbolVendorWasm::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t SymbolVendorWasm::GetPluginVersion() { return 1; }
Index: lldb/source/Plugins/SymbolVendor/wasm/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolVendor/wasm/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_lldb_library(lldbPluginSymbolVendorWasm PLUGIN
+  SymbolVendorWasm.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbHost
+    lldbSymbol
+    lldbPluginObjectFileWasm
+  )
Index: lldb/source/Plugins/SymbolVendor/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/SymbolVendor/CMakeLists.txt
+++ lldb/source/Plugins/SymbolVendor/CMakeLists.txt
@@ -3,3 +3,4 @@
 endif()
 
 add_subdirectory(ELF)
+add_subdirectory(wasm)
Index: lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
===================================================================
--- lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -52,6 +52,15 @@
   uint32_t GetPluginVersion() override { return 1; }
   /// \}
 
+  /// LLVM RTTI support
+  /// \{
+  static char ID;
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ObjectFile::isA(ClassID);
+  }
+  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+  /// \}
+
   /// ObjectFile Protocol.
   /// \{
   bool ParseHeader() override;
@@ -97,6 +106,12 @@
   }
   /// \}
 
+  /// A Wasm module that has external DWARF debug information should contain a
+  /// custom section named "external_debug_info", whose payload is an UTF-8
+  /// encoded string that points to a Wasm module that contains the debug
+  /// information for this module.
+  llvm::Optional<FileSpec> GetExternalDebugInfoFileSpec();
+
 private:
   ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
                  lldb::offset_t data_offset, const FileSpec *file,
Index: lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -72,6 +72,8 @@
   return ConstString(str);
 }
 
+char ObjectFileWasm::ID;
+
 void ObjectFileWasm::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 GetPluginDescriptionStatic(), CreateInstance,
@@ -177,6 +179,9 @@
     return false;
 
   if (section_id == llvm::wasm::WASM_SEC_CUSTOM) {
+    // Custom sections have the id 0. Their contents consist of a name
+    // identifying the custom section, followed by an uninterpreted sequence
+    // of bytes.
     lldb::offset_t prev_offset = c.tell();
     llvm::Optional<ConstString> sect_name = GetWasmString(data, c);
     if (!sect_name)
@@ -389,6 +394,24 @@
   return data;
 }
 
+llvm::Optional<FileSpec> ObjectFileWasm::GetExternalDebugInfoFileSpec() {
+  static ConstString g_sect_name_external_debug_info("external_debug_info");
+
+  for (const section_info &sect_info : m_sect_infos) {
+    if (g_sect_name_external_debug_info == sect_info.name) {
+      const uint32_t kBufferSize = 1024;
+      DataExtractor section_header_data =
+          ReadImageData(sect_info.offset, kBufferSize);
+      llvm::DataExtractor data = section_header_data.GetAsLLVM();
+      llvm::DataExtractor::Cursor c(0);
+      llvm::Optional<ConstString> symbols_url = GetWasmString(data, c);
+      if (symbols_url)
+        return FileSpec(symbols_url->GetStringRef());
+    }
+  }
+  return llvm::None;
+}
+
 void ObjectFileWasm::Dump(Stream *s) {
   ModuleSP module_sp(GetModule());
   if (!module_sp)
Index: lldb/source/API/SystemInitializerFull.cpp
===================================================================
--- lldb/source/API/SystemInitializerFull.cpp
+++ lldb/source/API/SystemInitializerFull.cpp
@@ -91,6 +91,7 @@
 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
 #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
 #include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
+#include "Plugins/SymbolVendor/wasm/SymbolVendorWasm.h"
 #include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h"
 #include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
 #include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
@@ -234,6 +235,7 @@
   SymbolFileDWARF::Initialize();
   SymbolFilePDB::Initialize();
   SymbolFileSymtab::Initialize();
+  wasm::SymbolVendorWasm::Initialize();
   UnwindAssemblyInstEmulation::Initialize();
   UnwindAssembly_x86::Initialize();
 
@@ -326,6 +328,7 @@
   ThreadSanitizerRuntime::Terminate();
   UndefinedBehaviorSanitizerRuntime::Terminate();
   MainThreadCheckerRuntime::Terminate();
+  wasm::SymbolVendorWasm::Terminate();
   SymbolVendorELF::Terminate();
   breakpad::SymbolFileBreakpad::Terminate();
   SymbolFileDWARF::Terminate();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to