mib created this revision.
mib added reviewers: JDevlieghere, jasonmolenda, jingham.
mib added a project: LLDB.
mib requested review of this revision.
Herald added a subscriber: lldb-commits.

This patch adds support for memory regions in Scripted Processes.
This is necessary to read the stack memory region in order to
reconstruct each stackframe of the program.

In order to do so, this patch makes some changes to the SBAPI, namely:

- Add a new constructor for `SBMemoryRegionInfo` that takes arguments such as 
the memory region name, address range, permissions ... This is used when 
reading memory at some address to compute the offset in the binary blob 
provided by the user.
- Change `SBMemoryRegionInfo` opaque pointer to a shared_ptr instead of 
unique_ptr so the ScriptInterpreter can extract the underlying 
`MemoryRegionInfo` object and pass it around.
- Add a `GetMemoryRegionContainingAddress` method to `SBMemoryRegionInfoList` 
to simplify the access to a specific memory region.

With these changes, lldb is now able to unwind the stack and reconstruct
each frame. On top of that, reloading the target module at offset 0 allows
lldb to symbolicate the `ScriptedProcess` using debug info, similarly to an
ordinary Process.

To test this, I wrote a simple program with multiple function calls, ran it in
lldb, stopped at a leaf function and read the registers values and copied
the stack memory into a binary file. These are then used in the python script.

Signed-off-by: Med Ismail Bennani <medismail.benn...@gmail.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108953

Files:
  lldb/bindings/interface/SBMemoryRegionInfo.i
  lldb/bindings/interface/SBMemoryRegionInfoList.i
  lldb/bindings/python/python-wrapper.swig
  lldb/examples/python/scripted_process/main.stack-dump
  lldb/examples/python/scripted_process/my_scripted_process.py
  lldb/include/lldb/API/SBMemoryRegionInfo.h
  lldb/include/lldb/API/SBMemoryRegionInfoList.h
  lldb/include/lldb/Interpreter/ScriptInterpreter.h
  lldb/source/API/SBMemoryRegionInfo.cpp
  lldb/source/API/SBMemoryRegionInfoList.cpp
  lldb/source/Interpreter/ScriptInterpreter.cpp
  lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
  
lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
  lldb/test/API/functionalities/scripted_process/main.c
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -166,6 +166,10 @@
   return nullptr;
 }
 
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data) {
+  return nullptr;
+}
+
 extern lldb::ValueObjectSP
 LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data) {
   return nullptr;
Index: lldb/test/API/functionalities/scripted_process/main.c
===================================================================
--- lldb/test/API/functionalities/scripted_process/main.c
+++ lldb/test/API/functionalities/scripted_process/main.c
@@ -1,5 +1,8 @@
-#include <stdlib.h>
-
-int main() {
-  return 0; // break here
+int bar(int i) {
+  int j = i * i; // break here
+  return j;
 }
+
+int foo(int i) { return bar(i); }
+
+int main() { return foo(42); }
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h
@@ -71,6 +71,23 @@
     return m_interpreter.GetDataExtractorFromSBData(*sb_data);
   }
 
+  template <>
+  lldb::MemoryRegionInfoSP
+  ExtractValueFromPythonObject<lldb::MemoryRegionInfoSP>(
+      python::PythonObject &p, Status &error) {
+    lldb::SBMemoryRegionInfo *sb_mem_region =
+        reinterpret_cast<lldb::SBMemoryRegionInfo *>(
+            LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get()));
+
+    if (!sb_mem_region) {
+      error.SetErrorString("Couldn't cast lldb::SBMemoryRegionInfo to "
+                           "lldb::MemoryRegionInfoSP.");
+      return nullptr;
+    }
+
+    return m_interpreter.GetOpaquePtrFromSBMemoryRegionInfo(*sb_mem_region);
+  }
+
   template <typename T = StructuredData::ObjectSP, typename... Args>
   T Dispatch(llvm::StringRef method_name, Status &error, Args... args) {
     using namespace python;
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -95,8 +95,24 @@
 lldb::MemoryRegionInfoSP
 ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
     lldb::addr_t address) {
-  // TODO: Implement
-  return {};
+  auto error_with_message = [](llvm::StringRef message) {
+    LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS),
+              "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data());
+    return lldb::MemoryRegionInfoSP();
+  };
+
+  Status error;
+  lldb::MemoryRegionInfoSP mem_region_sp = Dispatch<lldb::MemoryRegionInfoSP>(
+      "get_memory_region_containing_address", error, address);
+
+  if (!mem_region_sp || error.Fail()) {
+    return error_with_message(llvm::Twine("Null or invalid object (" +
+                                          llvm::Twine(error.AsCString()) +
+                                          llvm::Twine(")."))
+                                  .str());
+  }
+
+  return mem_region_sp;
 }
 
 StructuredData::DictionarySP
Index: lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -53,6 +53,7 @@
 extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
 extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
 extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data);
 
 } // namespace lldb_private
 
Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
===================================================================
--- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -248,7 +248,7 @@
   lldb::DataExtractorSP data_extractor_sp =
       GetInterface().ReadMemoryAtAddress(addr, size, error);
 
-  if (!data_extractor_sp || error.Fail())
+  if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail())
     return 0;
 
   offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
Index: lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/ScriptInterpreter.cpp
+++ lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -83,6 +83,11 @@
   return Status();
 }
 
+lldb::MemoryRegionInfoSP ScriptInterpreter::GetOpaquePtrFromSBMemoryRegionInfo(
+    const lldb::SBMemoryRegionInfo &mem_region) const {
+  return mem_region.m_opaque_sp;
+}
+
 lldb::ScriptLanguage
 ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
   if (language.equals_insensitive(LanguageToString(eScriptLanguageNone)))
Index: lldb/source/API/SBMemoryRegionInfoList.cpp
===================================================================
--- lldb/source/API/SBMemoryRegionInfoList.cpp
+++ lldb/source/API/SBMemoryRegionInfoList.cpp
@@ -48,6 +48,17 @@
 
   void Clear() { m_regions.clear(); }
 
+  bool GetMemoryRegionContainingAddress(lldb::addr_t addr,
+                                        MemoryRegionInfo &region_info) {
+    for (auto &region : m_regions) {
+      if (region.GetRange().Contains(addr)) {
+        region_info = region;
+        return true;
+      }
+    }
+    return false;
+  }
+
   bool GetMemoryRegionInfoAtIndex(size_t index,
                                   MemoryRegionInfo &region_info) {
     if (index >= GetSize())
@@ -103,6 +114,15 @@
   return m_opaque_up->GetSize();
 }
 
+bool SBMemoryRegionInfoList::GetMemoryRegionContainingAddress(
+    lldb::addr_t addr, SBMemoryRegionInfo &region_info) {
+  LLDB_RECORD_METHOD(
+      bool, SBMemoryRegionInfoList, GetMemoryRegionContainingAddress,
+      (lldb::addr_t, lldb::SBMemoryRegionInfo &), addr, region_info);
+
+  return m_opaque_up->GetMemoryRegionContainingAddress(addr, region_info.ref());
+}
+
 bool SBMemoryRegionInfoList::GetMemoryRegionAtIndex(
     uint32_t idx, SBMemoryRegionInfo &region_info) {
   LLDB_RECORD_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex,
@@ -153,6 +173,9 @@
       SBMemoryRegionInfoList, operator=,(
                                   const lldb::SBMemoryRegionInfoList &));
   LLDB_REGISTER_METHOD_CONST(uint32_t, SBMemoryRegionInfoList, GetSize, ());
+  LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList,
+                       GetMemoryRegionContainingAddress,
+                       (lldb::addr_t, lldb::SBMemoryRegionInfo &));
   LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex,
                        (uint32_t, lldb::SBMemoryRegionInfo &));
   LLDB_REGISTER_METHOD(void, SBMemoryRegionInfoList, Clear, ());
Index: lldb/source/API/SBMemoryRegionInfo.cpp
===================================================================
--- lldb/source/API/SBMemoryRegionInfo.cpp
+++ lldb/source/API/SBMemoryRegionInfo.cpp
@@ -18,21 +18,39 @@
 using namespace lldb;
 using namespace lldb_private;
 
-SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_up(new MemoryRegionInfo()) {
+SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_sp(new MemoryRegionInfo()) {
   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBMemoryRegionInfo);
 }
 
+SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin,
+                                       lldb::addr_t end, uint32_t permissions,
+                                       bool mapped, bool stack_memory)
+    : SBMemoryRegionInfo() {
+  LLDB_RECORD_CONSTRUCTOR(
+      SBMemoryRegionInfo,
+      (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool), name,
+      begin, end, permissions, mapped, stack_memory);
+  m_opaque_sp->SetName(name);
+  m_opaque_sp->GetRange().SetRangeBase(begin);
+  m_opaque_sp->GetRange().SetRangeEnd(end);
+  m_opaque_sp->SetLLDBPermissions(permissions);
+  m_opaque_sp->SetMapped(mapped ? MemoryRegionInfo::eYes
+                                : MemoryRegionInfo::eNo);
+  m_opaque_sp->SetIsStackMemory(stack_memory ? MemoryRegionInfo::eYes
+                                             : MemoryRegionInfo::eNo);
+}
+
 SBMemoryRegionInfo::SBMemoryRegionInfo(const MemoryRegionInfo *lldb_object_ptr)
-    : m_opaque_up(new MemoryRegionInfo()) {
+    : m_opaque_sp(new MemoryRegionInfo()) {
   if (lldb_object_ptr)
     ref() = *lldb_object_ptr;
 }
 
 SBMemoryRegionInfo::SBMemoryRegionInfo(const SBMemoryRegionInfo &rhs)
-    : m_opaque_up() {
+    : m_opaque_sp() {
   LLDB_RECORD_CONSTRUCTOR(SBMemoryRegionInfo,
                           (const lldb::SBMemoryRegionInfo &), rhs);
-  m_opaque_up = clone(rhs.m_opaque_up);
+  m_opaque_sp = clone(rhs.m_opaque_sp);
 }
 
 const SBMemoryRegionInfo &SBMemoryRegionInfo::
@@ -42,7 +60,7 @@
       SBMemoryRegionInfo, operator=,(const lldb::SBMemoryRegionInfo &), rhs);
 
   if (this != &rhs)
-    m_opaque_up = clone(rhs.m_opaque_up);
+    m_opaque_sp = clone(rhs.m_opaque_sp);
   return LLDB_RECORD_RESULT(*this);
 }
 
@@ -51,7 +69,7 @@
 void SBMemoryRegionInfo::Clear() {
   LLDB_RECORD_METHOD_NO_ARGS(void, SBMemoryRegionInfo, Clear);
 
-  m_opaque_up->Clear();
+  m_opaque_sp->Clear();
 }
 
 bool SBMemoryRegionInfo::operator==(const SBMemoryRegionInfo &rhs) const {
@@ -70,56 +88,56 @@
   return ref() != rhs.ref();
 }
 
-MemoryRegionInfo &SBMemoryRegionInfo::ref() { return *m_opaque_up; }
+MemoryRegionInfo &SBMemoryRegionInfo::ref() { return *m_opaque_sp; }
 
-const MemoryRegionInfo &SBMemoryRegionInfo::ref() const { return *m_opaque_up; }
+const MemoryRegionInfo &SBMemoryRegionInfo::ref() const { return *m_opaque_sp; }
 
 lldb::addr_t SBMemoryRegionInfo::GetRegionBase() {
   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBMemoryRegionInfo, GetRegionBase);
 
-  return m_opaque_up->GetRange().GetRangeBase();
+  return m_opaque_sp->GetRange().GetRangeBase();
 }
 
 lldb::addr_t SBMemoryRegionInfo::GetRegionEnd() {
   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBMemoryRegionInfo, GetRegionEnd);
 
-  return m_opaque_up->GetRange().GetRangeEnd();
+  return m_opaque_sp->GetRange().GetRangeEnd();
 }
 
 bool SBMemoryRegionInfo::IsReadable() {
   LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsReadable);
 
-  return m_opaque_up->GetReadable() == MemoryRegionInfo::eYes;
+  return m_opaque_sp->GetReadable() == MemoryRegionInfo::eYes;
 }
 
 bool SBMemoryRegionInfo::IsWritable() {
   LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsWritable);
 
-  return m_opaque_up->GetWritable() == MemoryRegionInfo::eYes;
+  return m_opaque_sp->GetWritable() == MemoryRegionInfo::eYes;
 }
 
 bool SBMemoryRegionInfo::IsExecutable() {
   LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsExecutable);
 
-  return m_opaque_up->GetExecutable() == MemoryRegionInfo::eYes;
+  return m_opaque_sp->GetExecutable() == MemoryRegionInfo::eYes;
 }
 
 bool SBMemoryRegionInfo::IsMapped() {
   LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, IsMapped);
 
-  return m_opaque_up->GetMapped() == MemoryRegionInfo::eYes;
+  return m_opaque_sp->GetMapped() == MemoryRegionInfo::eYes;
 }
 
 const char *SBMemoryRegionInfo::GetName() {
   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBMemoryRegionInfo, GetName);
 
-  return m_opaque_up->GetName().AsCString();
+  return m_opaque_sp->GetName().AsCString();
 }
 
 bool SBMemoryRegionInfo::HasDirtyMemoryPageList() {
   LLDB_RECORD_METHOD_NO_ARGS(bool, SBMemoryRegionInfo, HasDirtyMemoryPageList);
 
-  return m_opaque_up->GetDirtyPageList().hasValue();
+  return m_opaque_sp->GetDirtyPageList().hasValue();
 }
 
 uint32_t SBMemoryRegionInfo::GetNumDirtyPages() {
@@ -127,7 +145,7 @@
 
   uint32_t num_dirty_pages = 0;
   llvm::Optional<std::vector<addr_t>> dirty_page_list =
-      m_opaque_up->GetDirtyPageList();
+      m_opaque_sp->GetDirtyPageList();
   if (dirty_page_list.hasValue())
     num_dirty_pages = dirty_page_list.getValue().size();
 
@@ -140,7 +158,7 @@
 
   addr_t dirty_page_addr = LLDB_INVALID_ADDRESS;
   const llvm::Optional<std::vector<addr_t>> &dirty_page_list =
-      m_opaque_up->GetDirtyPageList();
+      m_opaque_sp->GetDirtyPageList();
   if (dirty_page_list.hasValue() && idx < dirty_page_list.getValue().size())
     dirty_page_addr = dirty_page_list.getValue()[idx];
 
@@ -150,7 +168,7 @@
 int SBMemoryRegionInfo::GetPageSize() {
   LLDB_RECORD_METHOD_NO_ARGS(int, SBMemoryRegionInfo, GetPageSize);
 
-  return m_opaque_up->GetPageSize();
+  return m_opaque_sp->GetPageSize();
 }
 
 bool SBMemoryRegionInfo::GetDescription(SBStream &description) {
@@ -158,13 +176,13 @@
                      (lldb::SBStream &), description);
 
   Stream &strm = description.ref();
-  const addr_t load_addr = m_opaque_up->GetRange().base;
+  const addr_t load_addr = m_opaque_sp->GetRange().base;
 
   strm.Printf("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 " ", load_addr,
-              load_addr + m_opaque_up->GetRange().size);
-  strm.Printf(m_opaque_up->GetReadable() ? "R" : "-");
-  strm.Printf(m_opaque_up->GetWritable() ? "W" : "-");
-  strm.Printf(m_opaque_up->GetExecutable() ? "X" : "-");
+              load_addr + m_opaque_sp->GetRange().size);
+  strm.Printf(m_opaque_sp->GetReadable() ? "R" : "-");
+  strm.Printf(m_opaque_sp->GetWritable() ? "W" : "-");
+  strm.Printf(m_opaque_sp->GetExecutable() ? "X" : "-");
   strm.Printf("]");
 
   return true;
@@ -178,6 +196,9 @@
   LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo, ());
   LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo,
                             (const lldb::SBMemoryRegionInfo &));
+  LLDB_REGISTER_CONSTRUCTOR(
+      SBMemoryRegionInfo,
+      (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool));
   LLDB_REGISTER_METHOD(
       const lldb::SBMemoryRegionInfo &,
       SBMemoryRegionInfo, operator=,(const lldb::SBMemoryRegionInfo &));
Index: lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -11,6 +11,7 @@
 
 #include "lldb/API/SBData.h"
 #include "lldb/API/SBError.h"
+#include "lldb/API/SBMemoryRegionInfo.h"
 #include "lldb/Breakpoint/BreakpointOptions.h"
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/PluginInterface.h"
@@ -564,6 +565,9 @@
 
   Status GetStatusFromSBError(const lldb::SBError &error) const;
 
+  lldb::MemoryRegionInfoSP GetOpaquePtrFromSBMemoryRegionInfo(
+      const lldb::SBMemoryRegionInfo &mem_region) const;
+
 protected:
   Debugger &m_debugger;
   lldb::ScriptLanguage m_script_lang;
Index: lldb/include/lldb/API/SBMemoryRegionInfoList.h
===================================================================
--- lldb/include/lldb/API/SBMemoryRegionInfoList.h
+++ lldb/include/lldb/API/SBMemoryRegionInfoList.h
@@ -27,6 +27,9 @@
 
   uint32_t GetSize() const;
 
+  bool GetMemoryRegionContainingAddress(lldb::addr_t addr,
+                                        SBMemoryRegionInfo &region_info);
+
   bool GetMemoryRegionAtIndex(uint32_t idx, SBMemoryRegionInfo &region_info);
 
   void Append(lldb::SBMemoryRegionInfo &region);
Index: lldb/include/lldb/API/SBMemoryRegionInfo.h
===================================================================
--- lldb/include/lldb/API/SBMemoryRegionInfo.h
+++ lldb/include/lldb/API/SBMemoryRegionInfo.h
@@ -20,6 +20,10 @@
 
   SBMemoryRegionInfo(const lldb::SBMemoryRegionInfo &rhs);
 
+  SBMemoryRegionInfo(const char *name, lldb::addr_t begin, lldb::addr_t end,
+                     uint32_t permissions, bool mapped,
+                     bool stack_memory = false);
+
   ~SBMemoryRegionInfo();
 
   const lldb::SBMemoryRegionInfo &
@@ -117,6 +121,8 @@
   friend class SBProcess;
   friend class SBMemoryRegionInfoList;
 
+  friend class lldb_private::ScriptInterpreter;
+
   lldb_private::MemoryRegionInfo &ref();
 
   const lldb_private::MemoryRegionInfo &ref() const;
@@ -124,7 +130,7 @@
   // Unused.
   SBMemoryRegionInfo(const lldb_private::MemoryRegionInfo *lldb_object_ptr);
 
-  lldb::MemoryRegionInfoUP m_opaque_up;
+  lldb::MemoryRegionInfoSP m_opaque_sp;
 };
 
 } // namespace lldb
Index: lldb/examples/python/scripted_process/my_scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/my_scripted_process.py
+++ lldb/examples/python/scripted_process/my_scripted_process.py
@@ -7,11 +7,22 @@
 from lldb.plugins.scripted_process import ScriptedThread
 
 class MyScriptedProcess(ScriptedProcess):
+    memory_regions = [
+        lldb.SBMemoryRegionInfo("stack", 0x1040b2000, 0x1040b4000, 0b110, True,
+                                True)
+    ]
+
+    stack_memory_dump = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                                     'main.stack-dump')
+
     def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
         super().__init__(target, args)
 
     def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
-        return self.memory_regions[0]
+        for region in self.memory_regions:
+            if region.GetRegionBase() <= addr < region.GetRegionEnd():
+                return region
+        return None
 
     def get_thread_with_id(self, tid: int):
         return {}
@@ -20,10 +31,25 @@
         return {}
 
     def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData:
-        data = lldb.SBData().CreateDataFromCString(
+        data = lldb.SBData()
+
+        with open(self.stack_memory_dump, 'rb') as f:
+            stack_mem = f.read(-1)
+            if not stack_mem:
+                return data
+
+            mem_region = self.get_memory_region_containing_address(addr)
+
+            if not mem_region or addr + size > mem_region.GetRegionEnd():
+                return data
+
+            offset = addr - mem_region.GetRegionBase()
+            shrunk_stack_mem = stack_mem[offset:offset + size]
+
+            error = lldb.SBError()
+            data.SetData(error, shrunk_stack_mem,
                                     self.target.GetByteOrder(),
-                                    self.target.GetCodeByteSize(),
-                                    "Hello, world!")
+                                    self.target.GetAddressByteSize())
         return data
 
     def get_loaded_images(self):
@@ -43,6 +69,30 @@
 
 
 class MyScriptedThread(ScriptedThread):
+    registers = {
+        "rax":0x0000000100070010,
+        "rbx":0x00000001040b6060,
+        "rcx":0x00000001040b2dd0,
+        "rdx":0x00000001040b2b78,
+        "rdi":0x000000000000002a,
+        "rsi":0x00000001040b2b68,
+        "rbp":0x00000001040b29f0,
+        "rsp":0x00000001040b29f0,
+        "r8":0x000000000038054b,
+        "r9":0xffffffff00000000,
+        "r10":0x0000000000000000,
+        "r11":0x0000000000000246,
+        "r12":0x000000010007c3a0,
+        "r13":0x00000001040b2ae8,
+        "r14":0x0000000100003f90,
+        "r15":0x00000001040b2b58,
+        "rip":0x0000000100003f57,
+        "rflags":0x0000000000000206,
+        "cs":0x000000000000002b,
+        "fs":0x0000000000000000,
+        "gs":0x0000000000000000,
+    }
+
     def __init__(self, target):
         super().__init__(target)
 
@@ -76,8 +126,7 @@
         return self.frame_zero[0:0]
 
     def get_register_context(self) -> str:
-        return struct.pack(
-                '21Q', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
+        return struct.pack(f"{len(self.registers)}Q", *self.registers.values())
 
 
 def __lldb_init_module(debugger, dict):
Index: lldb/bindings/python/python-wrapper.swig
===================================================================
--- lldb/bindings/python/python-wrapper.swig
+++ lldb/bindings/python/python-wrapper.swig
@@ -974,6 +974,22 @@
     return sb_ptr;
 }
 
+SWIGEXPORT void*
+LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo
+(
+    PyObject* data
+)
+{
+    lldb::SBMemoryRegionInfo* sb_ptr = NULL;
+
+    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0);
+
+    if (valid_cast == -1)
+        return NULL;
+
+    return sb_ptr;
+}
+
 SWIGEXPORT bool
 LLDBSwigPythonCallCommand
 (
Index: lldb/bindings/interface/SBMemoryRegionInfoList.i
===================================================================
--- lldb/bindings/interface/SBMemoryRegionInfoList.i
+++ lldb/bindings/interface/SBMemoryRegionInfoList.i
@@ -24,6 +24,9 @@
     uint32_t
     GetSize () const;
 
+    bool
+    GetMemoryRegionContainingAddress (lldb::addr_t addr, SBMemoryRegionInfo &region_info);
+
     bool
     GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo &region_info);
 
Index: lldb/bindings/interface/SBMemoryRegionInfo.i
===================================================================
--- lldb/bindings/interface/SBMemoryRegionInfo.i
+++ lldb/bindings/interface/SBMemoryRegionInfo.i
@@ -20,6 +20,9 @@
 
     SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs);
 
+    SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin,
+    lldb::addr_t end, uint32_t permissions, bool mapped, bool stack_memory);
+
     ~SBMemoryRegionInfo ();
 
     void
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to