[Lldb-commits] [lldb] c112190 - [LLDB] Add DynamicLoaderWasmDYLD plugin for WebAssembly debugging
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Mon Feb 17 03:49:10 PST 2020
Author: Paolo Severini
Date: 2020-02-17T12:42:23+01:00
New Revision: c1121908aace019b3e31e24def58a21a978531cd
URL: https://github.com/llvm/llvm-project/commit/c1121908aace019b3e31e24def58a21a978531cd
DIFF: https://github.com/llvm/llvm-project/commit/c1121908aace019b3e31e24def58a21a978531cd.diff
LOG: [LLDB] Add DynamicLoaderWasmDYLD plugin for WebAssembly debugging
Add a dynamic loader plug-in class for WebAssembly modules.
Differential Revision: https://reviews.llvm.org/D72751
Added:
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/test/API/functionalities/gdb_remote_client/TestWasm.py
lldb/test/API/functionalities/gdb_remote_client/test_sym.yaml
lldb/test/API/functionalities/gdb_remote_client/test_wasm_embedded_debug_sections.yaml
lldb/test/API/functionalities/gdb_remote_client/test_wasm_external_debug_sections.yaml
Modified:
lldb/source/API/SystemInitializerFull.cpp
lldb/source/Plugins/DynamicLoader/CMakeLists.txt
lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
lldb/test/Shell/ObjectFile/wasm/basic.yaml
lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml
lldb/test/Shell/ObjectFile/wasm/stripped-debug-sections.yaml
lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
lldb/tools/lldb-test/SystemInitializerTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp
index 7e2d80fceec8..9f68fc7e88c5 100644
--- a/lldb/source/API/SystemInitializerFull.cpp
+++ b/lldb/source/API/SystemInitializerFull.cpp
@@ -105,6 +105,7 @@ LLDB_PLUGIN_DECLARE(ProcessGDBRemote)
LLDB_PLUGIN_DECLARE(DynamicLoaderMacOSXDYLD)
LLDB_PLUGIN_DECLARE(DynamicLoaderPOSIXDYLD)
LLDB_PLUGIN_DECLARE(DynamicLoaderStatic)
+LLDB_PLUGIN_DECLARE(DynamicLoaderWasmDYLD)
LLDB_PLUGIN_DECLARE(DynamicLoaderWindowsDYLD)
using namespace lldb_private;
@@ -240,6 +241,7 @@ llvm::Error SystemInitializerFull::Initialize() {
LLDB_PLUGIN_INITIALIZE(ProcessGDBRemote);
LLDB_PLUGIN_INITIALIZE(DynamicLoaderMacOSXDYLD);
LLDB_PLUGIN_INITIALIZE(DynamicLoaderPOSIXDYLD);
+ LLDB_PLUGIN_INITIALIZE(DynamicLoaderWasmDYLD); // Before DynamicLoaderStatic.
LLDB_PLUGIN_INITIALIZE(DynamicLoaderStatic);
LLDB_PLUGIN_INITIALIZE(DynamicLoaderWindowsDYLD);
@@ -327,6 +329,7 @@ void SystemInitializerFull::Terminate() {
LLDB_PLUGIN_TERMINATE(DynamicLoaderMacOSXDYLD);
LLDB_PLUGIN_TERMINATE(DynamicLoaderPOSIXDYLD);
+ LLDB_PLUGIN_TERMINATE(DynamicLoaderWasmDYLD);
LLDB_PLUGIN_TERMINATE(DynamicLoaderStatic);
LLDB_PLUGIN_TERMINATE(DynamicLoaderWindowsDYLD);
diff --git a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
index 9f3b2ab0e50f..f357fea02efb 100644
--- a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
+++ b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
@@ -4,3 +4,4 @@ add_subdirectory(POSIX-DYLD)
add_subdirectory(Static)
add_subdirectory(Hexagon-DYLD)
add_subdirectory(Windows-DYLD)
+add_subdirectory(wasm-DYLD)
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt
new file mode 100644
index 000000000000..a4a4ac7b44e7
--- /dev/null
+++ b/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
+ )
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
new file mode 100644
index 000000000000..ae7e011eaa52
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
@@ -0,0 +1,70 @@
+//===-- 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;
+
+LLDB_PLUGIN_DEFINE(DynamicLoaderWasmDYLD)
+
+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;
+}
+
+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();
+}
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
new file mode 100644
index 000000000000..4a18972bb848
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
@@ -0,0 +1,48 @@
+//===-- 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
+ /// \{
+ 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_
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index b9561bdff9f3..e18a84bda4a8 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -235,7 +235,7 @@ ObjectFileWasm::ObjectFileWasm(const ModuleSP &module_sp, DataBufferSP &data_sp,
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);
}
@@ -244,7 +244,7 @@ ObjectFileWasm::ObjectFileWasm(const lldb::ModuleSP &module_sp,
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.
@@ -266,15 +266,19 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
for (const section_info §_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())
@@ -302,10 +306,9 @@ void ObjectFileWasm::CreateSections(SectionList &unified_section_list) {
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;
}
}
@@ -345,6 +348,10 @@ bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address,
/// 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 == LLDB_INVALID_ADDRESS ||
+ m_memory_addr == load_address);
+
ModuleSP module_sp = GetModule();
if (!module_sp)
return false;
@@ -357,12 +364,10 @@ bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address,
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;
}
}
@@ -370,11 +375,11 @@ bool ObjectFileWasm::SetLoadAddress(Target &target, lldb::addr_t load_address,
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, (size_t) (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());
}
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
index 36ef56fe2cce..5fedd06def27 100644
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -69,7 +69,7 @@ class ObjectFileWasm : public ObjectFile {
return m_arch.GetByteOrder();
}
- bool IsExecutable() const override { return true; }
+ bool IsExecutable() const override { return false; }
uint32_t GetAddressByteSize() const override {
return m_arch.GetAddressByteSize();
@@ -81,7 +81,7 @@ class ObjectFileWasm : public ObjectFile {
Symtab *GetSymtab() override;
- bool IsStripped() override { return true; }
+ bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
void CreateSections(SectionList &unified_section_list) override;
@@ -93,7 +93,7 @@ class ObjectFileWasm : public ObjectFile {
uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
- Type CalculateType() override { return eTypeExecutable; }
+ Type CalculateType() override { return eTypeSharedLibrary; }
Strata CalculateStrata() override { return eStrataUser; }
@@ -101,8 +101,7 @@ class ObjectFileWasm : public ObjectFile {
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);
+ return IsInMemory() ? Address(m_memory_addr) : Address(0);
}
/// \}
@@ -127,7 +126,7 @@ class ObjectFileWasm : public ObjectFile {
/// \}
/// Read a range of bytes from the Wasm module.
- DataExtractor ReadImageData(uint64_t offset, size_t size);
+ DataExtractor ReadImageData(lldb::offset_t offset, uint32_t size);
typedef struct section_info {
lldb::offset_t offset;
@@ -145,7 +144,6 @@ class ObjectFileWasm : public ObjectFile {
std::vector<section_info_t> m_sect_infos;
ArchSpec m_arch;
UUID m_uuid;
- uint32_t m_code_section_offset;
};
} // namespace wasm
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py b/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py
new file mode 100644
index 000000000000..8929e0e44e62
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py
@@ -0,0 +1,229 @@
+import lldb
+import binascii
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+LLDB_INVALID_ADDRESS = lldb.LLDB_INVALID_ADDRESS
+load_address = 0x400000000
+
+def format_register_value(val):
+ """
+ Encode each byte by two hex digits in little-endian order.
+ """
+ result = ""
+ mask = 0xff
+ shift = 0
+ for i in range(0, 8):
+ x = (val & mask) >> shift
+ result += format(x, '02x')
+ mask <<= 8
+ shift += 8
+ return result
+
+
+class MyResponder(MockGDBServerResponder):
+ current_pc = load_address + 0x0a
+
+ def __init__(self, obj_path, module_name = ""):
+ self._obj_path = obj_path
+ self._module_name = module_name or 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: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>' % (self._module_name, load_address)
+ return xml, False
+ else:
+ return None, False
+
+ def readMemory(self, addr, length):
+ if addr < load_address:
+ return "E02"
+ result = ""
+ with open(self._obj_path, mode='rb') as file:
+ file_content = bytearray(file.read())
+ addr_from = addr - 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
+
+
+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_load_module_with_embedded_symbols_from_remote(self):
+ """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module with embedded DWARF symbols"""
+
+ yaml_path = "test_wasm_embedded_debug_sections.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, "test_wasm")
+
+ 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(load_address | code_section.GetFileOffset(), code_section.GetLoadAddress(target))
+
+ debug_info_section = module.GetSectionAtIndex(1)
+ self.assertEquals(".debug_info", debug_info_section.GetName())
+ self.assertEquals(load_address | debug_info_section.GetFileOffset(), debug_info_section.GetLoadAddress(target))
+
+ debug_abbrev_section = module.GetSectionAtIndex(2)
+ self.assertEquals(".debug_abbrev", debug_abbrev_section.GetName())
+ self.assertEquals(load_address | debug_abbrev_section.GetFileOffset(), debug_abbrev_section.GetLoadAddress(target))
+
+ debug_line_section = module.GetSectionAtIndex(3)
+ self.assertEquals(".debug_line", debug_line_section.GetName())
+ self.assertEquals(load_address | debug_line_section.GetFileOffset(), debug_line_section.GetLoadAddress(target))
+
+ debug_str_section = module.GetSectionAtIndex(4)
+ self.assertEquals(".debug_str", debug_str_section.GetName())
+ self.assertEquals(load_address | debug_line_section.GetFileOffset(), debug_line_section.GetLoadAddress(target))
+
+
+ def test_load_module_with_stripped_symbols_from_remote(self):
+ """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module with symbols stripped into a separate Wasm file"""
+
+ sym_yaml_path = "test_sym.yaml"
+ sym_yaml_base, ext = os.path.splitext(sym_yaml_path)
+ sym_obj_path = self.getBuildArtifact(sym_yaml_base) + ".wasm"
+ self.yaml2obj(sym_yaml_path, sym_obj_path)
+
+ yaml_path = "test_wasm_external_debug_sections.yaml"
+ yaml_base, ext = os.path.splitext(yaml_path)
+ obj_path = self.getBuildArtifact(yaml_base) + ".wasm"
+ self.yaml2obj(yaml_path, obj_path)
+
+ self.server.responder = MyResponder(obj_path, "test_wasm")
+
+ folder, _ = os.path.split(obj_path)
+ self.runCmd("settings set target.debug-file-search-paths " + os.path.abspath(folder))
+
+ 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(load_address | code_section.GetFileOffset(), code_section.GetLoadAddress(target))
+
+ debug_info_section = module.GetSectionAtIndex(1)
+ self.assertEquals(".debug_info", debug_info_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target))
+
+ debug_abbrev_section = module.GetSectionAtIndex(2)
+ self.assertEquals(".debug_abbrev", debug_abbrev_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target))
+
+ debug_line_section = module.GetSectionAtIndex(3)
+ self.assertEquals(".debug_line", debug_line_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target))
+
+ debug_str_section = module.GetSectionAtIndex(4)
+ self.assertEquals(".debug_str", debug_str_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target))
+
+
+ def test_load_module_from_file(self):
+ """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module from a file"""
+
+ yaml_path = "test_wasm_embedded_debug_sections.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(load_address | code_section.GetFileOffset(), code_section.GetLoadAddress(target))
+
+ debug_info_section = module.GetSectionAtIndex(1)
+ self.assertEquals(".debug_info", debug_info_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target))
+
+ debug_abbrev_section = module.GetSectionAtIndex(2)
+ self.assertEquals(".debug_abbrev", debug_abbrev_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target))
+
+ debug_line_section = module.GetSectionAtIndex(3)
+ self.assertEquals(".debug_line", debug_line_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target))
+
+ debug_str_section = module.GetSectionAtIndex(4)
+ self.assertEquals(".debug_str", debug_str_section.GetName())
+ self.assertEquals(LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target))
+
diff --git a/lldb/test/API/functionalities/gdb_remote_client/test_sym.yaml b/lldb/test/API/functionalities/gdb_remote_client/test_sym.yaml
new file mode 100644
index 000000000000..ab517f5c22bd
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/test_sym.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
+...
diff --git a/lldb/test/API/functionalities/gdb_remote_client/test_wasm_embedded_debug_sections.yaml b/lldb/test/API/functionalities/gdb_remote_client/test_wasm_embedded_debug_sections.yaml
new file mode 100644
index 000000000000..347ead2ed17d
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/test_wasm_embedded_debug_sections.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
+...
diff --git a/lldb/test/API/functionalities/gdb_remote_client/test_wasm_external_debug_sections.yaml b/lldb/test/API/functionalities/gdb_remote_client/test_wasm_external_debug_sections.yaml
new file mode 100644
index 000000000000..4a34f799aa4c
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/test_wasm_external_debug_sections.yaml
@@ -0,0 +1,16 @@
+--- !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' Wasm-encoded
+...
diff --git a/lldb/test/Shell/ObjectFile/wasm/basic.yaml b/lldb/test/Shell/ObjectFile/wasm/basic.yaml
index e7928f961590..79b6c73bcbe4 100644
--- a/lldb/test/Shell/ObjectFile/wasm/basic.yaml
+++ b/lldb/test/Shell/ObjectFile/wasm/basic.yaml
@@ -4,11 +4,11 @@
# CHECK: Plugin name: wasm
# CHECK: Architecture: wasm32-unknown-unknown-wasm
# CHECK: UUID:
-# CHECK: Executable: true
-# CHECK: Stripped: true
-# CHECK: Type: executable
+# CHECK: Executable: false
+# CHECK: Stripped: false
+# CHECK: Type: shared library
# CHECK: Strata: user
-# CHECK: Base VM address: 0xa
+# CHECK: Base VM address: 0x0
# CHECK: Name: code
# CHECK: Type: code
diff --git a/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml b/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml
index ac36c66df441..537c1553a9d7 100644
--- a/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml
+++ b/lldb/test/Shell/ObjectFile/wasm/embedded-debug-sections.yaml
@@ -4,11 +4,11 @@
# CHECK: Plugin name: wasm
# CHECK: Architecture: wasm32-unknown-unknown-wasm
# CHECK: UUID:
-# CHECK: Executable: true
-# CHECK: Stripped: true
-# CHECK: Type: executable
+# CHECK: Executable: false
+# CHECK: Stripped: false
+# CHECK: Type: shared library
# CHECK: Strata: user
-# CHECK: Base VM address: 0xa
+# CHECK: Base VM address: 0x0
# CHECK: Name: code
# CHECK: Type: code
diff --git a/lldb/test/Shell/ObjectFile/wasm/stripped-debug-sections.yaml b/lldb/test/Shell/ObjectFile/wasm/stripped-debug-sections.yaml
index 0ec349e73be2..412fb0aa9fd7 100644
--- a/lldb/test/Shell/ObjectFile/wasm/stripped-debug-sections.yaml
+++ b/lldb/test/Shell/ObjectFile/wasm/stripped-debug-sections.yaml
@@ -4,9 +4,9 @@
# CHECK: Plugin name: wasm
# CHECK: Architecture: wasm32-unknown-unknown-wasm
# CHECK: UUID:
-# CHECK: Executable: true
-# CHECK: Stripped: true
-# CHECK: Type: executable
+# CHECK: Executable: false
+# CHECK: Stripped: false
+# CHECK: Type: shared library
# CHECK: Strata: user
# CHECK: Base VM address: 0x0
diff --git a/lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml b/lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
index 182690eac51e..4bfdd5ae3cb1 100644
--- a/lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
+++ b/lldb/test/Shell/ObjectFile/wasm/unified-debug-sections.yaml
@@ -13,11 +13,11 @@
# CHECK: Plugin name: wasm
# CHECK: Architecture: wasm32-unknown-unknown-wasm
# CHECK: UUID:
-# CHECK: Executable: true
+# CHECK: Executable: false
# CHECK: Stripped: true
-# CHECK: Type: executable
+# CHECK: Type: shared library
# CHECK: Strata: user
-# CHECK: Base VM address: 0xa
+# CHECK: Base VM address: 0x0
# CHECK: Name: code
# CHECK: Type: code
diff --git a/lldb/tools/lldb-test/SystemInitializerTest.cpp b/lldb/tools/lldb-test/SystemInitializerTest.cpp
index 92b4a468d81c..b33b08640471 100644
--- a/lldb/tools/lldb-test/SystemInitializerTest.cpp
+++ b/lldb/tools/lldb-test/SystemInitializerTest.cpp
@@ -91,6 +91,7 @@ LLDB_PLUGIN_DECLARE(ProcessGDBRemote)
LLDB_PLUGIN_DECLARE(DynamicLoaderMacOSXDYLD)
LLDB_PLUGIN_DECLARE(DynamicLoaderPOSIXDYLD)
LLDB_PLUGIN_DECLARE(DynamicLoaderStatic)
+LLDB_PLUGIN_DECLARE(DynamicLoaderWasmDYLD)
LLDB_PLUGIN_DECLARE(DynamicLoaderWindowsDYLD)
using namespace lldb_private;
@@ -215,6 +216,7 @@ llvm::Error SystemInitializerTest::Initialize() {
LLDB_PLUGIN_INITIALIZE(ProcessGDBRemote);
LLDB_PLUGIN_INITIALIZE(DynamicLoaderMacOSXDYLD);
LLDB_PLUGIN_INITIALIZE(DynamicLoaderPOSIXDYLD);
+ LLDB_PLUGIN_INITIALIZE(DynamicLoaderWasmDYLD); // Before DynamicLoaderStatic.
LLDB_PLUGIN_INITIALIZE(DynamicLoaderStatic);
LLDB_PLUGIN_INITIALIZE(DynamicLoaderWindowsDYLD);
@@ -302,6 +304,7 @@ void SystemInitializerTest::Terminate() {
LLDB_PLUGIN_TERMINATE(DynamicLoaderMacOSXDYLD);
LLDB_PLUGIN_TERMINATE(DynamicLoaderPOSIXDYLD);
+ LLDB_PLUGIN_TERMINATE(DynamicLoaderWasmDYLD);
LLDB_PLUGIN_TERMINATE(DynamicLoaderStatic);
LLDB_PLUGIN_TERMINATE(DynamicLoaderWindowsDYLD);
More information about the lldb-commits
mailing list