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

I have verified the logic of the dynamic loader quite carefully, but there are 
a couple of things to clarify.

A Wasm module is loaded at a 64 bit address, where the upper 32 bits are used 
as module identifier. Let’s say that we have a module with Id==4, so it will be 
loaded at address 0x00000004`00000000.  Each section is loaded at its relative 
file offset. Therefore if the code section starts at file offset 0x4d in the 
Wasm module, we call:
Target::SetSectionLoadAddress(section_sp, 0x40000004d).

The module can also contain embedded DWARF sections, which will also be loaded 
at their relative file offset in the same way. And since there cannot be 
duplicated sections in a module, there is no overlapping, we can always convert 
a load address back into a section.

However, there are two complications.

The first is that we need to call `Target::SetSectionLoadAddress()` twice, from 
two different places. First we need to call `Target::SetSectionLoadAddress()` 
in `ObjectFileWasm::SetLoadAddress()`, and then again in 
`DynamicLoaderWasmDYLD::DidAttach()`. The reason for this seems to originate in 
the sequence of function calls:

In `DynamicLoaderWasmDYLD::DidAttach()` we call 
`ProcessGDBRemote::LoadModules()` to get list of loaded modules from the remote 
(Wasm engine).
`ProcessGDBRemote::LoadModules()` calls, first:

- `DynamicLoaderWasmDYLD::LoadModuleAtAddress()` and from there:
  1. `DynamicLoader::UpdateLoadedSections() -> ObjectFileWasm::SetLoadAddress()`
  2. `Target::GetImages()::AppendIfNeeded(module) -> 
ProcessGDBRemote::ModulesDidLoad() -> JITLoaderList::ModulesDidLoad() -> 
Module::GetSymbolFile() -> SymbolFileDWARF::CalculateAbilities()`. Here we 
initialize the symbols for the module, and set `m_did_load_symfile`, but for 
this to work we need to have already set the load address for each section, in 
the previous `ObjectFileWasm::SetLoadAddress()`.

then:

- `Target::SetExecutableModule() -> Target::ClearModules() -> 
SectionLoadList::Clear()`

So, at the end of `LoadModules()` in `DynamicLoaderWasmDYLD::DidAttach()` the 
SectionLoadList is empty, and we need to set it again by calling 
`Target::.SetSectionLoadAddress()` again. 
This works but the duplication is ugly; is there a way to improve this?
_

The second problem is that the Code Section needs to be initialized (in 
`ObjectFileWasm::CreateSections()`) with `m_file_addr = m_file_offset = 0`, and 
not with the actual file offset of the Code section in the Wasm file. If we set 
`Section::m_file_addr` and `Section::m_file_offset` to the actual code offset, 
the DWARF info does not work correctly.

I have some doubts regarding the DWARF data generated by Clang for a Wasm 
target. Looking at an example, for a Wasm module that has the Code section at 
offset 0x57, I see this DWARF data:

  0x0000000b: DW_TAG_compile_unit
                […]
                DW_AT_low_pc (0x0000000000000000)
                DW_AT_ranges (0x00000000
                   [0x00000002, 0x0000000e)
                   [0x0000000f, 0x0000001a)
                   [0x0000001b, 0x00000099)
                   [0x0000009b, 0x0000011c))

The documentation <https://yurydelendik.github.io/webassembly-dwarf/#pc> says 
that //“Wherever a code address is used in DWARF for WebAssembly, it must be 
the offset of an instruction relative within the Code section of the 
WebAssembly file.”// 
But is this correct? Shouldn't maybe code addresses be offset-ed by the file 
address of 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
@@ -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);
   }
   /// \}
 
@@ -112,6 +111,8 @@
   /// information for this module.
   llvm::Optional<FileSpec> GetExternalDebugInfoFileSpec();
 
+  uint32_t GetCodeSectionOffset() const { return m_code_section_offset; }
+
 private:
   ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
                  lldb::offset_t data_offset, const FileSpec *file,
@@ -127,7 +128,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;
Index: lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -355,12 +355,12 @@
     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())) {
+    lldb::addr_t file_address = (section_sp->GetName() == "code")
+                                    ? GetCodeSectionOffset()
+                                    : section_sp->GetFileAddress();
+    if (target.SetSectionLoadAddress(section_sp, load_address | file_address)) {
       ++num_loaded_sections;
     }
   }
@@ -368,11 +368,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,133 @@
+//===-- 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;
+}
+
+/// 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;
+
+    ObjectFileWasm *image_object_file =
+        llvm::dyn_cast_or_null<ObjectFileWasm>(module_sp->GetObjectFile());
+    if (!image_object_file)
+      continue;
+
+    lldb::addr_t image_load_address =
+        image_object_file->GetBaseAddress().GetOffset();
+
+    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 file_addr = (section_sp->GetName() == "code")
+                                   ? image_object_file->GetCodeSectionOffset()
+                                   : section_sp->GetFileAddress();
+      lldb::addr_t load_addr = image_load_address | file_addr;
+      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"
@@ -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