forked from OSchip/llvm-project
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. llvm-svn: 144976
This commit is contained in:
parent
7ba18027e9
commit
46fb558df1
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1703,6 +1703,15 @@ ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &er
|
|||
return allocated_addr;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -166,6 +166,10 @@ public:
|
|||
virtual lldb::addr_t
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3282,16 +3282,51 @@ RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
|
|||
return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
|
||||
}
|
||||
|
||||
char retbuf[1024];
|
||||
DNBRegionInfo region_info = { 0, 0, 0 };
|
||||
int ret = DNBMemoryRegionInfo (m_ctx.ProcessID(), address, ®ion_info);
|
||||
std::ostringstream ostrm;
|
||||
|
||||
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");
|
||||
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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue