summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source')
-rw-r--r--lldb/tools/debugserver/source/DNB.cpp27
-rw-r--r--lldb/tools/debugserver/source/DNB.h4
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp6
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.cpp17
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.h2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp11
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMMemory.h2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp24
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMRegion.h2
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp54
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h4
12 files changed, 98 insertions, 57 deletions
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index e9461221954..c6dc313cd31 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -1125,29 +1125,26 @@ DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr)
}
//----------------------------------------------------------------------
-// Try to determine if a given address in the process PID is in an
-// executable region or not. Used for sniffing potential caller addresses
-// when unwinding a stack and we're making guesses about where the caller
-// frame addr might be saved.
+// Find attributes of the memory region that contains ADDR for process PID,
+// if possible, and return a string describing those attributes.
//
-// RETURNS: 1 if executable
-// 0 if not executable
-// -1 if we cannot make a determination on this target
+// Returns 1 if we could find attributes for this region and OUTBUF can
+// be sent to the remote debugger.
+//
+// Returns 0 if we couldn't find the attributes for a region of memory at
+// that address and OUTBUF should not be sent.
+//
+// Returns -1 if this platform cannot look up information about memory regions
+// or if we do not yet have a valid launched process.
//
-// Note that unmapped memory (an address that is not an allocated page in
-// PID) will return as 0 - it is not executable memory. -1 is intended
-// for a platform where we can't inspect memory region attributes.
//----------------------------------------------------------------------
int
-DNBIsAddressExecutable (nub_process_t pid, nub_addr_t addr)
+DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, char *outbuf, nub_size_t outbufsize)
{
MachProcessSP procSP;
if (GetProcessSP (pid, procSP))
{
- if (procSP->IsAddressExecutable(addr))
- return 1;
- else
- return 0;
+ return procSP->MemoryRegionInfo(addr, outbuf, outbufsize);
}
return -1;
}
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index 6c3cd9bbb70..3b6009a8221 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -66,7 +66,8 @@ 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 DNBIsAddressExecutable (nub_process_t pid, nub_addr_t addr) ;
+int DNBMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, char *outbuf, nub_size_t outbufsize);
+
//----------------------------------------------------------------------
// Process status
//----------------------------------------------------------------------
@@ -88,6 +89,7 @@ nub_size_t DNBProcessGetAvailableSTDOUT (nub_process_t pid, char
nub_size_t DNBProcessGetAvailableSTDERR (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
nub_size_t DNBProcessGetStopCount (nub_process_t pid) DNB_EXPORT;
uint32_t DNBProcessGetCPUType (nub_process_t pid) DNB_EXPORT;
+
//----------------------------------------------------------------------
// Process executable and arguments
//----------------------------------------------------------------------
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index 133f41e2df1..4cf8fd335da 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -603,10 +603,10 @@ MachProcess::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
return bytes_written;
}
-bool
-MachProcess::IsAddressExecutable(nub_addr_t address)
+int
+MachProcess::MemoryRegionInfo(nub_addr_t address, char *outbuf, nub_size_t outbufsize)
{
- return m_task.IsAddressExecutable (address);
+ return m_task.MemoryRegionInfo (address, outbuf, outbufsize);
}
void
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index b68fa7f49e2..732d50d69db 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -99,7 +99,7 @@ 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);
- bool IsAddressExecutable(nub_addr_t address);
+ 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 035198e4864..b6368fc8956 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
@@ -205,18 +205,17 @@ MachTask::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
}
//----------------------------------------------------------------------
-// MachTask::IsAddressExecutable
+// MachTask::MemoryRegionInfo
//----------------------------------------------------------------------
-bool
-MachTask::IsAddressExecutable (nub_addr_t addr)
+int
+MachTask::MemoryRegionInfo (nub_addr_t addr, char *outbuf, nub_size_t outbufsize)
{
task_t task = TaskPort();
- bool ret = false;
- if (task != TASK_NULL)
- {
- ret = m_vm_memory.IsExecutable(task, addr);
- DNBLogThreadedIf(LOG_MEMORY, "MachTask::IsAddressExecutable ( addr = 0x%8.8llx ) => %s", (uint64_t)addr, (ret ? "true" : "false"));
- }
+ 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);
return ret;
}
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h
index da64ba6c997..f0cfd0e56e8 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);
- bool IsAddressExecutable (nub_addr_t addr) ;
+ int MemoryRegionInfo (nub_addr_t addr, char *outbuf, nub_size_t outbufsize);
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 58789ed191a..69e50d546cf 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
@@ -52,15 +52,16 @@ MachVMMemory::MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count)
return count;
}
-bool
-MachVMMemory::IsExecutable(task_t task, nub_addr_t address)
+int
+MachVMMemory::MemoryRegionInfo(task_t task, nub_addr_t address, char *outbuf, nub_size_t outbufsize)
{
MachVMRegion vmRegion(task);
+ outbuf[0] = '\0';
- if (vmRegion.GetRegionForAddress(address) && vmRegion.IsExecutable())
- return true;
+ if (vmRegion.GetRegionForAddress(address) && vmRegion.GetRegionDescription(outbuf, outbufsize))
+ return 1;
else
- return false;
+ return 0;
}
nub_size_t
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
index 421e4b4999c..fa5583383bf 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();
- bool IsExecutable(task_t task, nub_addr_t address);
+ int MemoryRegionInfo(task_t task, nub_addr_t address, char *outbuf, nub_size_t outbufsize);
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 6299cf4179f..f12f2b92703 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp
@@ -177,3 +177,27 @@ MachVMRegion::GetRegionForAddress(nub_addr_t addr)
return true;
}
+
+bool
+MachVMRegion::GetRegionDescription (char *outbuf, nub_size_t outbufsize)
+{
+ 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;
+}
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
index bd1aaa0e2a2..7a3bd586600 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
@@ -43,7 +43,7 @@ public:
bool RestoreProtections();
bool GetRegionForAddress(nub_addr_t addr);
- bool IsExecutable() const { return (m_data.protection & VM_PROT_EXECUTE) == VM_PROT_EXECUTE; }
+ bool GetRegionDescription (char *outbuf, nub_size_t outbufsize);
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 75c85a7ba05..6cb251a682a 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -186,7 +186,7 @@ RNBRemote::CreatePacketTable ()
// t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
- t.push_back (Packet (address_is_executable, &RNBRemote::HandlePacket_IsAddressExecutable, NULL, "QAddressIsExecutable", "Indicate if an address is in an executable region or not"));
+ t.push_back (Packet (memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, "qMemoryRegionInfo", "Return size and attributes of a memory region that contains the given address"));
}
@@ -3241,24 +3241,36 @@ RNBRemote::HandlePacket_c (const char *p)
}
rnb_err_t
-RNBRemote::HandlePacket_IsAddressExecutable (const char *p)
+RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
{
- /* This tells us whether the specified address is in an executable region
- in the remote process or not. Examples of use:
- QAddressIsExecutable,3a55140
- AddressIsInExecutableRegion
+ /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code)
+ for the memory region containing a given address and return that information.
+
+ Users of this packet must be prepared for three results:
+
+ Region information is returned
+ Region information is unavailable for this address because the address is in unmapped memory
+ Region lookup cannot be performed on this platform or process is not yet launched
+ This packet isn't implemented
+
+ Examples of use:
+ qMemoryRegionInfo:3a55140
+ start:3a50000,size:100000,permissions:rwx
- QAddressIsExecutable,0
- AddressIsNotInExecutableRegion
+ qMemoryRegionInfo:0
+ error:address in unmapped region
- QAddressIsExecutable,3a551140 (on a different platform)
- CannotDetermineRegionAttributes
+ qMemoryRegionInfo:3a551140 (on a different platform)
+ error:region lookup cannot be performed
+
+ qMemoryRegionInfo
+ OK // this packet is implemented by the remote nub
*/
- p += sizeof ("QAddressIsExecutable") - 1;
+ p += sizeof ("qMemoryRegionInfo") - 1;
if (*p == '\0')
return SendPacket ("OK");
- if (*p++ != ',')
+ if (*p++ != ':')
return SendPacket ("E67");
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
p += 2;
@@ -3267,15 +3279,21 @@ RNBRemote::HandlePacket_IsAddressExecutable (const char *p)
uint64_t address = strtoul (p, NULL, 16);
if (errno != 0 && address == 0)
{
- return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in QAddressIsExecutable packet");
+ return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
}
- int ret = DNBIsAddressExecutable (m_ctx.ProcessID(), address);
+
+ char retbuf[1024];
+
+ int ret = DNBMemoryRegionInfo (m_ctx.ProcessID(), address, retbuf, sizeof (retbuf));
+ retbuf[sizeof (retbuf) - 1] = '\0';
if (ret == 1)
- return SendPacket ("AddressIsInExecutableRegion");
+ return SendPacket (retbuf);
if (ret == 0)
- return SendPacket ("AddressIsNotInExecutableRegion");
-
- return SendPacket ("CannotDetermineRegionAttributes");
+ return SendPacket ("error:address in unmapped region");
+ if (ret == -1)
+ return SendPacket ("error:region lookup cannot be performed");
+
+ return SendPacket ("E68");
}
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index 573846cad9b..3df4b9ba0d8 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -106,7 +106,7 @@ public:
set_stdout, // 'QSetSTDOUT:'
set_stderr, // 'QSetSTDERR:'
set_working_dir, // 'QSetWorkingDir:'
- address_is_executable, // 'QAddressIsExecutable'
+ memory_region_info, // 'qMemoryRegionInfo:'
allocate_memory, // '_M'
deallocate_memory, // '_m'
@@ -199,7 +199,7 @@ public:
rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description);
rnb_err_t HandlePacket_AllocateMemory (const char *p);
rnb_err_t HandlePacket_DeallocateMemory (const char *p);
- rnb_err_t HandlePacket_IsAddressExecutable (const char *p);
+ rnb_err_t HandlePacket_MemoryRegionInfo (const char *p);
rnb_err_t HandlePacket_stop_process (const char *p);
OpenPOWER on IntegriCloud