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 ®ion_info) { + for (auto ®ion : m_regions) { + if (region.GetRange().Contains(addr)) { + region_info = region; + return true; + } + } + return false; + } + bool GetMemoryRegionInfoAtIndex(size_t index, MemoryRegionInfo ®ion_info) { if (index >= GetSize()) @@ -103,6 +114,15 @@ return m_opaque_up->GetSize(); } +bool SBMemoryRegionInfoList::GetMemoryRegionContainingAddress( + lldb::addr_t addr, SBMemoryRegionInfo ®ion_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 ®ion_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 ®ion_info); + bool GetMemoryRegionAtIndex(uint32_t idx, SBMemoryRegionInfo ®ion_info); void Append(lldb::SBMemoryRegionInfo ®ion); 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 ®ion_info); + bool GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_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