diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestWasm.py b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestWasm.py
new file mode 100644
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestWasm.py
@@ -0,0 +1,240 @@
+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):
+ 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 = '' % ("test_wasm", 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)
+
+ 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)
+
+ 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"""
+
+ class Responder(MyResponder):
+
+ def __init__(self, obj_path):
+ MyResponder.__init__(self, obj_path)
+
+ def qXferRead(self, obj, annex, offset, length):
+ if obj == "libraries":
+ xml = '' % (self._obj_path, load_address)
+ return xml, False
+ else:
+ return None, False
+
+ 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 = Responder(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/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_sym.yaml b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_sym.yaml
new file mode 100644
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/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/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm_embedded_debug_sections.yaml b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm_embedded_debug_sections.yaml
new file mode 100644
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/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/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm_external_debug_sections.yaml b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/test_wasm_external_debug_sections.yaml
new file mode 100644
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/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/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp
--- a/lldb/source/API/SystemInitializerFull.cpp
+++ b/lldb/source/API/SystemInitializerFull.cpp
@@ -48,6 +48,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"
@@ -274,6 +275,7 @@
DynamicLoaderMacOSXDYLD::Initialize();
DynamicLoaderMacOS::Initialize();
DynamicLoaderPOSIXDYLD::Initialize();
+ wasm::DynamicLoaderWasmDYLD::Initialize(); // before DynamicLoaderStatic.
DynamicLoaderStatic::Initialize();
DynamicLoaderWindowsDYLD::Initialize();
@@ -362,6 +364,7 @@
DynamicLoaderMacOSXDYLD::Terminate();
DynamicLoaderMacOS::Terminate();
DynamicLoaderPOSIXDYLD::Terminate();
+ wasm::DynamicLoaderWasmDYLD::Terminate();
DynamicLoaderStatic::Terminate();
DynamicLoaderWindowsDYLD::Terminate();
diff --git a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
--- a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
+++ b/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)
diff --git a/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/CMakeLists.txt
new file mode 100644
--- /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.h b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h
new file mode 100644
--- /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/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
new file mode 100644
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp
@@ -0,0 +1,68 @@
+//===-- 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;
+}
+
+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/ObjectFile/wasm/ObjectFileWasm.h b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
+++ b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h
@@ -69,7 +69,7 @@
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 @@
Symtab *GetSymtab() override;
- bool IsStripped() override { return true; }
+ bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
void CreateSections(SectionList &unified_section_list) override;
@@ -93,7 +93,7 @@
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 @@
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 @@
/// \}
/// 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 @@
std::vector m_sect_infos;
ArchSpec m_arch;
UUID m_uuid;
- uint32_t m_code_section_offset;
};
} // namespace wasm
diff --git a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
--- a/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/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 §_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(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,10 @@
/// 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;
@@ -355,12 +362,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 +373,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, (size_t) (GetByteSize() - offset));
+ size = std::min(static_cast(size), GetByteSize() - offset);
auto buffer_sp = MapFileData(m_file, size, offset);
return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
}
diff --git a/lldb/test/Shell/ObjectFile/wasm/basic.yaml b/lldb/test/Shell/ObjectFile/wasm/basic.yaml
--- 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
--- 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
--- 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
--- 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
--- a/lldb/tools/lldb-test/SystemInitializerTest.cpp
+++ b/lldb/tools/lldb-test/SystemInitializerTest.cpp
@@ -38,6 +38,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"
@@ -244,6 +245,7 @@
DynamicLoaderMacOSXDYLD::Initialize();
DynamicLoaderMacOS::Initialize();
DynamicLoaderPOSIXDYLD::Initialize();
+ wasm::DynamicLoaderWasmDYLD::Initialize(); // before DynamicLoaderStatic.
DynamicLoaderStatic::Initialize();
DynamicLoaderWindowsDYLD::Initialize();
@@ -332,6 +334,7 @@
DynamicLoaderMacOSXDYLD::Terminate();
DynamicLoaderMacOS::Terminate();
DynamicLoaderPOSIXDYLD::Terminate();
+ wasm::DynamicLoaderWasmDYLD::Terminate();
DynamicLoaderStatic::Terminate();
DynamicLoaderWindowsDYLD::Terminate();