From 4b1b8b3e1d4aa5044e8ea184c8d8240aeca3e65d Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Fri, 21 Sep 2012 01:55:30 +0000 Subject: [PATCH] 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 --- .../Process/MacOSX-Kernel/CommunicationKDP.cpp | 48 +++++++++++++++-- .../Process/MacOSX-Kernel/CommunicationKDP.h | 9 +++- .../Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp | 11 +++- .../MacOSX-Kernel/RegisterContextKDP_arm.cpp | 40 +++++++++++++++ .../MacOSX-Kernel/RegisterContextKDP_i386.cpp | 30 +++++++++++ .../MacOSX-Kernel/RegisterContextKDP_x86_64.cpp | 60 ++++++++++++++++++++++ 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 506dae0..48c65db 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 db1e02f..f4a5108 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 948ce9f..8fa7cc6 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 296fbba..449ac64 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(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(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(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(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 504ea07..882b0c2 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(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(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(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 360bc6e..f4247a5 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(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(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(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(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(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(process_sp.get())->GetCommunication().SendRequestWriteRegisters (tid, EXCRegSet, &exc, sizeof(exc), error)) + { + if (error.Success()) + return 0; + } + } return -1; } -- 2.7.4