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.cpp28
-rw-r--r--lldb/tools/debugserver/source/DNB.h1
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp6
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h1
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.cpp17
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachTask.h1
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp11
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMMemory.h1
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachVMRegion.h3
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp41
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h2
11 files changed, 111 insertions, 1 deletions
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index 268b30b195d..e9461221954 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -1124,6 +1124,34 @@ DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr)
return 0;
}
+//----------------------------------------------------------------------
+// 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.
+//
+// RETURNS: 1 if executable
+// 0 if not executable
+// -1 if we cannot make a determination on this target
+//
+// 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)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ {
+ if (procSP->IsAddressExecutable(addr))
+ return 1;
+ else
+ return 0;
+ }
+ return -1;
+}
+
//----------------------------------------------------------------------
// Formatted output that uses memory and registers from process and
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index e9a3f341d19..6c3cd9bbb70 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -66,6 +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 DNBIsAddressExecutable (nub_process_t pid, nub_addr_t addr) ;
//----------------------------------------------------------------------
// Process status
//----------------------------------------------------------------------
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index a256acec8d3..133f41e2df1 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -478,7 +478,6 @@ MachProcess::Detach()
return true;
}
-
nub_size_t
MachProcess::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const
{
@@ -604,6 +603,11 @@ MachProcess::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
return bytes_written;
}
+bool
+MachProcess::IsAddressExecutable(nub_addr_t address)
+{
+ return m_task.IsAddressExecutable (address);
+}
void
MachProcess::ReplyToAllExceptions ()
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index d52735adba7..b68fa7f49e2 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -99,6 +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);
//----------------------------------------------------------------------
// Path and arg accessors
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
index 862a96b9367..035198e4864 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
@@ -205,6 +205,23 @@ MachTask::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
}
//----------------------------------------------------------------------
+// MachTask::IsAddressExecutable
+//----------------------------------------------------------------------
+bool
+MachTask::IsAddressExecutable (nub_addr_t addr)
+{
+ 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"));
+ }
+ return ret;
+}
+
+
+//----------------------------------------------------------------------
// MachTask::TaskPortForProcessID
//----------------------------------------------------------------------
task_t
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h
index 0e74086a727..da64ba6c997 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -64,6 +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) ;
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 eb7e10746e2..58789ed191a 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
@@ -52,6 +52,17 @@ MachVMMemory::MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count)
return count;
}
+bool
+MachVMMemory::IsExecutable(task_t task, nub_addr_t address)
+{
+ MachVMRegion vmRegion(task);
+
+ if (vmRegion.GetRegionForAddress(address) && vmRegion.IsExecutable())
+ return true;
+ else
+ return false;
+}
+
nub_size_t
MachVMMemory::Read(task_t task, nub_addr_t address, void *data, nub_size_t data_count)
{
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
index 5635186854a..421e4b4999c 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
@@ -27,6 +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);
protected:
nub_size_t MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
index 617e221a57e..bd1aaa0e2a2 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
@@ -42,6 +42,9 @@ public:
bool SetProtections(mach_vm_address_t addr, mach_vm_size_t size, vm_prot_t prot);
bool RestoreProtections();
bool GetRegionForAddress(nub_addr_t addr);
+
+ bool IsExecutable() const { return (m_data.protection & VM_PROT_EXECUTE) == VM_PROT_EXECUTE; }
+
protected:
#if defined (VM_REGION_SUBMAP_SHORT_INFO_COUNT_64)
typedef vm_region_submap_short_info_data_64_t RegionInfo;
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 2b265ed70fd..75c85a7ba05 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -186,6 +186,8 @@ 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"));
+
}
@@ -3238,6 +3240,45 @@ RNBRemote::HandlePacket_c (const char *p)
return rnb_success;
}
+rnb_err_t
+RNBRemote::HandlePacket_IsAddressExecutable (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
+
+ QAddressIsExecutable,0
+ AddressIsNotInExecutableRegion
+
+ QAddressIsExecutable,3a551140 (on a different platform)
+ CannotDetermineRegionAttributes
+ */
+
+ p += sizeof ("QAddressIsExecutable") - 1;
+ if (*p == '\0')
+ return SendPacket ("OK");
+ if (*p++ != ',')
+ return SendPacket ("E67");
+ if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
+ p += 2;
+
+ errno = 0;
+ uint64_t address = strtoul (p, NULL, 16);
+ if (errno != 0 && address == 0)
+ {
+ return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in QAddressIsExecutable packet");
+ }
+ int ret = DNBIsAddressExecutable (m_ctx.ProcessID(), address);
+ if (ret == 1)
+ return SendPacket ("AddressIsInExecutableRegion");
+ if (ret == 0)
+ return SendPacket ("AddressIsNotInExecutableRegion");
+
+ return SendPacket ("CannotDetermineRegionAttributes");
+}
+
+
/* `C sig [;addr]'
Resume with signal sig, optionally at address addr. */
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index 6940efc15b3..573846cad9b 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -106,6 +106,7 @@ public:
set_stdout, // 'QSetSTDOUT:'
set_stderr, // 'QSetSTDERR:'
set_working_dir, // 'QSetWorkingDir:'
+ address_is_executable, // 'QAddressIsExecutable'
allocate_memory, // '_M'
deallocate_memory, // '_m'
@@ -198,6 +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_stop_process (const char *p);
OpenPOWER on IntegriCloud