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

Modified to set `m_file_offset` to be the correct offset of the Code section. 
This also simplifies the code in ObjectFileWasm to avoid a special case for the 
code section in `ObjectFileWasm::SetLoadAddress`.
The DWARF code seems to only use GetFileAddress(), which still needs to return 
zero for the Code section.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72751

Files:
  
lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestWasm.py
  
lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm.yaml
  lldb/source/API/SystemInitializerFull.cpp
  lldb/source/Plugins/DynamicLoader/CMakeLists.txt
  lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt
  lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
  lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
  lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
  lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
  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
@@ -37,6 +37,7 @@
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 #include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
+#include "Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h"
 #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
 #include "Plugins/Instruction/PPC64/EmulateInstructionPPC64.h"
 #include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h"
@@ -246,6 +247,7 @@
   DynamicLoaderMacOSXDYLD::Initialize();
   DynamicLoaderMacOS::Initialize();
   DynamicLoaderPOSIXDYLD::Initialize();
+  wasm::DynamicLoaderWasmDYLD::Initialize();
   DynamicLoaderStatic::Initialize();
   DynamicLoaderWindowsDYLD::Initialize();
 
@@ -329,6 +331,7 @@
   DynamicLoaderMacOSXDYLD::Terminate();
   DynamicLoaderMacOS::Terminate();
   DynamicLoaderPOSIXDYLD::Terminate();
+  wasm::DynamicLoaderWasmDYLD::Terminate();
   DynamicLoaderStatic::Terminate();
   DynamicLoaderWindowsDYLD::Terminate();
 
Index: lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
===================================================================
--- lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -1,153 +1,151 @@
-//===-- ObjectFileWasm.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 LLDB_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
-#define LLDB_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
-
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/ArchSpec.h"
-
-namespace lldb_private {
-namespace wasm {
-
-/// Generic Wasm object file reader.
-///
-/// This class provides a generic wasm32 reader plugin implementing the
-/// ObjectFile protocol.
-class ObjectFileWasm : public ObjectFile {
-public:
-  static void Initialize();
-  static void Terminate();
-
-  static ConstString GetPluginNameStatic();
-  static const char *GetPluginDescriptionStatic() {
-    return "WebAssembly object file reader.";
-  }
-
-  static ObjectFile *
-  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
-                 lldb::offset_t data_offset, const FileSpec *file,
-                 lldb::offset_t file_offset, lldb::offset_t length);
-
-  static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
-                                          lldb::DataBufferSP &data_sp,
-                                          const lldb::ProcessSP &process_sp,
-                                          lldb::addr_t header_addr);
-
-  static size_t GetModuleSpecifications(const FileSpec &file,
-                                        lldb::DataBufferSP &data_sp,
-                                        lldb::offset_t data_offset,
-                                        lldb::offset_t file_offset,
-                                        lldb::offset_t length,
-                                        ModuleSpecList &specs);
-
-  /// PluginInterface protocol.
-  /// \{
-  ConstString GetPluginName() override { return GetPluginNameStatic(); }
-  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;
-
-  lldb::ByteOrder GetByteOrder() const override {
-    return m_arch.GetByteOrder();
-  }
-
-  bool IsExecutable() const override { return true; }
-
-  uint32_t GetAddressByteSize() const override {
-    return m_arch.GetAddressByteSize();
-  }
-
-  AddressClass GetAddressClass(lldb::addr_t file_addr) override {
-    return AddressClass::eInvalid;
-  }
-
-  Symtab *GetSymtab() override;
-
-  bool IsStripped() override { return true; }
-
-  void CreateSections(SectionList &unified_section_list) override;
-
-  void Dump(Stream *s) override;
-
-  ArchSpec GetArchitecture() override { return m_arch; }
-
-  UUID GetUUID() override { return m_uuid; }
-
-  uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
-
-  Type CalculateType() override { return eTypeExecutable; }
-
-  Strata CalculateStrata() override { return eStrataUser; }
-
-  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
-                      bool value_is_offset) override;
-
-  lldb_private::Address GetBaseAddress() override {
-    return IsInMemory() ? Address(m_memory_addr + m_code_section_offset)
-                        : Address(m_code_section_offset);
-  }
-  /// \}
-
-  /// 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,
-                 lldb::offset_t offset, lldb::offset_t length);
-  ObjectFileWasm(const lldb::ModuleSP &module_sp,
-                 lldb::DataBufferSP &header_data_sp,
-                 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
-
-  /// Wasm section decoding routines.
-  /// \{
-  bool DecodeNextSection(lldb::offset_t *offset_ptr);
-  bool DecodeSections();
-  /// \}
-
-  /// Read a range of bytes from the Wasm module.
-  DataExtractor ReadImageData(uint64_t offset, size_t size);
-
-  typedef struct section_info {
-    lldb::offset_t offset;
-    uint32_t size;
-    uint32_t id;
-    ConstString name;
-  } section_info_t;
-
-  /// Wasm section header dump routines.
-  /// \{
-  void DumpSectionHeader(llvm::raw_ostream &ostream, const section_info_t &sh);
-  void DumpSectionHeaders(llvm::raw_ostream &ostream);
-  /// \}
-
-  std::vector<section_info_t> m_sect_infos;
-  ArchSpec m_arch;
-  UUID m_uuid;
-  uint32_t m_code_section_offset;
-};
-
-} // namespace wasm
-} // namespace lldb_private
-#endif // LLDB_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
+//===-- ObjectFileWasm.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 LLDB_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
+#define LLDB_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
+
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+
+namespace lldb_private {
+namespace wasm {
+
+/// Generic Wasm object file reader.
+///
+/// This class provides a generic wasm32 reader plugin implementing the
+/// ObjectFile protocol.
+class ObjectFileWasm : public ObjectFile {
+public:
+  static void Initialize();
+  static void Terminate();
+
+  static ConstString GetPluginNameStatic();
+  static const char *GetPluginDescriptionStatic() {
+    return "WebAssembly object file reader.";
+  }
+
+  static ObjectFile *
+  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+                 lldb::offset_t data_offset, const FileSpec *file,
+                 lldb::offset_t file_offset, lldb::offset_t length);
+
+  static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
+                                          lldb::DataBufferSP &data_sp,
+                                          const lldb::ProcessSP &process_sp,
+                                          lldb::addr_t header_addr);
+
+  static size_t GetModuleSpecifications(const FileSpec &file,
+                                        lldb::DataBufferSP &data_sp,
+                                        lldb::offset_t data_offset,
+                                        lldb::offset_t file_offset,
+                                        lldb::offset_t length,
+                                        ModuleSpecList &specs);
+
+  /// PluginInterface protocol.
+  /// \{
+  ConstString GetPluginName() override { return GetPluginNameStatic(); }
+  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;
+
+  lldb::ByteOrder GetByteOrder() const override {
+    return m_arch.GetByteOrder();
+  }
+
+  bool IsExecutable() const override { return false; }
+
+  uint32_t GetAddressByteSize() const override {
+    return m_arch.GetAddressByteSize();
+  }
+
+  AddressClass GetAddressClass(lldb::addr_t file_addr) override {
+    return AddressClass::eInvalid;
+  }
+
+  Symtab *GetSymtab() override;
+
+  bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
+
+  void CreateSections(SectionList &unified_section_list) override;
+
+  void Dump(Stream *s) override;
+
+  ArchSpec GetArchitecture() override { return m_arch; }
+
+  UUID GetUUID() override { return m_uuid; }
+
+  uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
+
+  Type CalculateType() override { return eTypeSharedLibrary; }
+
+  Strata CalculateStrata() override { return eStrataUser; }
+
+  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
+                      bool value_is_offset) override;
+
+  lldb_private::Address GetBaseAddress() override {
+    return IsInMemory() ? Address(m_memory_addr) : Address(0);
+  }
+  /// \}
+
+  /// 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,
+                 lldb::offset_t offset, lldb::offset_t length);
+  ObjectFileWasm(const lldb::ModuleSP &module_sp,
+                 lldb::DataBufferSP &header_data_sp,
+                 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
+  /// Wasm section decoding routines.
+  /// \{
+  bool DecodeNextSection(lldb::offset_t *offset_ptr);
+  bool DecodeSections();
+  /// \}
+
+  /// Read a range of bytes from the Wasm module.
+  DataExtractor ReadImageData(lldb::offset_t offset, uint32_t size);
+
+  typedef struct section_info {
+    lldb::offset_t offset;
+    uint32_t size;
+    uint32_t id;
+    ConstString name;
+  } section_info_t;
+
+  /// Wasm section header dump routines.
+  /// \{
+  void DumpSectionHeader(llvm::raw_ostream &ostream, const section_info_t &sh);
+  void DumpSectionHeaders(llvm::raw_ostream &ostream);
+  /// \}
+
+  std::vector<section_info_t> m_sect_infos;
+  ArchSpec m_arch;
+  UUID m_uuid;
+};
+
+} // namespace wasm
+} // namespace lldb_private
+#endif // LLDB_PLUGINS_OBJECTFILE_WASM_OBJECTFILEWASM_H
Index: lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -233,7 +233,7 @@
                                offset_t data_offset, const FileSpec *file,
                                offset_t offset, offset_t length)
     : ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
-      m_arch("wasm32-unknown-unknown-wasm"), m_code_section_offset(0) {
+      m_arch("wasm32-unknown-unknown-wasm") {
   m_data.SetAddressByteSize(4);
 }
 
@@ -242,7 +242,7 @@
                                const lldb::ProcessSP &process_sp,
                                lldb::addr_t header_addr)
     : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
-      m_arch("wasm32-unknown-unknown-wasm"), m_code_section_offset(0) {}
+      m_arch("wasm32-unknown-unknown-wasm") {}
 
 bool ObjectFileWasm::ParseHeader() {
   // We already parsed the header during initialization.
@@ -264,15 +264,19 @@
   for (const section_info &sect_info : m_sect_infos) {
     SectionType section_type = eSectionTypeOther;
     ConstString section_name;
-    offset_t file_offset = 0;
-    addr_t vm_addr = 0;
-    size_t vm_size = 0;
+    offset_t file_offset = sect_info.offset & 0xffffffff;
+    addr_t vm_addr = file_offset;
+    size_t vm_size = sect_info.size;
 
     if (llvm::wasm::WASM_SEC_CODE == sect_info.id) {
       section_type = eSectionTypeCode;
       section_name = ConstString("code");
-      m_code_section_offset = sect_info.offset & 0xffffffff;
-      vm_size = sect_info.size;
+
+      // A code address in DWARF for WebAssembly is the offset of an
+      // instruction relative within the Code section of the WebAssembly file.
+      // For this reason Section::GetFileAddress() must return zero for the
+      // Code section.
+      vm_addr = 0;
     } else {
       section_type =
           llvm::StringSwitch<SectionType>(sect_info.name.GetStringRef())
@@ -300,10 +304,9 @@
       if (section_type == eSectionTypeOther)
         continue;
       section_name = sect_info.name;
-      file_offset = sect_info.offset & 0xffffffff;
-      if (IsInMemory()) {
-        vm_addr = sect_info.offset & 0xffffffff;
-        vm_size = sect_info.size;
+      if (!IsInMemory()) {
+        vm_size = 0;
+        vm_addr = 0;
       }
     }
 
@@ -343,6 +346,8 @@
   /// 0x0000000400000000 for module_id == 4.
   /// These 64-bit addresses will be used to request code ranges for a specific
   /// module from the WebAssembly engine.
+  assert(m_memory_addr == load_address);
+
   ModuleSP module_sp = GetModule();
   if (!module_sp)
     return false;
@@ -355,12 +360,10 @@
     return false;
 
   const size_t num_sections = section_list->GetSize();
-  size_t sect_idx = 0;
-
-  for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+  for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
     SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
-    if (target.GetSectionLoadList().SetSectionLoadAddress(
-            section_sp, load_address | section_sp->GetFileAddress())) {
+    if (target.SetSectionLoadAddress(
+            section_sp, load_address | section_sp->GetFileOffset())) {
       ++num_loaded_sections;
     }
   }
@@ -368,11 +371,11 @@
   return num_loaded_sections > 0;
 }
 
-DataExtractor ObjectFileWasm::ReadImageData(uint64_t offset, size_t size) {
+DataExtractor ObjectFileWasm::ReadImageData(offset_t offset, uint32_t size) {
   DataExtractor data;
   if (m_file) {
     if (offset < GetByteSize()) {
-      size = std::min(size, GetByteSize() - offset);
+      size = std::min(static_cast<uint64_t>(size), GetByteSize() - offset);
       auto buffer_sp = MapFileData(m_file, size, offset);
       return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
     }
Index: lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
@@ -0,0 +1,52 @@
+//===-- DynamicLoaderWasmDYLD.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_Plugins_DynamicLoaderWasmDYLD_h_
+#define liblldb_Plugins_DynamicLoaderWasmDYLD_h_
+
+#include "lldb/Target/DynamicLoader.h"
+
+namespace lldb_private {
+namespace wasm {
+
+class DynamicLoaderWasmDYLD : public DynamicLoader {
+public:
+  DynamicLoaderWasmDYLD(Process *process);
+
+  static void Initialize();
+  static void Terminate() {}
+
+  static ConstString GetPluginNameStatic();
+  static const char *GetPluginDescriptionStatic();
+
+  static DynamicLoader *CreateInstance(Process *process, bool force);
+
+  /// DynamicLoader
+  /// \{
+  lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file,
+                                     lldb::addr_t link_map_addr,
+                                     lldb::addr_t base_addr,
+                                     bool base_addr_is_offset) override;
+  void DidAttach() override;
+  void DidLaunch() override {}
+  Status CanLoadImage() override { return Status(); }
+  lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+                                                  bool stop) override;
+  /// \}
+
+  /// PluginInterface protocol.
+  /// \{
+  ConstString GetPluginName() override { return GetPluginNameStatic(); }
+  uint32_t GetPluginVersion() override { return 1; }
+  /// \}
+};
+
+} // namespace wasm
+} // namespace lldb_private
+
+#endif // liblldb_Plugins_DynamicLoaderWasmDYLD_h_
Index: lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
@@ -0,0 +1,81 @@
+//===-- DynamicLoaderWasmDYLD.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 "DynamicLoaderWasmDYLD.h"
+
+#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::wasm;
+
+DynamicLoaderWasmDYLD::DynamicLoaderWasmDYLD(Process *process)
+    : DynamicLoader(process) {}
+
+void DynamicLoaderWasmDYLD::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance);
+}
+
+ConstString DynamicLoaderWasmDYLD::GetPluginNameStatic() {
+  static ConstString g_plugin_name("wasm-dyld");
+  return g_plugin_name;
+}
+
+const char *DynamicLoaderWasmDYLD::GetPluginDescriptionStatic() {
+  return "Dynamic loader plug-in that watches for shared library "
+         "loads/unloads in WebAssembly engines.";
+}
+
+DynamicLoader *DynamicLoaderWasmDYLD::CreateInstance(Process *process,
+                                                     bool force) {
+  bool should_create = force;
+  if (!should_create) {
+    should_create =
+        (process->GetTarget().GetArchitecture().GetTriple().getArch() ==
+         llvm::Triple::wasm32);
+  }
+
+  if (should_create)
+    return new DynamicLoaderWasmDYLD(process);
+
+  return nullptr;
+}
+
+ModuleSP DynamicLoaderWasmDYLD::LoadModuleAtAddress(const FileSpec &file,
+                                                    addr_t link_map_addr,
+                                                    addr_t base_addr,
+                                                    bool base_addr_is_offset) {
+  if (ModuleSP module_sp = m_process->ReadModuleFromMemory(file, base_addr)) {
+    UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+    m_process->GetTarget().GetImages().AppendIfNeeded(module_sp);
+    return module_sp;
+  }
+
+  return ModuleSP();
+}
+
+void DynamicLoaderWasmDYLD::DidAttach() {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+  LLDB_LOGF(log, "DynamicLoaderWasmDYLD::%s()", __FUNCTION__);
+
+  // Ask the process for the list of loaded WebAssembly modules.
+  auto error = m_process->LoadModules();
+  LLDB_LOG_ERROR(log, std::move(error), "Couldn't load modules: {0}");
+}
+
+ThreadPlanSP DynamicLoaderWasmDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+                                                                 bool stop) {
+  return ThreadPlanSP();
+}
Index: lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_lldb_library(lldbPluginDynamicLoaderWasmDYLD PLUGIN
+  DynamicLoaderWasmDYLD.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbTarget
+  LINK_COMPONENTS
+    Support
+  )
Index: lldb/source/Plugins/DynamicLoader/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/DynamicLoader/CMakeLists.txt
+++ lldb/source/Plugins/DynamicLoader/CMakeLists.txt
@@ -4,3 +4,4 @@
 add_subdirectory(Static)
 add_subdirectory(Hexagon-DYLD)
 add_subdirectory(Windows-DYLD)
+add_subdirectory(wasm-DYLD)
Index: lldb/source/API/SystemInitializerFull.cpp
===================================================================
--- lldb/source/API/SystemInitializerFull.cpp
+++ lldb/source/API/SystemInitializerFull.cpp
@@ -45,6 +45,7 @@
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 #include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
+#include "Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h"
 #include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
 #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
 #include "Plugins/Instruction/MIPS/EmulateInstructionMIPS.h"
@@ -284,6 +285,7 @@
   DynamicLoaderMacOSXDYLD::Initialize();
   DynamicLoaderMacOS::Initialize();
   DynamicLoaderPOSIXDYLD::Initialize();
+  wasm::DynamicLoaderWasmDYLD::Initialize();
   DynamicLoaderStatic::Initialize();
   DynamicLoaderWindowsDYLD::Initialize();
 
@@ -377,6 +379,7 @@
   DynamicLoaderMacOSXDYLD::Terminate();
   DynamicLoaderMacOS::Terminate();
   DynamicLoaderPOSIXDYLD::Terminate();
+  wasm::DynamicLoaderWasmDYLD::Terminate();
   DynamicLoaderStatic::Terminate();
   DynamicLoaderWindowsDYLD::Terminate();
 
Index: lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm.yaml
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm.yaml
@@ -0,0 +1,25 @@
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+
+  - Type:            CODE
+    Functions:
+      - Index:           0
+        Locals:
+          - Type:            I32
+            Count:           6
+        Body:            238080808000210141102102200120026B21032003200036020C200328020C2104200328020C2105200420056C210620060F0B
+  - 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/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestWasm.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestWasm.py
@@ -0,0 +1,124 @@
+import lldb
+import binascii
+import struct
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+def format_register_value(val):
+    """
+    Encode each byte by two hex digits in little-endian order.
+    """
+    return ''.join(x.encode('hex') for x in struct.pack('<Q', val))
+
+class TestWasm(GDBRemoteTestBase):
+
+    def setUp(self):
+        super(TestWasm, self).setUp()
+        self._initial_platform = lldb.DBG.GetSelectedPlatform()
+
+    def tearDown(self):
+        lldb.DBG.SetSelectedPlatform(self._initial_platform)
+        super(TestWasm, self).tearDown()
+
+    def test_connect(self):
+
+        class MyResponder(MockGDBServerResponder):
+            load_address = 0x400000000
+            current_pc = 0x40000000a
+
+            def __init__(self, obj_path):
+                self._obj_path = obj_path
+                MockGDBServerResponder.__init__(self)
+
+            def respond(self, packet):
+                if packet == "qProcessInfo":
+                    return self.qProcessInfo()
+                if packet[0:13] == "qRegisterInfo":
+                    return self.qRegisterInfo(packet[13:])
+                return MockGDBServerResponder.respond(self, packet)
+
+            def qSupported(self, client_supported):
+                return "qXfer:libraries:read+;PacketSize=1000;vContSupported-"
+
+            def qHostInfo(self):
+                return ""
+
+            def QEnableErrorStrings(self):
+                return ""
+
+            def qfThreadInfo(self):
+                return "OK"
+
+            def qRegisterInfo(self, index):
+                if (index == 0):
+                    return "name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;"
+                return "E45"
+
+            def qProcessInfo(self):
+                return "pid:1;ppid:1;uid:1;gid:1;euid:1;egid:1;name:%s;triple:%s;ptrsize:4" % (hex_encode_bytes("lldb"), hex_encode_bytes("wasm32-unknown-unknown-wasm"))
+
+            def haltReason(self):
+                return "T05thread-pcs:" + format(self.current_pc, 'x') + ";thread:1;"
+
+            def readRegister(self, register):                
+                return format_register_value(self.current_pc)
+
+            def qXferRead(self, obj, annex, offset, length):
+                if obj == "libraries":
+                    xml = '<library-list><library name=\"%s\"><section address=\"%d\"/></library></library-list>' % ("test_wasm", self.load_address)
+                    return xml, False
+                else:
+                    return None, False
+
+            def readMemory(self, addr, length):
+                result = ""
+                with open(self._obj_path, mode='rb') as file:
+                    file_content = bytearray(file.read())                    
+                    addr_from = addr - self.load_address
+                    addr_to = addr_from + min(length, len(file_content) - addr_from)
+                    for i in range(addr_from, addr_to):
+                        result += format(file_content[i], '02x')
+                    file.close()
+                return result
+
+        """Test connecting to a WebAssembly engine via GDB-remote"""
+
+        yaml_path = "test_wasm.yaml"
+        yaml_base, ext = os.path.splitext(yaml_path)
+        obj_path = self.getBuildArtifact(yaml_base)
+        self.yaml2obj(yaml_path, obj_path)
+
+        self.server.responder = MyResponder(obj_path)
+
+        target = self.dbg.CreateTarget("")
+        process = self.connect(target)
+        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateStopped])
+    
+        num_modules = target.GetNumModules()
+        self.assertEquals(1, num_modules)
+
+        module = target.GetModuleAtIndex(0)
+        num_sections = module.GetNumSections()
+        self.assertEquals(5, num_sections)
+
+        code_section = module.GetSectionAtIndex(0)
+        self.assertEquals("code", code_section.GetName())
+        self.assertEquals(0x40000000a, code_section.GetLoadAddress(target))
+
+        debug_info_section = module.GetSectionAtIndex(1)
+        self.assertEquals(".debug_info", debug_info_section.GetName())
+        self.assertEquals(0x400000050, debug_info_section.GetLoadAddress(target))
+
+        debug_abbrev_section = module.GetSectionAtIndex(2)
+        self.assertEquals(".debug_abbrev", debug_abbrev_section.GetName())
+        self.assertEquals(0x400000062, debug_abbrev_section.GetLoadAddress(target))
+
+        debug_line_section = module.GetSectionAtIndex(3)
+        self.assertEquals(".debug_line", debug_line_section.GetName())
+        self.assertEquals(0x400000072, debug_line_section.GetLoadAddress(target))
+
+        debug_str_section = module.GetSectionAtIndex(4)
+        self.assertEquals(".debug_str", debug_str_section.GetName())
+        self.assertEquals(0x400000081, debug_str_section.GetLoadAddress(target))
+
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to