diff options
Diffstat (limited to 'lldb/tools/debugserver/source')
| -rw-r--r-- | lldb/tools/debugserver/source/DNB.cpp | 28 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/DNB.h | 1 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.cpp | 6 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.h | 1 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachTask.cpp | 17 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachTask.h | 1 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp | 11 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachVMMemory.h | 1 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachVMRegion.h | 3 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.cpp | 41 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/RNBRemote.h | 2 |
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); |

