diff options
17 files changed, 292 insertions, 56 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index df07491ece5..a921c771824 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -27,6 +27,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Core/Error.h" #include "lldb/Core/Event.h" +#include "lldb/Core/RangeMap.h" #include "lldb/Core/StringList.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/PluginInterface.h" @@ -1171,6 +1172,77 @@ inline bool operator!= (const ProcessModID &lhs, const ProcessModID &rhs) else return false; } + +class MemoryRegionInfo +{ +public: + typedef Range<lldb::addr_t, lldb::addr_t> RangeType; + + MemoryRegionInfo () : + m_range (), + m_permissions (0) + { + } + + ~MemoryRegionInfo () + { + } + + RangeType & + GetRange() + { + return m_range; + } + + void + Clear() + { + m_range.Clear(); + m_permissions = 0; + } + + const RangeType & + GetRange() const + { + return m_range; + } + + // Pass in a uint32_t permissions with one or more lldb::Permissions + // enumeration values logical OR'ed together. + bool + TestPermissions (uint32_t permissions) const + { + return m_permissions.AllSet(permissions); + } + + const Flags & + GetPermissions () const + { + return m_permissions; + } + + void + SetPermissions (uint32_t permissions) + { + m_permissions.Reset(permissions); + } + + void + AddPermissions (uint32_t permissions) + { + m_permissions.Set (permissions); + } + + void + RemovePermissions (uint32_t permissions) + { + m_permissions.Clear (permissions); + } + +protected: + RangeType m_range; + Flags m_permissions; // Uses lldb::Permissions enumeration values logical OR'ed together +}; //---------------------------------------------------------------------- /// @class Process Process.h "lldb/Target/Process.h" @@ -2478,6 +2550,25 @@ public: lldb::addr_t AllocateMemory (size_t size, uint32_t permissions, Error &error); + virtual Error + GetMemoryRegionInfo (lldb::addr_t load_addr, + MemoryRegionInfo &range_info) + { + Error error; + error.SetErrorString ("Process::GetMemoryRegionInfo() not supported"); + return error; + } + + virtual uint32_t + GetLoadAddressPermissions (lldb::addr_t load_addr) + { + MemoryRegionInfo range_info; + Error error (GetMemoryRegionInfo (load_addr, range_info)); + if (error.Success()) + return range_info.GetPermissions().Get(); + return 0; + } + //------------------------------------------------------------------ /// Determines whether executing JIT-compiled code in this process /// is possible. diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 5dd4dc68027..13b1abe796d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -46,6 +46,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : m_supports_vCont_S (eLazyBoolCalculate), m_qHostInfo_is_valid (eLazyBoolCalculate), m_supports_alloc_dealloc_memory (eLazyBoolCalculate), + m_supports_memory_region_info (eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -123,6 +124,7 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings() m_supports_vCont_S = eLazyBoolCalculate; m_qHostInfo_is_valid = eLazyBoolCalculate; m_supports_alloc_dealloc_memory = eLazyBoolCalculate; + m_supports_memory_region_info = eLazyBoolCalculate; m_supports_qProcessInfoPID = true; m_supports_qfProcessInfo = true; @@ -1086,6 +1088,77 @@ GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr) return false; } +Error +GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, + lldb_private::MemoryRegionInfo ®ion_info) +{ + Error error; + region_info.Clear(); + + if (m_supports_memory_region_info != eLazyBoolNo) + { + m_supports_memory_region_info = eLazyBoolYes; + char packet[64]; + const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%llx", (uint64_t)addr); + assert (packet_len < sizeof(packet)); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) + { + std::string name; + std::string value; + addr_t addr_value; + bool success = true; + while (success && response.GetNameColonValue(name, value)) + { + if (name.compare ("start") == 0) + { + addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success); + if (success) + region_info.GetRange().SetRangeBase(addr_value); + } + else if (name.compare ("size") == 0) + { + addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success); + if (success) + region_info.GetRange().SetByteSize (addr_value); + } + else if (name.compare ("permissions") == 0) + { + if (value.find('r') != std::string::npos) + region_info.AddPermissions (ePermissionsReadable); + if (value.find('w') != std::string::npos) + region_info.AddPermissions (ePermissionsWritable); + if (value.find('x') != std::string::npos) + region_info.AddPermissions (ePermissionsExecutable); + } + else if (name.compare ("error") == 0) + { + StringExtractorGDBRemote name_extractor; + // Swap "value" over into "name_extractor" + name_extractor.GetStringRef().swap(value); + // Now convert the HEX bytes into a string value + name_extractor.GetHexByteString (value); + error.SetErrorString(value.c_str()); + } + } + } + else + { + m_supports_memory_region_info = eLazyBoolNo; + } + } + + if (m_supports_memory_region_info == eLazyBoolNo) + { + error.SetErrorString("qMemoryRegionInfo is not supported"); + } + if (error.Fail()) + region_info.Clear(); + return error; + +} + + int GDBRemoteCommunicationClient::SetSTDIN (char const *path) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 0f980fe102b..30d6fb0707e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -17,6 +17,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ArchSpec.h" +#include "lldb/Target/Process.h" #include "GDBRemoteCommunication.h" @@ -196,6 +197,10 @@ public: bool DeallocateMemory (lldb::addr_t addr); + lldb_private::Error + GetMemoryRegionInfo (lldb::addr_t addr, + lldb_private::MemoryRegionInfo &range_info); + const lldb_private::ArchSpec & GetHostArchitecture (); @@ -332,6 +337,7 @@ protected: lldb_private::LazyBool m_supports_vCont_S; lldb_private::LazyBool m_qHostInfo_is_valid; lldb_private::LazyBool m_supports_alloc_dealloc_memory; + lldb_private::LazyBool m_supports_memory_region_info; bool m_supports_qProcessInfoPID:1, diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index ba6431291ad..6aa89fadaa9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1704,6 +1704,15 @@ ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &er } Error +ProcessGDBRemote::GetMemoryRegionInfo (addr_t load_addr, + MemoryRegionInfo ®ion_info) +{ + + Error error (m_gdb_comm.GetMemoryRegionInfo (load_addr, region_info)); + return error; +} + +Error ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr) { Error error; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 2b298ffe2b1..15ccb34ef3a 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -167,6 +167,10 @@ public: DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error); virtual lldb_private::Error + GetMemoryRegionInfo (lldb::addr_t load_addr, + lldb_private::MemoryRegionInfo ®ion_info); + + virtual lldb_private::Error DoDeallocateMemory (lldb::addr_t ptr); //------------------------------------------------------------------ diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index c6dc313cd31..12950102edd 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -1139,13 +1139,12 @@ DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) // //---------------------------------------------------------------------- int -DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, char *outbuf, nub_size_t outbufsize) +DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) - { - return procSP->MemoryRegionInfo(addr, outbuf, outbufsize); - } + return procSP->Task().GetMemoryRegionInfo (addr, region_info); + return -1; } diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h index 3b6009a8221..2e791f41e21 100644 --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -66,7 +66,7 @@ nub_size_t DNBProcessMemoryRead (nub_process_t pid, nub_addr_t addr, nub nub_size_t DNBProcessMemoryWrite (nub_process_t pid, nub_addr_t addr, nub_size_t size, const void *buf) DNB_EXPORT; nub_addr_t DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT; nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) DNB_EXPORT; -int DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, char *outbuf, nub_size_t outbufsize); +int DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT; //---------------------------------------------------------------------- // Process status diff --git a/lldb/tools/debugserver/source/DNBDefs.h b/lldb/tools/debugserver/source/DNBDefs.h index 4b4729307d5..87926327504 100644 --- a/lldb/tools/debugserver/source/DNBDefs.h +++ b/lldb/tools/debugserver/source/DNBDefs.h @@ -333,6 +333,13 @@ struct DNBExecutableImageInfo DNBSegment *segments; // Array of contiguous memory segments in executable }; +struct DNBRegionInfo +{ + nub_addr_t addr; + nub_addr_t size; + uint32_t permissions; +}; + typedef nub_bool_t (*DNBCallbackBreakpointHit)(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton); typedef nub_addr_t (*DNBCallbackNameToAddress)(nub_process_t pid, const char *name, const char *shlib_regex, void *baton); typedef nub_size_t (*DNBCallbackCopyExecutableImageInfos)(nub_process_t pid, struct DNBExecutableImageInfo **image_infos, nub_bool_t only_changed, void *baton); diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp index 4cf8fd335da..264c7362e61 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp @@ -603,12 +603,6 @@ MachProcess::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf) return bytes_written; } -int -MachProcess::MemoryRegionInfo(nub_addr_t address, char *outbuf, nub_size_t outbufsize) -{ - return m_task.MemoryRegionInfo (address, outbuf, outbufsize); -} - void MachProcess::ReplyToAllExceptions () { diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h index 732d50d69db..d52735adba7 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -99,7 +99,6 @@ public: bool Detach (); nub_size_t ReadMemory (nub_addr_t addr, nub_size_t size, void *buf); nub_size_t WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf); - int MemoryRegionInfo(nub_addr_t address, char *outbuf, nub_size_t outbufsize); //---------------------------------------------------------------------- // Path and arg accessors diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp index b6368fc8956..88f3f46b45e 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp @@ -208,14 +208,19 @@ MachTask::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf) // MachTask::MemoryRegionInfo //---------------------------------------------------------------------- int -MachTask::MemoryRegionInfo (nub_addr_t addr, char *outbuf, nub_size_t outbufsize) +MachTask::GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info) { task_t task = TaskPort(); if (task == TASK_NULL) return -1; - int ret = m_vm_memory.MemoryRegionInfo(task, addr, outbuf, outbufsize); - DNBLogThreadedIf(LOG_MEMORY, "MachTask::MemoryRegionInfo ( addr = 0x%8.8llx ) => %d", (uint64_t)addr, ret); + int ret = m_vm_memory.GetMemoryRegionInfo(task, addr, region_info); + DNBLogThreadedIf(LOG_MEMORY, "MachTask::MemoryRegionInfo ( addr = 0x%8.8llx ) => %i (start = 0x%8.8llx, size = 0x%8.8llx, permissions = %u)", + (uint64_t)addr, + ret, + (uint64_t)region_info->addr, + (uint64_t)region_info->size, + region_info->permissions); return ret; } diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h index f0cfd0e56e8..b0eaa8d60de 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachTask.h +++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h @@ -64,7 +64,7 @@ public: nub_size_t ReadMemory (nub_addr_t addr, nub_size_t size, void *buf); nub_size_t WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf); - int MemoryRegionInfo (nub_addr_t addr, char *outbuf, nub_size_t outbufsize); + int GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info); nub_addr_t AllocateMemory (nub_size_t size, uint32_t permissions); nub_bool_t DeallocateMemory (nub_addr_t addr); diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp index 69e50d546cf..d0eb3e75368 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp @@ -53,15 +53,21 @@ MachVMMemory::MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count) } int -MachVMMemory::MemoryRegionInfo(task_t task, nub_addr_t address, char *outbuf, nub_size_t outbufsize) +MachVMMemory::GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info) { MachVMRegion vmRegion(task); - outbuf[0] = '\0'; - if (vmRegion.GetRegionForAddress(address) && vmRegion.GetRegionDescription(outbuf, outbufsize)) + if (vmRegion.GetRegionForAddress(address)) + { + region_info->addr = vmRegion.StartAddress(); + region_info->size = vmRegion.GetByteSize(); + region_info->permissions = vmRegion.GetDNBPermissions(); return 1; - else - return 0; + } + region_info->addr = 0; + region_info->size = 0; + region_info->permissions = 0; + return 0; } nub_size_t diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h index fa5583383bf..e32fa4f4c44 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h +++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h @@ -27,7 +27,7 @@ public: nub_size_t Read(task_t task, nub_addr_t address, void *data, nub_size_t data_count); nub_size_t Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count); nub_size_t PageSize(); - int MemoryRegionInfo(task_t task, nub_addr_t address, char *outbuf, nub_size_t outbufsize); + int GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info); protected: nub_size_t MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count); diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp index f12f2b92703..e1667f0c196 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp @@ -134,7 +134,21 @@ MachVMRegion::GetRegionForAddress(nub_addr_t addr) mach_msg_type_number_t info_size = kRegionInfoSize; assert(sizeof(info_size) == 4); m_err = ::mach_vm_region_recurse (m_task, &m_start, &m_size, &m_depth, (vm_region_recurse_info_t)&m_data, &info_size); - if (DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS) || m_err.Fail()) + const bool log_protections = DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS); + if (m_err.Success()) + { + if ((addr < m_start) || (addr >= (m_start + m_size))) + { + m_err.SetErrorString("no region for address"); + m_err.SetError(-1, DNBError::Generic); + if (log_protections) + m_err.LogThreaded("::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx not in range [0x%8.8llx - 0x%8.8llx)", + m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr, (uint64_t)m_start, (uint64_t)m_start + m_size); + return false; + } + } + + if (log_protections || m_err.Fail()) m_err.LogThreaded("::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx ", m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr); if (m_err.Fail()) { @@ -142,7 +156,7 @@ MachVMRegion::GetRegionForAddress(nub_addr_t addr) } else { - if (DNBLogCheckLogBit(LOG_MEMORY_PROTECTIONS)) + if (log_protections) { DNBLogThreaded("info = { prot = %u, " "max_prot = %u, " @@ -178,26 +192,18 @@ MachVMRegion::GetRegionForAddress(nub_addr_t addr) return true; } -bool -MachVMRegion::GetRegionDescription (char *outbuf, nub_size_t outbufsize) +uint32_t +MachVMRegion::GetDNBPermissions () const { - if (m_addr == INVALID_NUB_ADDRESS || m_start == INVALID_NUB_ADDRESS || m_size == 0) - return false; - snprintf (outbuf, outbufsize, "start:%llx,size:%llx", m_start, m_size); - outbuf[outbufsize - 1] = '\0'; - - char tmpbuf[128]; - strcpy (tmpbuf, ",permissions:"); - if ((m_data.protection & VM_PROT_READ) == VM_PROT_READ) - strcat (tmpbuf, "r"); - if ((m_data.protection & VM_PROT_WRITE) == VM_PROT_WRITE) - strcat (tmpbuf, "w"); - if ((m_data.protection & VM_PROT_EXECUTE) == VM_PROT_EXECUTE) - strcat (tmpbuf, "x"); - strlcat (outbuf, tmpbuf, outbufsize); - - // It would be nice if we could figure out whether the memory region is stack memory or jitted code memory as well - - outbuf[outbufsize - 1] = '\0'; - return true; + if (m_addr == INVALID_NUB_ADDRESS || m_start == INVALID_NUB_ADDRESS || m_size == 0) + return 0; + uint32_t dnb_permissions = 0; + + if ((m_data.protection & VM_PROT_READ) == VM_PROT_READ) + dnb_permissions |= eMemoryPermissionsReadable; + if ((m_data.protection & VM_PROT_WRITE) == VM_PROT_WRITE) + dnb_permissions |= eMemoryPermissionsWritable; + if ((m_data.protection & VM_PROT_EXECUTE) == VM_PROT_EXECUTE) + dnb_permissions |= eMemoryPermissionsExecutable; + return dnb_permissions; } diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h index 7a3bd586600..e856f0b2414 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h +++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h @@ -27,6 +27,7 @@ public: void Clear(); mach_vm_address_t StartAddress() const { return m_start; } mach_vm_address_t EndAddress() const { return m_start + m_size; } + mach_vm_size_t GetByteSize () const { return m_size; } mach_vm_address_t BytesRemaining(mach_vm_address_t addr) const { if (ContainsAddress(addr)) @@ -43,7 +44,8 @@ public: bool RestoreProtections(); bool GetRegionForAddress(nub_addr_t addr); - bool GetRegionDescription (char *outbuf, nub_size_t outbufsize); + uint32_t + GetDNBPermissions () const; protected: #if defined (VM_REGION_SUBMAP_SHORT_INFO_COUNT_64) diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 6cb251a682a..c640023b21e 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -3282,16 +3282,51 @@ RNBRemote::HandlePacket_MemoryRegionInfo (const char *p) return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet"); } - char retbuf[1024]; - - int ret = DNBMemoryRegionInfo (m_ctx.ProcessID(), address, retbuf, sizeof (retbuf)); - retbuf[sizeof (retbuf) - 1] = '\0'; - if (ret == 1) - return SendPacket (retbuf); - if (ret == 0) - return SendPacket ("error:address in unmapped region"); - if (ret == -1) - return SendPacket ("error:region lookup cannot be performed"); + DNBRegionInfo region_info = { 0, 0, 0 }; + int ret = DNBMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info); + std::ostringstream ostrm; + + if (ret == 1 && region_info.size > 0) + { + // start:3a50000,size:100000,permissions:rwx + ostrm << "start:" << std::hex << region_info.addr << ';' + << "size:" << std::hex << region_info.size << ';'; + + if (region_info.permissions) + { + ostrm << "permissions:"; + + if (region_info.permissions & eMemoryPermissionsReadable) + ostrm << 'r'; + if (region_info.permissions & eMemoryPermissionsWritable) + ostrm << 'w'; + if (region_info.permissions & eMemoryPermissionsExecutable) + ostrm << 'x'; + ostrm << ';'; + } + return SendPacket (ostrm.str()); + } + else + { + ostrm << std::hex << "error:"; + const char *error_message = NULL; + if (ret == -1) + { + error_message = "region lookup cannot be performed"; + } + else + { + error_message = "address in unmapped region"; + } + // hex encode the error message so we can send any characters we want in + // the future since this is text + const int error_message_len = strlen (error_message); + const uint8_t *u_error_message = (const uint8_t *)error_message; + for (int i = 0; i < error_message_len; i++) + ostrm << RAWHEX8(u_error_message[i]); + ostrm << ';'; + return SendPacket (ostrm.str()); + } return SendPacket ("E68"); } |