[Lldb-commits] [lldb] r144074 - in /lldb/trunk/tools/debugserver/source: DNB.cpp DNB.h MacOSX/MachProcess.cpp MacOSX/MachProcess.h MacOSX/MachTask.cpp MacOSX/MachTask.h MacOSX/MachVMMemory.cpp MacOSX/MachVMMemory.h MacOSX/MachVMRegion.h RNBRemote.cpp RNBRemote.h

Jason Molenda jmolenda at apple.com
Mon Nov 7 20:28:12 PST 2011


Author: jmolenda
Date: Mon Nov  7 22:28:12 2011
New Revision: 144074

URL: http://llvm.org/viewvc/llvm-project?rev=144074&view=rev
Log:
Add "QAddressIsExecutable" packet to debugserver.  Used to test
whether a given address is in an executable region of memory or
not.  I haven't written the lldb side that will use this packet it
hasn't been tested yet but it's a simple enough bit of code.

I want to have this feature available for the unwinder code.  When
we're stopped at an address with no valid symbol context, there are
a number of questions I'd like to ask --

  is the current pc value in an executable region (e.g. did they
  jump to unallocated/unexecutable memory?  we know how to unwind
  from here if so.)

  Is the stack pointer or the frame pointer the correct register
  to use to find the caller's saved pc value?

Once we're past the first frame we can trust things like eh_frame
and ABI unwind schemes but the first frame is challenging and having
a way to check potential addresses to see if they're executable or
not would help narrow down the possibilities a lot.


Modified:
    lldb/trunk/tools/debugserver/source/DNB.cpp
    lldb/trunk/tools/debugserver/source/DNB.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachVMRegion.h
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.h

Modified: lldb/trunk/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNB.cpp Mon Nov  7 22:28:12 2011
@@ -1124,6 +1124,34 @@
     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

Modified: lldb/trunk/tools/debugserver/source/DNB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.h?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.h (original)
+++ lldb/trunk/tools/debugserver/source/DNB.h Mon Nov  7 22:28:12 2011
@@ -66,6 +66,7 @@
 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
 //----------------------------------------------------------------------

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp Mon Nov  7 22:28:12 2011
@@ -478,7 +478,6 @@
     return true;
 }
 
-
 nub_size_t
 MachProcess::RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const
 {
@@ -604,6 +603,11 @@
     return bytes_written;
 }
 
+bool
+MachProcess::IsAddressExecutable(nub_addr_t address)
+{
+    return m_task.IsAddressExecutable (address);
+}
 
 void
 MachProcess::ReplyToAllExceptions ()

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Mon Nov  7 22:28:12 2011
@@ -99,6 +99,7 @@
     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

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp Mon Nov  7 22:28:12 2011
@@ -205,6 +205,23 @@
 }
 
 //----------------------------------------------------------------------
+// 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

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h Mon Nov  7 22:28:12 2011
@@ -64,6 +64,7 @@
 
             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);

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.cpp Mon Nov  7 22:28:12 2011
@@ -52,6 +52,17 @@
     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)
 {

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.h?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachVMMemory.h Mon Nov  7 22:28:12 2011
@@ -27,6 +27,7 @@
     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);

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachVMRegion.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachVMRegion.h?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachVMRegion.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachVMRegion.h Mon Nov  7 22:28:12 2011
@@ -42,6 +42,9 @@
     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;

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Mon Nov  7 22:28:12 2011
@@ -186,6 +186,8 @@
 //  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 @@
     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.  */
 

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=144074&r1=144073&r2=144074&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Mon Nov  7 22:28:12 2011
@@ -106,6 +106,7 @@
         set_stdout,                     // 'QSetSTDOUT:'
         set_stderr,                     // 'QSetSTDERR:'
         set_working_dir,                // 'QSetWorkingDir:'
+        address_is_executable,          // 'QAddressIsExecutable'
         allocate_memory,                // '_M'
         deallocate_memory,              // '_m'
 
@@ -198,6 +199,7 @@
     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);
 





More information about the lldb-commits mailing list