summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2012-09-21 01:55:30 +0000
committerGreg Clayton <gclayton@apple.com>2012-09-21 01:55:30 +0000
commit4b1b8b3e1d4aa5044e8ea184c8d8240aeca3e65d (patch)
treeaf75d750b5088c8305f8a2234ca77250b8c07aa0
parent6fa1682368f192f7148392d3136455664aab2f1b (diff)
downloadbcm5719-llvm-4b1b8b3e1d4aa5044e8ea184c8d8240aeca3e65d.tar.gz
bcm5719-llvm-4b1b8b3e1d4aa5044e8ea184c8d8240aeca3e65d.zip
<rdar://problem/9959501>
KDP -- now with rudimentary process control (continue only) and read + write registers (which means we can see stack frames) for x86_64, i386 and ARM. llvm-svn: 164352
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp48
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h9
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp11
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp40
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp30
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp60
6 files changed, 192 insertions, 6 deletions
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index 506dae07c12..48c65dbe799 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -256,6 +256,20 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtrac
uint8_t reply_command = packet.GetU8(&offset);
switch (reply_command)
{
+ case ePacketTypeRequest | KDP_EXCEPTION:
+ case ePacketTypeRequest | KDP_TERMINATION:
+ // We got an exception request, so be sure to send an ACK
+ {
+ PacketStreamType request_ack_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
+ // Set the reply but and make the ACK packet
+ request_ack_packet.PutHex8 (reply_command | ePacketTypeReply);
+ request_ack_packet.PutHex8 (packet.GetU8(&offset));
+ request_ack_packet.PutHex16 (packet.GetU16(&offset));
+ request_ack_packet.PutHex32 (packet.GetU32(&offset));
+ // Ack to the exception or termination
+ SendRequestPacketNoLock (request_ack_packet);
+ }
+ // Fall through to case below to get packet contents
case ePacketTypeReply | KDP_CONNECT:
case ePacketTypeReply | KDP_DISCONNECT:
case ePacketTypeReply | KDP_HOSTINFO:
@@ -269,8 +283,6 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtrac
case ePacketTypeReply | KDP_IMAGEPATH:
case ePacketTypeReply | KDP_SUSPEND:
case ePacketTypeReply | KDP_RESUMECPUS:
- case ePacketTypeReply | KDP_EXCEPTION:
- case ePacketTypeReply | KDP_TERMINATION:
case ePacketTypeReply | KDP_BREAKPOINT_SET:
case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
case ePacketTypeReply | KDP_REGIONS:
@@ -1003,7 +1015,7 @@ CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet)
uint32_t
CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
uint32_t flavor,
- void *dst,
+ void *dst,
uint32_t dst_len,
Error &error)
{
@@ -1032,7 +1044,7 @@ CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
error.Clear();
// Return the number of bytes we could have returned regardless if
// we copied them or not, just so we know when things don't match up
- return src_len;
+ return src_len;
}
}
if (kdp_error)
@@ -1043,6 +1055,34 @@ CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
return 0;
}
+uint32_t
+CommunicationKDP::SendRequestWriteRegisters (uint32_t cpu,
+ uint32_t flavor,
+ const void *src,
+ uint32_t src_len,
+ Error &error)
+{
+ PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
+ const CommandType command = KDP_WRITEREGS;
+ // Size is header + 4 byte cpu and 4 byte flavor
+ const uint32_t command_length = 8 + 4 + 4;
+ const uint32_t request_sequence_id = m_request_sequence_id;
+ MakeRequestPacketHeader (command, request_packet, command_length);
+ request_packet.PutHex32 (cpu);
+ request_packet.PutHex32 (flavor);
+ request_packet.Write(src, src_len);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ {
+ uint32_t offset = 8;
+ uint32_t kdp_error = reply_packet.GetU32 (&offset);
+ if (kdp_error == 0)
+ return src_len;
+ error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
+ }
+ return 0;
+}
+
bool
CommunicationKDP::SendRequestResume (uint32_t cpu_mask)
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
index db1e02f605f..f4a51080e25 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
@@ -177,7 +177,14 @@ public:
void *dst,
uint32_t dst_size,
lldb_private::Error &error);
-
+
+ uint32_t
+ SendRequestWriteRegisters (uint32_t cpu,
+ uint32_t flavor,
+ const void *src,
+ uint32_t src_size,
+ lldb_private::Error &error);
+
const char *
GetKernelVersion ();
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 948ce9fec36..8fa7cc67c69 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -307,7 +307,16 @@ Error
ProcessKDP::DoResume ()
{
Error error;
- if (!m_comm.SendRequestResume ())
+ if (m_comm.SendRequestResume ())
+ {
+ SetPrivateState(eStateRunning);
+ DataExtractor exc_reply_packet;
+ if (m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 60 * USEC_PER_SEC))
+ {
+ SetPrivateState(eStateStopped);
+ }
+ }
+ else
error.SetErrorString ("KDP resume failed");
return error;
}
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
index 296fbbac7e9..449ac646ab3 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
@@ -97,24 +97,64 @@ RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
int
RegisterContextKDP_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
index 504ea07ba4f..882b0c2e931 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
@@ -81,18 +81,48 @@ RegisterContextKDP_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
int
RegisterContextKDP_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
index 360bc6e0dac..f4247a5da27 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
@@ -33,35 +33,95 @@ RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64()
int
RegisterContextKDP_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, GPRRegSet, &gpr, sizeof(gpr), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, FPURegSet, &fpu, sizeof(fpu), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
int
RegisterContextKDP_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
{
+ ProcessSP process_sp (CalculateProcess());
+ if (process_sp)
+ {
+ Error error;
+ if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error))
+ {
+ if (error.Success())
+ return 0;
+ }
+ }
return -1;
}
OpenPOWER on IntegriCloud