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 @@ -105,6 +105,7 @@ 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 @@ 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 @@ 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 --- 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,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/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 @@ -235,7 +235,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); } @@ -244,7 +244,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. @@ -266,15 +266,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()) @@ -302,10 +306,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; } } @@ -345,6 +348,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; @@ -357,12 +364,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; } } @@ -370,11 +375,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/API/functionalities/gdb_remote_client/TestWasm.py b/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py new file mode 100644 --- /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 = '
' % (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 --- /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 --- /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 --- /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 --- 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 @@ -91,6 +91,7 @@ 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 @@ 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 @@ LLDB_PLUGIN_TERMINATE(DynamicLoaderMacOSXDYLD); LLDB_PLUGIN_TERMINATE(DynamicLoaderPOSIXDYLD); + LLDB_PLUGIN_TERMINATE(DynamicLoaderWasmDYLD); LLDB_PLUGIN_TERMINATE(DynamicLoaderStatic); LLDB_PLUGIN_TERMINATE(DynamicLoaderWindowsDYLD);