summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-11-18 07:03:08 +0000
committerGreg Clayton <gclayton@apple.com>2011-11-18 07:03:08 +0000
commita9385537809ef342c843c5ab972e513742652047 (patch)
tree8589a0a80b100dca4974382c9f5d2ae756aa3b3a
parent0963fdd2478c6404d11b96e7d5ae1f2de8b3bb1f (diff)
Added optional calls to lldb_private::Process for getting memory region info
from a process and hooked it up to the new packet that was recently added to our GDB remote executable named debugserver. Now Process has the following new calls: virtual Error Process::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info); virtual uint32_t GetLoadAddressPermissions (lldb::addr_t load_addr); Only the first one needs to be implemented by subclasses that can add this support. Cleaned up the way the new packet was implemented in debugserver to be more useful as an API inside debugserver. Also found an error where finding a region for an address actually will pick up the next region that follows the address in the query so we also need ot make sure that the address we requested the region for falls into the region that gets returned. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144976 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/lldb/Target/Process.h91
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp73
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h6
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp9
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h4
-rw-r--r--tools/debugserver/source/DNB.cpp7
-rw-r--r--tools/debugserver/source/DNB.h2
-rw-r--r--tools/debugserver/source/DNBDefs.h7
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.cpp6
-rw-r--r--tools/debugserver/source/MacOSX/MachProcess.h1
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.cpp11
-rw-r--r--tools/debugserver/source/MacOSX/MachTask.h2
-rw-r--r--tools/debugserver/source/MacOSX/MachVMMemory.cpp16
-rw-r--r--tools/debugserver/source/MacOSX/MachVMMemory.h2
-rw-r--r--tools/debugserver/source/MacOSX/MachVMRegion.cpp52
-rw-r--r--tools/debugserver/source/MacOSX/MachVMRegion.h4
-rw-r--r--tools/debugserver/source/RNBRemote.cpp55
17 files changed, 292 insertions, 56 deletions
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index df07491ec..a921c7718 100644
--- a/include/lldb/Target/Process.h
+++ b/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/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 5dd4dc680..13b1abe79 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/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 &region_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/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 0f980fe10..30d6fb070 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/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/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index ba6431291..6aa89fada 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/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 &region_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/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 2b298ffe2..15ccb34ef 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/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 &region_info);
+
+ virtual lldb_private::Error
DoDeallocateMemory (lldb::addr_t ptr);
//------------------------------------------------------------------
diff --git a/tools/debugserver/source/DNB.cpp b/tools/debugserver/source/DNB.cpp
index c6dc313cd..12950102e 100644
--- a/tools/debugserver/source/DNB.cpp
+++ b/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/tools/debugserver/source/DNB.h b/tools/debugserver/source/DNB.h
index 3b6009a82..2e791f41e 100644
--- a/tools/debugserver/source/DNB.h
+++ b/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/tools/debugserver/source/DNBDefs.h b/tools/debugserver/source/DNBDefs.h
index 4b4729307..879263275 100644
--- a/tools/debugserver/source/DNBDefs.h
+++ b/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/tools/debugserver/source/MacOSX/MachProcess.cpp b/tools/debugserver/source/MacOSX/MachProcess.cpp
index 4cf8fd335..264c7362e 100644
--- a/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/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/tools/debugserver/source/MacOSX/MachProcess.h b/tools/debugserver/source/MacOSX/MachProcess.h
index 732d50d69..d52735adb 100644
--- a/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/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/tools/debugserver/source/MacOSX/MachTask.cpp b/tools/debugserver/source/MacOSX/MachTask.cpp
index b6368fc89..88f3f46b4 100644
--- a/tools/debugserver/source/MacOSX/MachTask.cpp
+++ b/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/tools/debugserver/source/MacOSX/MachTask.h b/tools/debugserver/source/MacOSX/MachTask.h
index f0cfd0e56..b0eaa8d60 100644
--- a/tools/debugserver/source/MacOSX/MachTask.h
+++ b/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/tools/debugserver/source/MacOSX/MachVMMemory.cpp b/tools/debugserver/source/MacOSX/MachVMMemory.cpp
index 69e50d546..d0eb3e753 100644
--- a/tools/debugserver/source/MacOSX/MachVMMemory.cpp
+++ b/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/tools/debugserver/source/MacOSX/MachVMMemory.h b/tools/debugserver/source/MacOSX/MachVMMemory.h
index fa5583383..e32fa4f4c 100644
--- a/tools/debugserver/source/MacOSX/MachVMMemory.h
+++ b/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/tools/debugserver/source/MacOSX/MachVMRegion.cpp b/tools/debugserver/source/MacOSX/MachVMRegion.cpp
index f12f2b927..e1667f0c1 100644
--- a/tools/debugserver/source/MacOSX/MachVMRegion.cpp
+++ b/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/tools/debugserver/source/MacOSX/MachVMRegion.h b/tools/debugserver/source/MacOSX/MachVMRegion.h
index 7a3bd5866..e856f0b24 100644
--- a/tools/debugserver/source/MacOSX/MachVMRegion.h
+++ b/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/tools/debugserver/source/RNBRemote.cpp b/tools/debugserver/source/RNBRemote.cpp
index 6cb251a68..c640023b2 100644
--- a/tools/debugserver/source/RNBRemote.cpp
+++ b/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, &region_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");
}