paolosev created this revision.
paolosev added reviewers: labath, clayborg, aprantl, sbc100, teemperor.
paolosev added a project: LLDB.
Herald added subscribers: lldb-commits, sunfish, aheejin, jgravelle-google, 
mgorny.
paolosev added a comment.

What is the best way to test this class?


Add a dynamic loader plug-in class for WebAssembly modules.

Depends on D72650 <https://reviews.llvm.org/D72650>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72751

Files:
  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

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,132 @@
+//===-- 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 "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;
+}
+
+/// In WebAssembly, linear memory is disjointed from code space. The VM can load
+/// multiple instances of a module, which logically share the same code.
+/// Currently we only support wasm32, which uses a 32-bit address space for the
+/// code.
+/// We represent a code address in LLDB as a 64-bit address with the format:
+/// 63            32 31             0
+/// +---------------+---------------+
+/// +   module_id   |     offset    |
+/// +---------------+---------------+
+/// where the lower 32 bits represent a module offset (relative to the module
+/// start not to the beginning of the code section) and the higher 32 bits
+/// uniquely identify the module in the WebAssembly VM.
+/// This method should be called for each Wasm module loaded in the debuggee,
+/// with base_addr = 0x{module_id}|00000000 (for example 0x0000000100000000).
+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}");
+
+  ModuleList loaded_module_list;
+  const ModuleList &module_list = m_process->GetTarget().GetImages();
+  const size_t num_modules = module_list.GetSize();
+  for (uint32_t idx = 0; idx < num_modules; ++idx) {
+    ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx));
+    if (!module_sp)
+      continue;
+
+    ObjectFile *image_object_file = module_sp->GetObjectFile();
+    if (!image_object_file)
+      continue;
+
+    lldb::addr_t code_load_address =
+        image_object_file->GetBaseAddress().GetOffset();
+    lldb::addr_t image_load_address = code_load_address & 0xffffffff00000000;
+
+    SectionList *section_list = image_object_file->GetSectionList();
+    if (!section_list)
+      continue;
+
+    // Fixes the section load address for each section.
+    const size_t num_sections = section_list->GetSize();
+    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+      SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+
+      // Code section load address is offsetted by the code section
+      // offset in the Wasm module.
+      lldb::addr_t load_addr =
+          section_sp->GetFileAddress() |
+          ((section_sp->GetName() == "code") ? code_load_address
+                                             : image_load_address);
+      if (m_process->GetTarget().SetSectionLoadAddress(section_sp, load_addr))
+        loaded_module_list.AppendIfNeeded(module_sp);
+    }
+  }
+
+  m_process->GetTarget().ModulesDidLoad(loaded_module_list);
+}
+
+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"
@@ -286,6 +287,7 @@
   DynamicLoaderPOSIXDYLD::Initialize();
   DynamicLoaderStatic::Initialize();
   DynamicLoaderWindowsDYLD::Initialize();
+  wasm::DynamicLoaderWasmDYLD::Initialize();
 
   // Scan for any system or user LLDB plug-ins
   PluginManager::Initialize();
@@ -379,6 +381,7 @@
   DynamicLoaderPOSIXDYLD::Terminate();
   DynamicLoaderStatic::Terminate();
   DynamicLoaderWindowsDYLD::Terminate();
+  wasm::DynamicLoaderWasmDYLD::Terminate();
 
 #ifndef LLDB_DISABLE_PYTHON
   OperatingSystemPython::Terminate();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to