[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