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