diff options
author | Kate Stone <katherine.stone@apple.com> | 2016-09-06 20:57:50 +0000 |
---|---|---|
committer | Kate Stone <katherine.stone@apple.com> | 2016-09-06 20:57:50 +0000 |
commit | b9c1b51e45b845debb76d8658edabca70ca56079 (patch) | |
tree | dfcb5a13ef2b014202340f47036da383eaee74aa /lldb/source/Plugins/Process/MacOSX-Kernel | |
parent | d5aa73376966339caad04013510626ec2e42c760 (diff) | |
download | bcm5719-llvm-b9c1b51e45b845debb76d8658edabca70ca56079.tar.gz bcm5719-llvm-b9c1b51e45b845debb76d8658edabca70ca56079.zip |
*** This commit represents a complete reformatting of the LLDB source code
*** to conform to clang-format’s LLVM style. This kind of mass change has
*** two obvious implications:
Firstly, merging this particular commit into a downstream fork may be a huge
effort. Alternatively, it may be worth merging all changes up to this commit,
performing the same reformatting operation locally, and then discarding the
merge for this particular commit. The commands used to accomplish this
reformatting were as follows (with current working directory as the root of
the repository):
find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} +
find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ;
The version of clang-format used was 3.9.0, and autopep8 was 1.2.4.
Secondly, “blame” style tools will generally point to this commit instead of
a meaningful prior commit. There are alternatives available that will attempt
to look through this change and find the appropriate prior commit. YMMV.
llvm-svn: 280751
Diffstat (limited to 'lldb/source/Plugins/Process/MacOSX-Kernel')
16 files changed, 3180 insertions, 3736 deletions
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index bb0dfcfdb35..c016677674a 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// - #include "CommunicationKDP.h" // C Includes @@ -38,39 +37,26 @@ using namespace lldb_private; // CommunicationKDP constructor //---------------------------------------------------------------------- CommunicationKDP::CommunicationKDP(const char *comm_name) - : Communication(comm_name), - m_addr_byte_size(4), - m_byte_order(eByteOrderLittle), - m_packet_timeout(5), - m_sequence_mutex(), - m_is_running(false), - m_session_key(0u), - m_request_sequence_id(0u), - m_exception_sequence_id(0u), - m_kdp_version_version(0u), - m_kdp_version_feature(0u), - m_kdp_hostinfo_cpu_mask(0u), - m_kdp_hostinfo_cpu_type(0u), - m_kdp_hostinfo_cpu_subtype(0u) -{ -} + : Communication(comm_name), m_addr_byte_size(4), + m_byte_order(eByteOrderLittle), m_packet_timeout(5), m_sequence_mutex(), + m_is_running(false), m_session_key(0u), m_request_sequence_id(0u), + m_exception_sequence_id(0u), m_kdp_version_version(0u), + m_kdp_version_feature(0u), m_kdp_hostinfo_cpu_mask(0u), + m_kdp_hostinfo_cpu_type(0u), m_kdp_hostinfo_cpu_subtype(0u) {} //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CommunicationKDP::~CommunicationKDP() -{ - if (IsConnected()) - { - Disconnect(); - } +CommunicationKDP::~CommunicationKDP() { + if (IsConnected()) { + Disconnect(); + } } -bool -CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet) -{ - std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex); - return SendRequestPacketNoLock (request_packet); +bool CommunicationKDP::SendRequestPacket( + const PacketStreamType &request_packet) { + std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex); + return SendRequestPacketNoLock(request_packet); } #if 0 @@ -82,408 +68,370 @@ typedef struct { } kdp_hdr_t; #endif -void -CommunicationKDP::MakeRequestPacketHeader (CommandType request_type, - PacketStreamType &request_packet, - uint16_t request_length) -{ - request_packet.Clear(); - request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type - request_packet.PutHex8 (m_request_sequence_id++); // Sequence number - request_packet.PutHex16 (request_length); // Length of the packet including this header - request_packet.PutHex32 (m_session_key); // Session key +void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type, + PacketStreamType &request_packet, + uint16_t request_length) { + request_packet.Clear(); + request_packet.PutHex8(request_type | + ePacketTypeRequest); // Set the request type + request_packet.PutHex8(m_request_sequence_id++); // Sequence number + request_packet.PutHex16( + request_length); // Length of the packet including this header + request_packet.PutHex32(m_session_key); // Session key } -bool -CommunicationKDP::SendRequestAndGetReply (const CommandType command, - const PacketStreamType &request_packet, - DataExtractor &reply_packet) -{ - if (IsRunning()) - { - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); - if (log) - { - PacketStreamType log_strm; - DumpPacket (log_strm, request_packet.GetData(), request_packet.GetSize()); - log->Printf("error: kdp running, not sending packet: %.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); - } - return false; +bool CommunicationKDP::SendRequestAndGetReply( + const CommandType command, const PacketStreamType &request_packet, + DataExtractor &reply_packet) { + if (IsRunning()) { + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); + if (log) { + PacketStreamType log_strm; + DumpPacket(log_strm, request_packet.GetData(), request_packet.GetSize()); + log->Printf("error: kdp running, not sending packet: %.*s", + (uint32_t)log_strm.GetSize(), log_strm.GetData()); } + return false; + } - std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex); + std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex); #ifdef LLDB_CONFIGURATION_DEBUG - // NOTE: this only works for packets that are in native endian byte order - assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2))); + // NOTE: this only works for packets that are in native endian byte order + assert(request_packet.GetSize() == + *((uint16_t *)(request_packet.GetData() + 2))); #endif - lldb::offset_t offset = 1; - const uint32_t num_retries = 3; - for (uint32_t i=0; i<num_retries; ++i) - { - if (SendRequestPacketNoLock(request_packet)) - { - const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1]; - while (1) - { - if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ())) - { - offset = 0; - const uint8_t reply_command = reply_packet.GetU8 (&offset); - const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset); - if (request_sequence_id == reply_sequence_id) - { - // The sequent ID was correct, now verify we got the response we were looking for - if ((reply_command & eCommandTypeMask) == command) - { - // Success - if (command == KDP_RESUMECPUS) - m_is_running.SetValue(true, eBroadcastAlways); - return true; - } - else - { - // Failed to get the correct response, bail - reply_packet.Clear(); - return false; - } - } - else if (reply_sequence_id > request_sequence_id) - { - // Sequence ID was greater than the sequence ID of the packet we sent, something - // is really wrong... - reply_packet.Clear(); - return false; - } - else - { - // The reply sequence ID was less than our current packet's sequence ID - // so we should keep trying to get a response because this was a response - // for a previous packet that we must have retried. - } - } - else - { - // Break and retry sending the packet as we didn't get a response due to timeout - break; - } + lldb::offset_t offset = 1; + const uint32_t num_retries = 3; + for (uint32_t i = 0; i < num_retries; ++i) { + if (SendRequestPacketNoLock(request_packet)) { + const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1]; + while (1) { + if (WaitForPacketWithTimeoutMicroSecondsNoLock( + reply_packet, GetPacketTimeoutInMicroSeconds())) { + offset = 0; + const uint8_t reply_command = reply_packet.GetU8(&offset); + const uint8_t reply_sequence_id = reply_packet.GetU8(&offset); + if (request_sequence_id == reply_sequence_id) { + // The sequent ID was correct, now verify we got the response we + // were looking for + if ((reply_command & eCommandTypeMask) == command) { + // Success + if (command == KDP_RESUMECPUS) + m_is_running.SetValue(true, eBroadcastAlways); + return true; + } else { + // Failed to get the correct response, bail + reply_packet.Clear(); + return false; } + } else if (reply_sequence_id > request_sequence_id) { + // Sequence ID was greater than the sequence ID of the packet we + // sent, something + // is really wrong... + reply_packet.Clear(); + return false; + } else { + // The reply sequence ID was less than our current packet's sequence + // ID + // so we should keep trying to get a response because this was a + // response + // for a previous packet that we must have retried. + } + } else { + // Break and retry sending the packet as we didn't get a response due + // to timeout + break; } + } } - reply_packet.Clear(); - return false; + } + reply_packet.Clear(); + return false; } -bool -CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet) -{ - if (IsConnected()) - { - const char *packet_data = request_packet.GetData(); - const size_t packet_size = request_packet.GetSize(); - - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); - if (log) - { - PacketStreamType log_strm; - DumpPacket (log_strm, packet_data, packet_size); - log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); - } - ConnectionStatus status = eConnectionStatusSuccess; - - size_t bytes_written = Write (packet_data, - packet_size, - status, - NULL); - - if (bytes_written == packet_size) - return true; - - if (log) - log->Printf ("error: failed to send packet entire packet %" PRIu64 " of %" PRIu64 " bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size); +bool CommunicationKDP::SendRequestPacketNoLock( + const PacketStreamType &request_packet) { + if (IsConnected()) { + const char *packet_data = request_packet.GetData(); + const size_t packet_size = request_packet.GetSize(); + + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); + if (log) { + PacketStreamType log_strm; + DumpPacket(log_strm, packet_data, packet_size); + log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); } - return false; -} + ConnectionStatus status = eConnectionStatusSuccess; -bool -CommunicationKDP::GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock) -{ - return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex, std::try_to_lock)).owns_lock(); + size_t bytes_written = Write(packet_data, packet_size, status, NULL); + + if (bytes_written == packet_size) + return true; + + if (log) + log->Printf("error: failed to send packet entire packet %" PRIu64 + " of %" PRIu64 " bytes sent", + (uint64_t)bytes_written, (uint64_t)packet_size); + } + return false; } -bool -CommunicationKDP::WaitForNotRunningPrivate(const std::chrono::microseconds &timeout) -{ - return m_is_running.WaitForValueEqualTo(false, timeout, NULL); +bool CommunicationKDP::GetSequenceMutex( + std::unique_lock<std::recursive_mutex> &lock) { + return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex, + std::try_to_lock)) + .owns_lock(); } -size_t -CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec) -{ - std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex); - return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); +bool CommunicationKDP::WaitForNotRunningPrivate( + const std::chrono::microseconds &timeout) { + return m_is_running.WaitForValueEqualTo(false, timeout, NULL); } size_t -CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec) -{ - uint8_t buffer[8192]; - Error error; - - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE)); +CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds(DataExtractor &packet, + uint32_t timeout_usec) { + std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex); + return WaitForPacketWithTimeoutMicroSecondsNoLock(packet, timeout_usec); +} - // Check for a packet from our cache first without trying any reading... - if (CheckForPacket (NULL, 0, packet)) +size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock( + DataExtractor &packet, uint32_t timeout_usec) { + uint8_t buffer[8192]; + Error error; + + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS | + KDP_LOG_VERBOSE)); + + // Check for a packet from our cache first without trying any reading... + if (CheckForPacket(NULL, 0, packet)) + return packet.GetByteSize(); + + bool timed_out = false; + while (IsConnected() && !timed_out) { + lldb::ConnectionStatus status = eConnectionStatusNoConnection; + size_t bytes_read = + Read(buffer, sizeof(buffer), timeout_usec, status, &error); + + if (log) + log->Printf("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, " + "status = %s, error = %s) => bytes_read = %" PRIu64, + LLVM_PRETTY_FUNCTION, timeout_usec, + Communication::ConnectionStatusAsCString(status), + error.AsCString(), (uint64_t)bytes_read); + + if (bytes_read > 0) { + if (CheckForPacket(buffer, bytes_read, packet)) return packet.GetByteSize(); - - bool timed_out = false; - while (IsConnected() && !timed_out) - { - lldb::ConnectionStatus status = eConnectionStatusNoConnection; - size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); - - if (log) - log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64, - LLVM_PRETTY_FUNCTION, - timeout_usec, - Communication::ConnectionStatusAsCString (status), - error.AsCString(), - (uint64_t)bytes_read); - - if (bytes_read > 0) - { - if (CheckForPacket (buffer, bytes_read, packet)) - return packet.GetByteSize(); - } - else - { - switch (status) - { - case eConnectionStatusInterrupted: - case eConnectionStatusTimedOut: - timed_out = true; - break; - case eConnectionStatusSuccess: - //printf ("status = success but error = %s\n", error.AsCString("<invalid>")); - break; - - case eConnectionStatusEndOfFile: - case eConnectionStatusNoConnection: - case eConnectionStatusLostConnection: - case eConnectionStatusError: - Disconnect(); - break; - } - } + } else { + switch (status) { + case eConnectionStatusInterrupted: + case eConnectionStatusTimedOut: + timed_out = true; + break; + case eConnectionStatusSuccess: + // printf ("status = success but error = %s\n", + // error.AsCString("<invalid>")); + break; + + case eConnectionStatusEndOfFile: + case eConnectionStatusNoConnection: + case eConnectionStatusLostConnection: + case eConnectionStatusError: + Disconnect(); + break; + } } - packet.Clear (); - return 0; + } + packet.Clear(); + return 0; } -bool -CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet) -{ - // Put the packet data into the buffer in a thread safe fashion - std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex); +bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len, + DataExtractor &packet) { + // Put the packet data into the buffer in a thread safe fashion + std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex); - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); - if (src && src_len > 0) - { - if (log && log->GetVerbose()) - { - PacketStreamType log_strm; - DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS); - log->Printf ("CommunicationKDP::%s adding %u bytes: %s", - __FUNCTION__, - (uint32_t)src_len, - log_strm.GetData()); - } - m_bytes.append ((const char *)src, src_len); + if (src && src_len > 0) { + if (log && log->GetVerbose()) { + PacketStreamType log_strm; + DataExtractor::DumpHexBytes(&log_strm, src, src_len, UINT32_MAX, + LLDB_INVALID_ADDRESS); + log->Printf("CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__, + (uint32_t)src_len, log_strm.GetData()); } - - // Make sure we at least have enough bytes for a packet header - const size_t bytes_available = m_bytes.size(); - if (bytes_available >= 8) - { - packet.SetData (&m_bytes[0], bytes_available, m_byte_order); - lldb::offset_t offset = 0; - 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)); - m_is_running.SetValue(false, eBroadcastAlways); - // Ack to the exception or termination - SendRequestPacketNoLock (request_ack_packet); - } - // Fall through to case below to get packet contents - LLVM_FALLTHROUGH; - case ePacketTypeReply | KDP_CONNECT: - case ePacketTypeReply | KDP_DISCONNECT: - case ePacketTypeReply | KDP_HOSTINFO: - case ePacketTypeReply | KDP_VERSION: - case ePacketTypeReply | KDP_MAXBYTES: - case ePacketTypeReply | KDP_READMEM: - case ePacketTypeReply | KDP_WRITEMEM: - case ePacketTypeReply | KDP_READREGS: - case ePacketTypeReply | KDP_WRITEREGS: - case ePacketTypeReply | KDP_LOAD: - case ePacketTypeReply | KDP_IMAGEPATH: - case ePacketTypeReply | KDP_SUSPEND: - case ePacketTypeReply | KDP_RESUMECPUS: - case ePacketTypeReply | KDP_BREAKPOINT_SET: - case ePacketTypeReply | KDP_BREAKPOINT_REMOVE: - case ePacketTypeReply | KDP_REGIONS: - case ePacketTypeReply | KDP_REATTACH: - case ePacketTypeReply | KDP_HOSTREBOOT: - case ePacketTypeReply | KDP_READMEM64: - case ePacketTypeReply | KDP_WRITEMEM64: - case ePacketTypeReply | KDP_BREAKPOINT_SET64: - case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64: - case ePacketTypeReply | KDP_KERNELVERSION: - case ePacketTypeReply | KDP_READPHYSMEM64: - case ePacketTypeReply | KDP_WRITEPHYSMEM64: - case ePacketTypeReply | KDP_READIOPORT: - case ePacketTypeReply | KDP_WRITEIOPORT: - case ePacketTypeReply | KDP_READMSR64: - case ePacketTypeReply | KDP_WRITEMSR64: - case ePacketTypeReply | KDP_DUMPINFO: - { - offset = 2; - const uint16_t length = packet.GetU16 (&offset); - if (length <= bytes_available) - { - // We have an entire packet ready, we need to copy the data - // bytes into a buffer that will be owned by the packet and - // erase the bytes from our communcation buffer "m_bytes" - packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length))); - m_bytes.erase (0, length); - - if (log) - { - PacketStreamType log_strm; - DumpPacket (log_strm, packet); - - log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); - } - return true; - } - } - break; - - default: - // Unrecognized reply command byte, erase this byte and try to get back on track - if (log) - log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x", - __FUNCTION__, - (uint8_t)m_bytes[0]); - m_bytes.erase(0, 1); - break; + m_bytes.append((const char *)src, src_len); + } + + // Make sure we at least have enough bytes for a packet header + const size_t bytes_available = m_bytes.size(); + if (bytes_available >= 8) { + packet.SetData(&m_bytes[0], bytes_available, m_byte_order); + lldb::offset_t offset = 0; + 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)); + m_is_running.SetValue(false, eBroadcastAlways); + // Ack to the exception or termination + SendRequestPacketNoLock(request_ack_packet); + } + // Fall through to case below to get packet contents + LLVM_FALLTHROUGH; + case ePacketTypeReply | KDP_CONNECT: + case ePacketTypeReply | KDP_DISCONNECT: + case ePacketTypeReply | KDP_HOSTINFO: + case ePacketTypeReply | KDP_VERSION: + case ePacketTypeReply | KDP_MAXBYTES: + case ePacketTypeReply | KDP_READMEM: + case ePacketTypeReply | KDP_WRITEMEM: + case ePacketTypeReply | KDP_READREGS: + case ePacketTypeReply | KDP_WRITEREGS: + case ePacketTypeReply | KDP_LOAD: + case ePacketTypeReply | KDP_IMAGEPATH: + case ePacketTypeReply | KDP_SUSPEND: + case ePacketTypeReply | KDP_RESUMECPUS: + case ePacketTypeReply | KDP_BREAKPOINT_SET: + case ePacketTypeReply | KDP_BREAKPOINT_REMOVE: + case ePacketTypeReply | KDP_REGIONS: + case ePacketTypeReply | KDP_REATTACH: + case ePacketTypeReply | KDP_HOSTREBOOT: + case ePacketTypeReply | KDP_READMEM64: + case ePacketTypeReply | KDP_WRITEMEM64: + case ePacketTypeReply | KDP_BREAKPOINT_SET64: + case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64: + case ePacketTypeReply | KDP_KERNELVERSION: + case ePacketTypeReply | KDP_READPHYSMEM64: + case ePacketTypeReply | KDP_WRITEPHYSMEM64: + case ePacketTypeReply | KDP_READIOPORT: + case ePacketTypeReply | KDP_WRITEIOPORT: + case ePacketTypeReply | KDP_READMSR64: + case ePacketTypeReply | KDP_WRITEMSR64: + case ePacketTypeReply | KDP_DUMPINFO: { + offset = 2; + const uint16_t length = packet.GetU16(&offset); + if (length <= bytes_available) { + // We have an entire packet ready, we need to copy the data + // bytes into a buffer that will be owned by the packet and + // erase the bytes from our communcation buffer "m_bytes" + packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length))); + m_bytes.erase(0, length); + + if (log) { + PacketStreamType log_strm; + DumpPacket(log_strm, packet); + + log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); } + return true; + } + } break; + + default: + // Unrecognized reply command byte, erase this byte and try to get back on + // track + if (log) + log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x", + __FUNCTION__, (uint8_t)m_bytes[0]); + m_bytes.erase(0, 1); + break; } - packet.Clear(); - return false; + } + packet.Clear(); + return false; } - -bool -CommunicationKDP::SendRequestConnect (uint16_t reply_port, - uint16_t exc_port, - const char *greeting) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - if (greeting == NULL) - greeting = ""; - - const CommandType command = KDP_CONNECT; - // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL - const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1; - MakeRequestPacketHeader (command, request_packet, command_length); - // Always send connect ports as little endian - request_packet.SetByteOrder (eByteOrderLittle); - request_packet.PutHex16 (htons(reply_port)); - request_packet.PutHex16 (htons(exc_port)); - request_packet.SetByteOrder (m_byte_order); - request_packet.PutCString (greeting); - DataExtractor reply_packet; - return SendRequestAndGetReply (command, request_packet, reply_packet); +bool CommunicationKDP::SendRequestConnect(uint16_t reply_port, + uint16_t exc_port, + const char *greeting) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + if (greeting == NULL) + greeting = ""; + + const CommandType command = KDP_CONNECT; + // Length is 82 uint16_t and the length of the greeting C string with the + // terminating NULL + const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1; + MakeRequestPacketHeader(command, request_packet, command_length); + // Always send connect ports as little endian + request_packet.SetByteOrder(eByteOrderLittle); + request_packet.PutHex16(htons(reply_port)); + request_packet.PutHex16(htons(exc_port)); + request_packet.SetByteOrder(m_byte_order); + request_packet.PutCString(greeting); + DataExtractor reply_packet; + return SendRequestAndGetReply(command, request_packet, reply_packet); } -void -CommunicationKDP::ClearKDPSettings () -{ - m_request_sequence_id = 0; - m_kdp_version_version = 0; - m_kdp_version_feature = 0; - m_kdp_hostinfo_cpu_mask = 0; - m_kdp_hostinfo_cpu_type = 0; - m_kdp_hostinfo_cpu_subtype = 0; +void CommunicationKDP::ClearKDPSettings() { + m_request_sequence_id = 0; + m_kdp_version_version = 0; + m_kdp_version_feature = 0; + m_kdp_hostinfo_cpu_mask = 0; + m_kdp_hostinfo_cpu_type = 0; + m_kdp_hostinfo_cpu_subtype = 0; } -bool -CommunicationKDP::SendRequestReattach (uint16_t reply_port) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_REATTACH; - // Length is 8 bytes for the header plus 2 bytes for the reply UDP port - const uint32_t command_length = 8 + 2; - MakeRequestPacketHeader (command, request_packet, command_length); - // Always send connect ports as little endian - request_packet.SetByteOrder (eByteOrderLittle); - request_packet.PutHex16(htons(reply_port)); - request_packet.SetByteOrder (m_byte_order); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - // Reset the sequence ID to zero for reattach - ClearKDPSettings (); - lldb::offset_t offset = 4; - m_session_key = reply_packet.GetU32 (&offset); - return true; - } - return false; +bool CommunicationKDP::SendRequestReattach(uint16_t reply_port) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_REATTACH; + // Length is 8 bytes for the header plus 2 bytes for the reply UDP port + const uint32_t command_length = 8 + 2; + MakeRequestPacketHeader(command, request_packet, command_length); + // Always send connect ports as little endian + request_packet.SetByteOrder(eByteOrderLittle); + request_packet.PutHex16(htons(reply_port)); + request_packet.SetByteOrder(m_byte_order); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + // Reset the sequence ID to zero for reattach + ClearKDPSettings(); + lldb::offset_t offset = 4; + m_session_key = reply_packet.GetU32(&offset); + return true; + } + return false; } -uint32_t -CommunicationKDP::GetVersion () -{ - if (!VersionIsValid()) - SendRequestVersion(); - return m_kdp_version_version; +uint32_t CommunicationKDP::GetVersion() { + if (!VersionIsValid()) + SendRequestVersion(); + return m_kdp_version_version; } -uint32_t -CommunicationKDP::GetFeatureFlags () -{ - if (!VersionIsValid()) - SendRequestVersion(); - return m_kdp_version_feature; +uint32_t CommunicationKDP::GetFeatureFlags() { + if (!VersionIsValid()) + SendRequestVersion(); + return m_kdp_version_feature; } -bool -CommunicationKDP::SendRequestVersion () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_VERSION; - const uint32_t command_length = 8; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - m_kdp_version_version = reply_packet.GetU32 (&offset); - m_kdp_version_feature = reply_packet.GetU32 (&offset); - return true; - } - return false; +bool CommunicationKDP::SendRequestVersion() { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_VERSION; + const uint32_t command_length = 8; + MakeRequestPacketHeader(command, request_packet, command_length); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + m_kdp_version_version = reply_packet.GetU32(&offset); + m_kdp_version_feature = reply_packet.GetU32(&offset); + return true; + } + return false; } #if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... @@ -514,932 +462,863 @@ CommunicationKDP::SendRequestImagePath () } #endif -uint32_t -CommunicationKDP::GetCPUMask () -{ - if (!HostInfoIsValid()) - SendRequestHostInfo(); - return m_kdp_hostinfo_cpu_mask; +uint32_t CommunicationKDP::GetCPUMask() { + if (!HostInfoIsValid()) + SendRequestHostInfo(); + return m_kdp_hostinfo_cpu_mask; } -uint32_t -CommunicationKDP::GetCPUType () -{ - if (!HostInfoIsValid()) - SendRequestHostInfo(); - return m_kdp_hostinfo_cpu_type; +uint32_t CommunicationKDP::GetCPUType() { + if (!HostInfoIsValid()) + SendRequestHostInfo(); + return m_kdp_hostinfo_cpu_type; } -uint32_t -CommunicationKDP::GetCPUSubtype () -{ - if (!HostInfoIsValid()) - SendRequestHostInfo(); - return m_kdp_hostinfo_cpu_subtype; +uint32_t CommunicationKDP::GetCPUSubtype() { + if (!HostInfoIsValid()) + SendRequestHostInfo(); + return m_kdp_hostinfo_cpu_subtype; } -lldb_private::UUID -CommunicationKDP::GetUUID () -{ - UUID uuid; - if (GetKernelVersion() == NULL) - return uuid; - - if (m_kernel_version.find("UUID=") == std::string::npos) - return uuid; - - size_t p = m_kernel_version.find("UUID=") + strlen ("UUID="); - std::string uuid_str = m_kernel_version.substr(p, 36); - if (uuid_str.size() < 32) - return uuid; +lldb_private::UUID CommunicationKDP::GetUUID() { + UUID uuid; + if (GetKernelVersion() == NULL) + return uuid; - if (uuid.SetFromCString (uuid_str.c_str()) == 0) - { - UUID invalid_uuid; - return invalid_uuid; - } + if (m_kernel_version.find("UUID=") == std::string::npos) + return uuid; + size_t p = m_kernel_version.find("UUID=") + strlen("UUID="); + std::string uuid_str = m_kernel_version.substr(p, 36); + if (uuid_str.size() < 32) return uuid; -} -bool -CommunicationKDP::RemoteIsEFI () -{ - if (GetKernelVersion() == NULL) - return false; - if (strncmp (m_kernel_version.c_str(), "EFI", 3) == 0) - return true; - else - return false; -} + if (uuid.SetFromCString(uuid_str.c_str()) == 0) { + UUID invalid_uuid; + return invalid_uuid; + } -bool -CommunicationKDP::RemoteIsDarwinKernel () -{ - if (GetKernelVersion() == NULL) - return false; - if (m_kernel_version.find("Darwin Kernel") != std::string::npos) - return true; - else - return false; + return uuid; } -lldb::addr_t -CommunicationKDP::GetLoadAddress () -{ - if (GetKernelVersion() == NULL) - return LLDB_INVALID_ADDRESS; - - if (m_kernel_version.find("stext=") == std::string::npos) - return LLDB_INVALID_ADDRESS; - size_t p = m_kernel_version.find("stext=") + strlen ("stext="); - if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x') - return LLDB_INVALID_ADDRESS; - - addr_t kernel_load_address; - errno = 0; - kernel_load_address = ::strtoul (m_kernel_version.c_str() + p, NULL, 16); - if (errno != 0 || kernel_load_address == 0) - return LLDB_INVALID_ADDRESS; - - return kernel_load_address; +bool CommunicationKDP::RemoteIsEFI() { + if (GetKernelVersion() == NULL) + return false; + if (strncmp(m_kernel_version.c_str(), "EFI", 3) == 0) + return true; + else + return false; } -bool -CommunicationKDP::SendRequestHostInfo () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_HOSTINFO; - const uint32_t command_length = 8; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset); - m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset); - m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset); - - ArchSpec kernel_arch; - kernel_arch.SetArchitecture (eArchTypeMachO, - m_kdp_hostinfo_cpu_type, - m_kdp_hostinfo_cpu_subtype); - - m_addr_byte_size = kernel_arch.GetAddressByteSize(); - m_byte_order = kernel_arch.GetByteOrder(); - return true; - } +bool CommunicationKDP::RemoteIsDarwinKernel() { + if (GetKernelVersion() == NULL) + return false; + if (m_kernel_version.find("Darwin Kernel") != std::string::npos) + return true; + else return false; } -const char * -CommunicationKDP::GetKernelVersion () -{ - if (m_kernel_version.empty()) - SendRequestKernelVersion (); - return m_kernel_version.c_str(); -} +lldb::addr_t CommunicationKDP::GetLoadAddress() { + if (GetKernelVersion() == NULL) + return LLDB_INVALID_ADDRESS; -bool -CommunicationKDP::SendRequestKernelVersion () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_KERNELVERSION; - const uint32_t command_length = 8; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - const char *kernel_version_cstr = reply_packet.PeekCStr(8); - if (kernel_version_cstr && kernel_version_cstr[0]) - m_kernel_version.assign (kernel_version_cstr); - return true; - } - return false; + if (m_kernel_version.find("stext=") == std::string::npos) + return LLDB_INVALID_ADDRESS; + size_t p = m_kernel_version.find("stext=") + strlen("stext="); + if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x') + return LLDB_INVALID_ADDRESS; + + addr_t kernel_load_address; + errno = 0; + kernel_load_address = ::strtoul(m_kernel_version.c_str() + p, NULL, 16); + if (errno != 0 || kernel_load_address == 0) + return LLDB_INVALID_ADDRESS; + + return kernel_load_address; } -bool -CommunicationKDP::SendRequestDisconnect () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_DISCONNECT; - const uint32_t command_length = 8; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - // Are we supposed to get a reply for disconnect? - } - ClearKDPSettings (); +bool CommunicationKDP::SendRequestHostInfo() { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_HOSTINFO; + const uint32_t command_length = 8; + MakeRequestPacketHeader(command, request_packet, command_length); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + m_kdp_hostinfo_cpu_mask = reply_packet.GetU32(&offset); + m_kdp_hostinfo_cpu_type = reply_packet.GetU32(&offset); + m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32(&offset); + + ArchSpec kernel_arch; + kernel_arch.SetArchitecture(eArchTypeMachO, m_kdp_hostinfo_cpu_type, + m_kdp_hostinfo_cpu_subtype); + + m_addr_byte_size = kernel_arch.GetAddressByteSize(); + m_byte_order = kernel_arch.GetByteOrder(); return true; + } + return false; } -uint32_t -CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr, - void *dst, - uint32_t dst_len, - Error &error) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - bool use_64 = (GetVersion() >= 11); - uint32_t command_addr_byte_size = use_64 ? 8 : 4; - const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM; - // Size is header + address size + uint32_t length - const uint32_t command_length = 8 + command_addr_byte_size + 4; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutMaxHex64 (addr, command_addr_byte_size); - request_packet.PutHex32 (dst_len); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - uint32_t kdp_error = reply_packet.GetU32 (&offset); - uint32_t src_len = reply_packet.GetByteSize() - 12; - - if (src_len > 0) - { - const void *src = reply_packet.GetData(&offset, src_len); - if (src) - { - ::memcpy (dst, src, src_len); - error.Clear(); - return src_len; - } - } - if (kdp_error) - error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error); - else - error.SetErrorString ("kdp read memory failed"); - } - else - { - error.SetErrorString ("failed to send packet"); - } - return 0; +const char *CommunicationKDP::GetKernelVersion() { + if (m_kernel_version.empty()) + SendRequestKernelVersion(); + return m_kernel_version.c_str(); } +bool CommunicationKDP::SendRequestKernelVersion() { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_KERNELVERSION; + const uint32_t command_length = 8; + MakeRequestPacketHeader(command, request_packet, command_length); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + const char *kernel_version_cstr = reply_packet.PeekCStr(8); + if (kernel_version_cstr && kernel_version_cstr[0]) + m_kernel_version.assign(kernel_version_cstr); + return true; + } + return false; +} -uint32_t -CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr, - const void *src, - uint32_t src_len, - Error &error) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - bool use_64 = (GetVersion() >= 11); - uint32_t command_addr_byte_size = use_64 ? 8 : 4; - const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM; - // Size is header + address size + uint32_t length - const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutMaxHex64 (addr, command_addr_byte_size); - request_packet.PutHex32 (src_len); - request_packet.PutRawBytes(src, src_len); +bool CommunicationKDP::SendRequestDisconnect() { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_DISCONNECT; + const uint32_t command_length = 8; + MakeRequestPacketHeader(command, request_packet, command_length); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + // Are we supposed to get a reply for disconnect? + } + ClearKDPSettings(); + return true; +} - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - uint32_t kdp_error = reply_packet.GetU32 (&offset); - if (kdp_error) - error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error); - else - { - error.Clear(); - return src_len; - } +uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst, + uint32_t dst_len, + Error &error) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + bool use_64 = (GetVersion() >= 11); + uint32_t command_addr_byte_size = use_64 ? 8 : 4; + const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM; + // Size is header + address size + uint32_t length + const uint32_t command_length = 8 + command_addr_byte_size + 4; + MakeRequestPacketHeader(command, request_packet, command_length); + request_packet.PutMaxHex64(addr, command_addr_byte_size); + request_packet.PutHex32(dst_len); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + uint32_t kdp_error = reply_packet.GetU32(&offset); + uint32_t src_len = reply_packet.GetByteSize() - 12; + + if (src_len > 0) { + const void *src = reply_packet.GetData(&offset, src_len); + if (src) { + ::memcpy(dst, src, src_len); + error.Clear(); + return src_len; + } } + if (kdp_error) + error.SetErrorStringWithFormat("kdp read memory failed (error %u)", + kdp_error); else - { - error.SetErrorString ("failed to send packet"); - } - return 0; + error.SetErrorString("kdp read memory failed"); + } else { + error.SetErrorString("failed to send packet"); + } + return 0; } -bool -CommunicationKDP::SendRawRequest (uint8_t command_byte, - const void *src, // Raw packet payload bytes - uint32_t src_len, // Raw packet payload length - DataExtractor &reply_packet, - Error &error) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - // Size is header + address size + uint32_t length - const uint32_t command_length = 8 + src_len; - const CommandType command = (CommandType)command_byte; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutRawBytes(src, src_len); - - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - uint32_t kdp_error = reply_packet.GetU32 (&offset); - if (kdp_error && (command_byte != KDP_DUMPINFO)) - error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error); - else - { - error.Clear(); - return true; - } - } - else - { - error.SetErrorString ("failed to send packet"); +uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr, + const void *src, + uint32_t src_len, + Error &error) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + bool use_64 = (GetVersion() >= 11); + uint32_t command_addr_byte_size = use_64 ? 8 : 4; + const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM; + // Size is header + address size + uint32_t length + const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len; + MakeRequestPacketHeader(command, request_packet, command_length); + request_packet.PutMaxHex64(addr, command_addr_byte_size); + request_packet.PutHex32(src_len); + request_packet.PutRawBytes(src, src_len); + + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + uint32_t kdp_error = reply_packet.GetU32(&offset); + if (kdp_error) + error.SetErrorStringWithFormat("kdp write memory failed (error %u)", + kdp_error); + else { + error.Clear(); + return src_len; } - return false; + } else { + error.SetErrorString("failed to send packet"); + } + return 0; } - -const char * -CommunicationKDP::GetCommandAsCString (uint8_t command) -{ - switch (command) - { - case KDP_CONNECT: return "KDP_CONNECT"; - case KDP_DISCONNECT: return "KDP_DISCONNECT"; - case KDP_HOSTINFO: return "KDP_HOSTINFO"; - case KDP_VERSION: return "KDP_VERSION"; - case KDP_MAXBYTES: return "KDP_MAXBYTES"; - case KDP_READMEM: return "KDP_READMEM"; - case KDP_WRITEMEM: return "KDP_WRITEMEM"; - case KDP_READREGS: return "KDP_READREGS"; - case KDP_WRITEREGS: return "KDP_WRITEREGS"; - case KDP_LOAD: return "KDP_LOAD"; - case KDP_IMAGEPATH: return "KDP_IMAGEPATH"; - case KDP_SUSPEND: return "KDP_SUSPEND"; - case KDP_RESUMECPUS: return "KDP_RESUMECPUS"; - case KDP_EXCEPTION: return "KDP_EXCEPTION"; - case KDP_TERMINATION: return "KDP_TERMINATION"; - case KDP_BREAKPOINT_SET: return "KDP_BREAKPOINT_SET"; - case KDP_BREAKPOINT_REMOVE: return "KDP_BREAKPOINT_REMOVE"; - case KDP_REGIONS: return "KDP_REGIONS"; - case KDP_REATTACH: return "KDP_REATTACH"; - case KDP_HOSTREBOOT: return "KDP_HOSTREBOOT"; - case KDP_READMEM64: return "KDP_READMEM64"; - case KDP_WRITEMEM64: return "KDP_WRITEMEM64"; - case KDP_BREAKPOINT_SET64: return "KDP_BREAKPOINT64_SET"; - case KDP_BREAKPOINT_REMOVE64: return "KDP_BREAKPOINT64_REMOVE"; - case KDP_KERNELVERSION: return "KDP_KERNELVERSION"; - case KDP_READPHYSMEM64: return "KDP_READPHYSMEM64"; - case KDP_WRITEPHYSMEM64: return "KDP_WRITEPHYSMEM64"; - case KDP_READIOPORT: return "KDP_READIOPORT"; - case KDP_WRITEIOPORT: return "KDP_WRITEIOPORT"; - case KDP_READMSR64: return "KDP_READMSR64"; - case KDP_WRITEMSR64: return "KDP_WRITEMSR64"; - case KDP_DUMPINFO: return "KDP_DUMPINFO"; +bool CommunicationKDP::SendRawRequest( + uint8_t command_byte, + const void *src, // Raw packet payload bytes + uint32_t src_len, // Raw packet payload length + DataExtractor &reply_packet, Error &error) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + // Size is header + address size + uint32_t length + const uint32_t command_length = 8 + src_len; + const CommandType command = (CommandType)command_byte; + MakeRequestPacketHeader(command, request_packet, command_length); + request_packet.PutRawBytes(src, src_len); + + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + uint32_t kdp_error = reply_packet.GetU32(&offset); + if (kdp_error && (command_byte != KDP_DUMPINFO)) + error.SetErrorStringWithFormat("request packet 0x%8.8x failed (error %u)", + command_byte, kdp_error); + else { + error.Clear(); + return true; } - return NULL; + } else { + error.SetErrorString("failed to send packet"); + } + return false; } -void -CommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len) -{ - DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size); - DumpPacket (s, extractor); +const char *CommunicationKDP::GetCommandAsCString(uint8_t command) { + switch (command) { + case KDP_CONNECT: + return "KDP_CONNECT"; + case KDP_DISCONNECT: + return "KDP_DISCONNECT"; + case KDP_HOSTINFO: + return "KDP_HOSTINFO"; + case KDP_VERSION: + return "KDP_VERSION"; + case KDP_MAXBYTES: + return "KDP_MAXBYTES"; + case KDP_READMEM: + return "KDP_READMEM"; + case KDP_WRITEMEM: + return "KDP_WRITEMEM"; + case KDP_READREGS: + return "KDP_READREGS"; + case KDP_WRITEREGS: + return "KDP_WRITEREGS"; + case KDP_LOAD: + return "KDP_LOAD"; + case KDP_IMAGEPATH: + return "KDP_IMAGEPATH"; + case KDP_SUSPEND: + return "KDP_SUSPEND"; + case KDP_RESUMECPUS: + return "KDP_RESUMECPUS"; + case KDP_EXCEPTION: + return "KDP_EXCEPTION"; + case KDP_TERMINATION: + return "KDP_TERMINATION"; + case KDP_BREAKPOINT_SET: + return "KDP_BREAKPOINT_SET"; + case KDP_BREAKPOINT_REMOVE: + return "KDP_BREAKPOINT_REMOVE"; + case KDP_REGIONS: + return "KDP_REGIONS"; + case KDP_REATTACH: + return "KDP_REATTACH"; + case KDP_HOSTREBOOT: + return "KDP_HOSTREBOOT"; + case KDP_READMEM64: + return "KDP_READMEM64"; + case KDP_WRITEMEM64: + return "KDP_WRITEMEM64"; + case KDP_BREAKPOINT_SET64: + return "KDP_BREAKPOINT64_SET"; + case KDP_BREAKPOINT_REMOVE64: + return "KDP_BREAKPOINT64_REMOVE"; + case KDP_KERNELVERSION: + return "KDP_KERNELVERSION"; + case KDP_READPHYSMEM64: + return "KDP_READPHYSMEM64"; + case KDP_WRITEPHYSMEM64: + return "KDP_WRITEPHYSMEM64"; + case KDP_READIOPORT: + return "KDP_READIOPORT"; + case KDP_WRITEIOPORT: + return "KDP_WRITEIOPORT"; + case KDP_READMSR64: + return "KDP_READMSR64"; + case KDP_WRITEMSR64: + return "KDP_WRITEMSR64"; + case KDP_DUMPINFO: + return "KDP_DUMPINFO"; + } + return NULL; } -void -CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet) -{ - const char *error_desc = NULL; - if (packet.GetByteSize() < 8) - { - error_desc = "error: invalid packet (too short): "; - } - else - { - lldb::offset_t offset = 0; - const uint8_t first_packet_byte = packet.GetU8 (&offset); - const uint8_t sequence_id = packet.GetU8 (&offset); - const uint16_t length = packet.GetU16 (&offset); - const uint32_t key = packet.GetU32 (&offset); - const CommandType command = ExtractCommand (first_packet_byte); - const char *command_name = GetCommandAsCString (command); - if (command_name) - { - const bool is_reply = ExtractIsReply(first_packet_byte); - s.Printf ("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ", - IsRunning(), - is_reply ? "<--" : "-->", - command_name, - first_packet_byte, - sequence_id, - length, - key); - - if (is_reply) - { - // Dump request reply packets - switch (command) - { - // Commands that return a single 32 bit error - case KDP_CONNECT: - case KDP_WRITEMEM: - case KDP_WRITEMEM64: - case KDP_BREAKPOINT_SET: - case KDP_BREAKPOINT_REMOVE: - case KDP_BREAKPOINT_SET64: - case KDP_BREAKPOINT_REMOVE64: - case KDP_WRITEREGS: - case KDP_LOAD: - case KDP_WRITEIOPORT: - case KDP_WRITEMSR64: - { - const uint32_t error = packet.GetU32 (&offset); - s.Printf(" (error=0x%8.8x)", error); - } - break; - - case KDP_DISCONNECT: - case KDP_REATTACH: - case KDP_HOSTREBOOT: - case KDP_SUSPEND: - case KDP_RESUMECPUS: - case KDP_EXCEPTION: - case KDP_TERMINATION: - // No return value for the reply, just the header to ack - s.PutCString(" ()"); - break; - - case KDP_HOSTINFO: - { - const uint32_t cpu_mask = packet.GetU32 (&offset); - const uint32_t cpu_type = packet.GetU32 (&offset); - const uint32_t cpu_subtype = packet.GetU32 (&offset); - s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype); - } - break; - - case KDP_VERSION: - { - const uint32_t version = packet.GetU32 (&offset); - const uint32_t feature = packet.GetU32 (&offset); - s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature); - } - break; - - case KDP_REGIONS: - { - const uint32_t region_count = packet.GetU32 (&offset); - s.Printf(" (count = %u", region_count); - for (uint32_t i=0; i<region_count; ++i) - { - const addr_t region_addr = packet.GetPointer (&offset); - const uint32_t region_size = packet.GetU32 (&offset); - const uint32_t region_prot = packet.GetU32 (&offset); - s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot)); - } - } - break; - - case KDP_READMEM: - case KDP_READMEM64: - case KDP_READPHYSMEM64: - { - const uint32_t error = packet.GetU32 (&offset); - const uint32_t count = packet.GetByteSize() - offset; - s.Printf(" (error = 0x%8.8x:\n", error); - if (count > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatBytesWithASCII, // Format to use - 1, // Size of each item in bytes - count, // Number of items - 16, // Number per line - m_last_read_memory_addr, // Don't show addresses before each line - 0, 0); // No bitfields - } - break; - - case KDP_READREGS: - { - const uint32_t error = packet.GetU32 (&offset); - const uint32_t count = packet.GetByteSize() - offset; - s.Printf(" (error = 0x%8.8x regs:\n", error); - if (count > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - m_addr_byte_size, // Size of each item in bytes - count / m_addr_byte_size, // Number of items - 16 / m_addr_byte_size, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - } - break; - - case KDP_KERNELVERSION: - { - const char *kernel_version = packet.PeekCStr(8); - s.Printf(" (version = \"%s\")", kernel_version); - } - break; - - case KDP_MAXBYTES: - { - const uint32_t max_bytes = packet.GetU32 (&offset); - s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes); - } - break; - case KDP_IMAGEPATH: - { - const char *path = packet.GetCStr(&offset); - s.Printf(" (path = \"%s\")", path); - } - break; - - case KDP_READIOPORT: - case KDP_READMSR64: - { - const uint32_t error = packet.GetU32 (&offset); - const uint32_t count = packet.GetByteSize() - offset; - s.Printf(" (error = 0x%8.8x io:\n", error); - if (count > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - 1, // Size of each item in bytes - count, // Number of items - 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - } - break; - case KDP_DUMPINFO: - { - const uint32_t count = packet.GetByteSize() - offset; - s.Printf(" (count = %u, bytes = \n", count); - if (count > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - 1, // Size of each item in bytes - count, // Number of items - 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - - } - break; - - default: - s.Printf(" (add support for dumping this packet reply!!!"); - break; - - } - } - else - { - // Dump request packets - switch (command) - { - case KDP_CONNECT: - { - const uint16_t reply_port = ntohs(packet.GetU16 (&offset)); - const uint16_t exc_port = ntohs(packet.GetU16 (&offset)); - s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset)); - } - break; - - case KDP_DISCONNECT: - case KDP_HOSTREBOOT: - case KDP_HOSTINFO: - case KDP_VERSION: - case KDP_REGIONS: - case KDP_KERNELVERSION: - case KDP_MAXBYTES: - case KDP_IMAGEPATH: - case KDP_SUSPEND: - // No args, just the header in the request... - s.PutCString(" ()"); - break; - - case KDP_RESUMECPUS: - { - const uint32_t cpu_mask = packet.GetU32 (&offset); - s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask); - } - break; - - case KDP_READMEM: - { - const uint32_t addr = packet.GetU32 (&offset); - const uint32_t size = packet.GetU32 (&offset); - s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size); - m_last_read_memory_addr = addr; - } - break; - - case KDP_WRITEMEM: - { - const uint32_t addr = packet.GetU32 (&offset); - const uint32_t size = packet.GetU32 (&offset); - s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size); - if (size > 0) - DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); - } - break; - - case KDP_READMEM64: - { - const uint64_t addr = packet.GetU64 (&offset); - const uint32_t size = packet.GetU32 (&offset); - s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size); - m_last_read_memory_addr = addr; - } - break; - - case KDP_READPHYSMEM64: - { - const uint64_t addr = packet.GetU64 (&offset); - const uint32_t size = packet.GetU32 (&offset); - const uint32_t lcpu = packet.GetU16 (&offset); - s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu); - m_last_read_memory_addr = addr; - } - break; - - case KDP_WRITEMEM64: - { - const uint64_t addr = packet.GetU64 (&offset); - const uint32_t size = packet.GetU32 (&offset); - s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size); - if (size > 0) - DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); - } - break; - - case KDP_WRITEPHYSMEM64: - { - const uint64_t addr = packet.GetU64 (&offset); - const uint32_t size = packet.GetU32 (&offset); - const uint32_t lcpu = packet.GetU16 (&offset); - s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu); - if (size > 0) - DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); - } - break; - - case KDP_READREGS: - { - const uint32_t cpu = packet.GetU32 (&offset); - const uint32_t flavor = packet.GetU32 (&offset); - s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor); - } - break; - - case KDP_WRITEREGS: - { - const uint32_t cpu = packet.GetU32 (&offset); - const uint32_t flavor = packet.GetU32 (&offset); - const uint32_t nbytes = packet.GetByteSize() - offset; - s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor); - if (nbytes > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - m_addr_byte_size, // Size of each item in bytes - nbytes / m_addr_byte_size, // Number of items - 16 / m_addr_byte_size, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - } - break; - - - case KDP_BREAKPOINT_SET: - case KDP_BREAKPOINT_REMOVE: - { - const uint32_t addr = packet.GetU32 (&offset); - s.Printf(" (addr = 0x%8.8x)", addr); - } - break; - - case KDP_BREAKPOINT_SET64: - case KDP_BREAKPOINT_REMOVE64: - { - const uint64_t addr = packet.GetU64 (&offset); - s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr); - } - break; - - - case KDP_LOAD: - { - const char *path = packet.GetCStr(&offset); - s.Printf(" (path = \"%s\")", path); - } - break; - - case KDP_EXCEPTION: - { - const uint32_t count = packet.GetU32 (&offset); - - for (uint32_t i=0; i<count; ++i) - { - const uint32_t cpu = packet.GetU32 (&offset); - const uint32_t exc = packet.GetU32 (&offset); - const uint32_t code = packet.GetU32 (&offset); - const uint32_t subcode = packet.GetU32 (&offset); - const char *exc_cstr = NULL; - switch (exc) - { - case 1: exc_cstr = "EXC_BAD_ACCESS"; break; - case 2: exc_cstr = "EXC_BAD_INSTRUCTION"; break; - case 3: exc_cstr = "EXC_ARITHMETIC"; break; - case 4: exc_cstr = "EXC_EMULATION"; break; - case 5: exc_cstr = "EXC_SOFTWARE"; break; - case 6: exc_cstr = "EXC_BREAKPOINT"; break; - case 7: exc_cstr = "EXC_SYSCALL"; break; - case 8: exc_cstr = "EXC_MACH_SYSCALL"; break; - case 9: exc_cstr = "EXC_RPC_ALERT"; break; - case 10: exc_cstr = "EXC_CRASH"; break; - default: - break; - } - - s.Printf ("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)} ", - cpu, exc_cstr, exc, code, code, subcode, subcode); - } - } - break; - - case KDP_TERMINATION: - { - const uint32_t term_code = packet.GetU32 (&offset); - const uint32_t exit_code = packet.GetU32 (&offset); - s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code); - } - break; - - case KDP_REATTACH: - { - const uint16_t reply_port = ntohs(packet.GetU16 (&offset)); - s.Printf(" (reply_port = %u)", reply_port); - } - break; - - case KDP_READMSR64: - { - const uint32_t address = packet.GetU32 (&offset); - const uint16_t lcpu = packet.GetU16 (&offset); - s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu); - } - break; - - case KDP_WRITEMSR64: - { - const uint32_t address = packet.GetU32 (&offset); - const uint16_t lcpu = packet.GetU16 (&offset); - const uint32_t nbytes = packet.GetByteSize() - offset; - s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes); - if (nbytes > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - 1, // Size of each item in bytes - nbytes, // Number of items - 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - } - break; - - case KDP_READIOPORT: - { - const uint16_t lcpu = packet.GetU16 (&offset); - const uint16_t address = packet.GetU16 (&offset); - const uint16_t nbytes = packet.GetU16 (&offset); - s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes); - } - break; - - case KDP_WRITEIOPORT: - { - const uint16_t lcpu = packet.GetU16 (&offset); - const uint16_t address = packet.GetU16 (&offset); - const uint16_t nbytes = packet.GetU16 (&offset); - s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes); - if (nbytes > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - 1, // Size of each item in bytes - nbytes, // Number of items - 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - } - break; - - case KDP_DUMPINFO: - { - const uint32_t count = packet.GetByteSize() - offset; - s.Printf(" (count = %u, bytes = \n", count); - if (count > 0) - packet.Dump (&s, // Stream to dump to - offset, // Offset within "packet" - eFormatHex, // Format to use - 1, // Size of each item in bytes - count, // Number of items - 16, // Number per line - LLDB_INVALID_ADDRESS, // Don't show addresses before each line - 0, 0); // No bitfields - - } - break; - - } - } - } - else - { - error_desc = "error: invalid packet command: "; - } - } - - if (error_desc) - { - s.PutCString (error_desc); - - packet.Dump (&s, // Stream to dump to - 0, // Offset into "packet" - eFormatBytes, // Dump as hex bytes - 1, // Size of each item is 1 for single bytes - packet.GetByteSize(), // Number of bytes - UINT32_MAX, // Num bytes per line - LLDB_INVALID_ADDRESS, // Base address - 0, 0); // Bitfield info set to not do anything bitfield related - } +void CommunicationKDP::DumpPacket(Stream &s, const void *data, + uint32_t data_len) { + DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size); + DumpPacket(s, extractor); } -uint32_t -CommunicationKDP::SendRequestReadRegisters (uint32_t cpu, - uint32_t flavor, - void *dst, - uint32_t dst_len, - Error &error) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_READREGS; - // Size is header + 4 byte cpu and 4 byte flavor - const uint32_t command_length = 8 + 4 + 4; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutHex32 (cpu); - request_packet.PutHex32 (flavor); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - uint32_t kdp_error = reply_packet.GetU32 (&offset); - uint32_t src_len = reply_packet.GetByteSize() - 12; - - if (src_len > 0) - { - const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len); - const void *src = reply_packet.GetData(&offset, bytes_to_copy); - if (src) - { - ::memcpy (dst, src, bytes_to_copy); - 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; +void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) { + const char *error_desc = NULL; + if (packet.GetByteSize() < 8) { + error_desc = "error: invalid packet (too short): "; + } else { + lldb::offset_t offset = 0; + const uint8_t first_packet_byte = packet.GetU8(&offset); + const uint8_t sequence_id = packet.GetU8(&offset); + const uint16_t length = packet.GetU16(&offset); + const uint32_t key = packet.GetU32(&offset); + const CommandType command = ExtractCommand(first_packet_byte); + const char *command_name = GetCommandAsCString(command); + if (command_name) { + const bool is_reply = ExtractIsReply(first_packet_byte); + s.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ", + IsRunning(), is_reply ? "<--" : "-->", command_name, + first_packet_byte, sequence_id, length, key); + + if (is_reply) { + // Dump request reply packets + switch (command) { + // Commands that return a single 32 bit error + case KDP_CONNECT: + case KDP_WRITEMEM: + case KDP_WRITEMEM64: + case KDP_BREAKPOINT_SET: + case KDP_BREAKPOINT_REMOVE: + case KDP_BREAKPOINT_SET64: + case KDP_BREAKPOINT_REMOVE64: + case KDP_WRITEREGS: + case KDP_LOAD: + case KDP_WRITEIOPORT: + case KDP_WRITEMSR64: { + const uint32_t error = packet.GetU32(&offset); + s.Printf(" (error=0x%8.8x)", error); + } break; + + case KDP_DISCONNECT: + case KDP_REATTACH: + case KDP_HOSTREBOOT: + case KDP_SUSPEND: + case KDP_RESUMECPUS: + case KDP_EXCEPTION: + case KDP_TERMINATION: + // No return value for the reply, just the header to ack + s.PutCString(" ()"); + break; + + case KDP_HOSTINFO: { + const uint32_t cpu_mask = packet.GetU32(&offset); + const uint32_t cpu_type = packet.GetU32(&offset); + const uint32_t cpu_subtype = packet.GetU32(&offset); + s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", + cpu_mask, cpu_type, cpu_subtype); + } break; + + case KDP_VERSION: { + const uint32_t version = packet.GetU32(&offset); + const uint32_t feature = packet.GetU32(&offset); + s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature); + } break; + + case KDP_REGIONS: { + const uint32_t region_count = packet.GetU32(&offset); + s.Printf(" (count = %u", region_count); + for (uint32_t i = 0; i < region_count; ++i) { + const addr_t region_addr = packet.GetPointer(&offset); + const uint32_t region_size = packet.GetU32(&offset); + const uint32_t region_prot = packet.GetU32(&offset); + s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 + " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", + region_addr, region_addr, region_addr + region_size, + region_size, GetPermissionsAsCString(region_prot)); + } + } break; + + case KDP_READMEM: + case KDP_READMEM64: + case KDP_READPHYSMEM64: { + const uint32_t error = packet.GetU32(&offset); + const uint32_t count = packet.GetByteSize() - offset; + s.Printf(" (error = 0x%8.8x:\n", error); + if (count > 0) + packet.Dump(&s, // Stream to dump to + offset, // Offset within "packet" + eFormatBytesWithASCII, // Format to use + 1, // Size of each item in bytes + count, // Number of items + 16, // Number per line + m_last_read_memory_addr, // Don't show addresses before + // each line + 0, 0); // No bitfields + } break; + + case KDP_READREGS: { + const uint32_t error = packet.GetU32(&offset); + const uint32_t count = packet.GetByteSize() - offset; + s.Printf(" (error = 0x%8.8x regs:\n", error); + if (count > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + m_addr_byte_size, // Size of each item in bytes + count / m_addr_byte_size, // Number of items + 16 / m_addr_byte_size, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + } break; + + case KDP_KERNELVERSION: { + const char *kernel_version = packet.PeekCStr(8); + s.Printf(" (version = \"%s\")", kernel_version); + } break; + + case KDP_MAXBYTES: { + const uint32_t max_bytes = packet.GetU32(&offset); + s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes); + } break; + case KDP_IMAGEPATH: { + const char *path = packet.GetCStr(&offset); + s.Printf(" (path = \"%s\")", path); + } break; + + case KDP_READIOPORT: + case KDP_READMSR64: { + const uint32_t error = packet.GetU32(&offset); + const uint32_t count = packet.GetByteSize() - offset; + s.Printf(" (error = 0x%8.8x io:\n", error); + if (count > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + 1, // Size of each item in bytes + count, // Number of items + 16, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + } break; + case KDP_DUMPINFO: { + const uint32_t count = packet.GetByteSize() - offset; + s.Printf(" (count = %u, bytes = \n", count); + if (count > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + 1, // Size of each item in bytes + count, // Number of items + 16, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + + } break; + + default: + s.Printf(" (add support for dumping this packet reply!!!"); + break; + } + } else { + // Dump request packets + switch (command) { + case KDP_CONNECT: { + const uint16_t reply_port = ntohs(packet.GetU16(&offset)); + const uint16_t exc_port = ntohs(packet.GetU16(&offset)); + s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", + reply_port, exc_port, packet.GetCStr(&offset)); + } break; + + case KDP_DISCONNECT: + case KDP_HOSTREBOOT: + case KDP_HOSTINFO: + case KDP_VERSION: + case KDP_REGIONS: + case KDP_KERNELVERSION: + case KDP_MAXBYTES: + case KDP_IMAGEPATH: + case KDP_SUSPEND: + // No args, just the header in the request... + s.PutCString(" ()"); + break; + + case KDP_RESUMECPUS: { + const uint32_t cpu_mask = packet.GetU32(&offset); + s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask); + } break; + + case KDP_READMEM: { + const uint32_t addr = packet.GetU32(&offset); + const uint32_t size = packet.GetU32(&offset); + s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size); + m_last_read_memory_addr = addr; + } break; + + case KDP_WRITEMEM: { + const uint32_t addr = packet.GetU32(&offset); + const uint32_t size = packet.GetU32(&offset); + s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size); + if (size > 0) + DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, + 32, addr); + } break; + + case KDP_READMEM64: { + const uint64_t addr = packet.GetU64(&offset); + const uint32_t size = packet.GetU32(&offset); + s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size); + m_last_read_memory_addr = addr; + } break; + + case KDP_READPHYSMEM64: { + const uint64_t addr = packet.GetU64(&offset); + const uint32_t size = packet.GetU32(&offset); + const uint32_t lcpu = packet.GetU16(&offset); + s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, + lcpu); + m_last_read_memory_addr = addr; + } break; + + case KDP_WRITEMEM64: { + const uint64_t addr = packet.GetU64(&offset); + const uint32_t size = packet.GetU32(&offset); + s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, + size); + if (size > 0) + DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, + 32, addr); + } break; + + case KDP_WRITEPHYSMEM64: { + const uint64_t addr = packet.GetU64(&offset); + const uint32_t size = packet.GetU32(&offset); + const uint32_t lcpu = packet.GetU16(&offset); + s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", + addr, size, lcpu); + if (size > 0) + DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, + 32, addr); + } break; + + case KDP_READREGS: { + const uint32_t cpu = packet.GetU32(&offset); + const uint32_t flavor = packet.GetU32(&offset); + s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor); + } break; + + case KDP_WRITEREGS: { + const uint32_t cpu = packet.GetU32(&offset); + const uint32_t flavor = packet.GetU32(&offset); + const uint32_t nbytes = packet.GetByteSize() - offset; + s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor); + if (nbytes > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + m_addr_byte_size, // Size of each item in bytes + nbytes / m_addr_byte_size, // Number of items + 16 / m_addr_byte_size, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + } break; + + case KDP_BREAKPOINT_SET: + case KDP_BREAKPOINT_REMOVE: { + const uint32_t addr = packet.GetU32(&offset); + s.Printf(" (addr = 0x%8.8x)", addr); + } break; + + case KDP_BREAKPOINT_SET64: + case KDP_BREAKPOINT_REMOVE64: { + const uint64_t addr = packet.GetU64(&offset); + s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr); + } break; + + case KDP_LOAD: { + const char *path = packet.GetCStr(&offset); + s.Printf(" (path = \"%s\")", path); + } break; + + case KDP_EXCEPTION: { + const uint32_t count = packet.GetU32(&offset); + + for (uint32_t i = 0; i < count; ++i) { + const uint32_t cpu = packet.GetU32(&offset); + const uint32_t exc = packet.GetU32(&offset); + const uint32_t code = packet.GetU32(&offset); + const uint32_t subcode = packet.GetU32(&offset); + const char *exc_cstr = NULL; + switch (exc) { + case 1: + exc_cstr = "EXC_BAD_ACCESS"; + break; + case 2: + exc_cstr = "EXC_BAD_INSTRUCTION"; + break; + case 3: + exc_cstr = "EXC_ARITHMETIC"; + break; + case 4: + exc_cstr = "EXC_EMULATION"; + break; + case 5: + exc_cstr = "EXC_SOFTWARE"; + break; + case 6: + exc_cstr = "EXC_BREAKPOINT"; + break; + case 7: + exc_cstr = "EXC_SYSCALL"; + break; + case 8: + exc_cstr = "EXC_MACH_SYSCALL"; + break; + case 9: + exc_cstr = "EXC_RPC_ALERT"; + break; + case 10: + exc_cstr = "EXC_CRASH"; + break; + default: + break; } + + s.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), " + "subcode = %u (0x%8.8x)} ", + cpu, exc_cstr, exc, code, code, subcode, subcode); + } + } break; + + case KDP_TERMINATION: { + const uint32_t term_code = packet.GetU32(&offset); + const uint32_t exit_code = packet.GetU32(&offset); + s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", + term_code, term_code, exit_code, exit_code); + } break; + + case KDP_REATTACH: { + const uint16_t reply_port = ntohs(packet.GetU16(&offset)); + s.Printf(" (reply_port = %u)", reply_port); + } break; + + case KDP_READMSR64: { + const uint32_t address = packet.GetU32(&offset); + const uint16_t lcpu = packet.GetU16(&offset); + s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu); + } break; + + case KDP_WRITEMSR64: { + const uint32_t address = packet.GetU32(&offset); + const uint16_t lcpu = packet.GetU16(&offset); + const uint32_t nbytes = packet.GetByteSize() - offset; + s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, + address, nbytes); + if (nbytes > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + 1, // Size of each item in bytes + nbytes, // Number of items + 16, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + } break; + + case KDP_READIOPORT: { + const uint16_t lcpu = packet.GetU16(&offset); + const uint16_t address = packet.GetU16(&offset); + const uint16_t nbytes = packet.GetU16(&offset); + s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, + nbytes); + } break; + + case KDP_WRITEIOPORT: { + const uint16_t lcpu = packet.GetU16(&offset); + const uint16_t address = packet.GetU16(&offset); + const uint16_t nbytes = packet.GetU16(&offset); + s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, + address, nbytes); + if (nbytes > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + 1, // Size of each item in bytes + nbytes, // Number of items + 16, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + } break; + + case KDP_DUMPINFO: { + const uint32_t count = packet.GetByteSize() - offset; + s.Printf(" (count = %u, bytes = \n", count); + if (count > 0) + packet.Dump( + &s, // Stream to dump to + offset, // Offset within "packet" + eFormatHex, // Format to use + 1, // Size of each item in bytes + count, // Number of items + 16, // Number per line + LLDB_INVALID_ADDRESS, // Don't show addresses before each line + 0, 0); // No bitfields + + } break; } - if (kdp_error) - error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error); - else - error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor); + } + } else { + error_desc = "error: invalid packet command: "; } - else - { - error.SetErrorString ("failed to send packet"); - } - return 0; + } + + if (error_desc) { + s.PutCString(error_desc); + + packet.Dump(&s, // Stream to dump to + 0, // Offset into "packet" + eFormatBytes, // Dump as hex bytes + 1, // Size of each item is 1 for single bytes + packet.GetByteSize(), // Number of bytes + UINT32_MAX, // Num bytes per line + LLDB_INVALID_ADDRESS, // Base address + 0, 0); // Bitfield info set to not do anything bitfield related + } } -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 + src_len; - 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_packet, reply_packet)) - { - lldb::offset_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); +uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu, + uint32_t flavor, void *dst, + uint32_t dst_len, + Error &error) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_READREGS; + // Size is header + 4 byte cpu and 4 byte flavor + const uint32_t command_length = 8 + 4 + 4; + MakeRequestPacketHeader(command, request_packet, command_length); + request_packet.PutHex32(cpu); + request_packet.PutHex32(flavor); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + uint32_t kdp_error = reply_packet.GetU32(&offset); + uint32_t src_len = reply_packet.GetByteSize() - 12; + + if (src_len > 0) { + const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len); + const void *src = reply_packet.GetData(&offset, bytes_to_copy); + if (src) { + ::memcpy(dst, src, bytes_to_copy); + 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; + } } + if (kdp_error) + error.SetErrorStringWithFormat( + "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, + flavor, kdp_error); else - { - error.SetErrorString ("failed to send packet"); - } - return 0; + error.SetErrorStringWithFormat( + "failed to read kdp registers for cpu %u flavor %u", cpu, flavor); + } else { + error.SetErrorString("failed to send packet"); + } + return 0; } - -bool -CommunicationKDP::SendRequestResume () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_RESUMECPUS; - const uint32_t command_length = 12; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutHex32(GetCPUMask()); - - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - return true; - return false; +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 + src_len; + 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_packet, reply_packet)) { + lldb::offset_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); + } else { + error.SetErrorString("failed to send packet"); + } + return 0; } -bool -CommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr) -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - bool use_64 = (GetVersion() >= 11); - uint32_t command_addr_byte_size = use_64 ? 8 : 4; - const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET ): - (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE); +bool CommunicationKDP::SendRequestResume() { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_RESUMECPUS; + const uint32_t command_length = 12; + MakeRequestPacketHeader(command, request_packet, command_length); + request_packet.PutHex32(GetCPUMask()); - const uint32_t command_length = 8 + command_addr_byte_size; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutMaxHex64 (addr, command_addr_byte_size); - - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - { - lldb::offset_t offset = 8; - uint32_t kdp_error = reply_packet.GetU32 (&offset); - if (kdp_error == 0) - return true; - } - return false; + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) + return true; + return false; } -bool -CommunicationKDP::SendRequestSuspend () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_SUSPEND; - const uint32_t command_length = 8; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_packet, reply_packet)) - return true; - return false; +bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + bool use_64 = (GetVersion() >= 11); + uint32_t command_addr_byte_size = use_64 ? 8 : 4; + const CommandType command = + set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET) + : (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE); + + const uint32_t command_length = 8 + command_addr_byte_size; + MakeRequestPacketHeader(command, request_packet, command_length); + request_packet.PutMaxHex64(addr, command_addr_byte_size); + + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) { + lldb::offset_t offset = 8; + uint32_t kdp_error = reply_packet.GetU32(&offset); + if (kdp_error == 0) + return true; + } + return false; } +bool CommunicationKDP::SendRequestSuspend() { + PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, + m_byte_order); + const CommandType command = KDP_SUSPEND; + const uint32_t command_length = 8; + MakeRequestPacketHeader(command, request_packet, command_length); + DataExtractor reply_packet; + if (SendRequestAndGetReply(command, request_packet, reply_packet)) + return true; + return false; +} diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h index fe77cbb9ae4..6e02cb22d51 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -18,330 +18,248 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/Communication.h" #include "lldb/Core/Listener.h" #include "lldb/Core/StreamBuffer.h" #include "lldb/Host/Predicate.h" #include "lldb/Host/TimeValue.h" +#include "lldb/lldb-private.h" -class CommunicationKDP : public lldb_private::Communication -{ +class CommunicationKDP : public lldb_private::Communication { public: - enum - { - eBroadcastBitRunPacketSent = kLoUserBroadcastBit - }; - - const static uint32_t kMaxPacketSize = 1200; - const static uint32_t kMaxDataSize = 1024; - typedef lldb_private::StreamBuffer<1024> PacketStreamType; - typedef enum - { - KDP_CONNECT = 0u, - KDP_DISCONNECT, - KDP_HOSTINFO, - KDP_VERSION, - KDP_MAXBYTES, - KDP_READMEM, - KDP_WRITEMEM, - KDP_READREGS, - KDP_WRITEREGS, - KDP_LOAD, - KDP_IMAGEPATH, - KDP_SUSPEND, - KDP_RESUMECPUS, - KDP_EXCEPTION, - KDP_TERMINATION, - KDP_BREAKPOINT_SET, - KDP_BREAKPOINT_REMOVE, - KDP_REGIONS, - KDP_REATTACH, - KDP_HOSTREBOOT, - KDP_READMEM64, - KDP_WRITEMEM64, - KDP_BREAKPOINT_SET64, - KDP_BREAKPOINT_REMOVE64, - KDP_KERNELVERSION, - KDP_READPHYSMEM64, - KDP_WRITEPHYSMEM64, - KDP_READIOPORT, - KDP_WRITEIOPORT, - KDP_READMSR64, - KDP_WRITEMSR64, - KDP_DUMPINFO - } CommandType; - - enum - { - KDP_FEATURE_BP = (1u << 0) - }; - - typedef enum - { - KDP_PROTERR_SUCCESS = 0, - KDP_PROTERR_ALREADY_CONNECTED, - KDP_PROTERR_BAD_NBYTES, - KDP_PROTERR_BADFLAVOR - } KDPError; - - typedef enum - { - ePacketTypeRequest = 0x00u, - ePacketTypeReply = 0x80u, - ePacketTypeMask = 0x80u, - eCommandTypeMask = 0x7fu - } PacketType; - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CommunicationKDP (const char *comm_name); - - virtual - ~CommunicationKDP(); - - bool - SendRequestPacket (const PacketStreamType &request_packet); - - // Wait for a packet within 'nsec' seconds - size_t - WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response, - uint32_t usec); - - bool - GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock); - - bool - CheckForPacket (const uint8_t *src, - size_t src_len, - lldb_private::DataExtractor &packet); - bool - IsRunning() const - { - return m_is_running.GetValue(); - } - - //------------------------------------------------------------------ - // Set the global packet timeout. - // - // For clients, this is the timeout that gets used when sending - // packets and waiting for responses. For servers, this might not - // get used, and if it doesn't this should be moved to the - // CommunicationKDPClient. - //------------------------------------------------------------------ - uint32_t - SetPacketTimeout (uint32_t packet_timeout) - { - const uint32_t old_packet_timeout = m_packet_timeout; - m_packet_timeout = packet_timeout; - return old_packet_timeout; - } - - uint32_t - GetPacketTimeoutInMicroSeconds () const - { - return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec; - } - - //------------------------------------------------------------------ - // Public Request Packets - //------------------------------------------------------------------ - bool - SendRequestConnect (uint16_t reply_port, - uint16_t exc_port, - const char *greeting); - - bool - SendRequestReattach (uint16_t reply_port); - - bool - SendRequestDisconnect (); - - uint32_t - SendRequestReadMemory (lldb::addr_t addr, - void *dst, - uint32_t dst_size, - lldb_private::Error &error); - - uint32_t - SendRequestWriteMemory (lldb::addr_t addr, - const void *src, - uint32_t src_len, - lldb_private::Error &error); - - bool - SendRawRequest (uint8_t command_byte, - const void *src, - uint32_t src_len, - lldb_private::DataExtractor &reply, - lldb_private::Error &error); - - uint32_t - SendRequestReadRegisters (uint32_t cpu, - uint32_t flavor, - 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 (); - - // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... - // const char * - // GetImagePath (); - - uint32_t - GetVersion (); - - uint32_t - GetFeatureFlags (); - - bool - LocalBreakpointsAreSupported () - { - return (GetFeatureFlags() & KDP_FEATURE_BP) != 0; - } - - uint32_t - GetCPUMask (); - - uint32_t - GetCPUType (); - - uint32_t - GetCPUSubtype (); - - lldb_private::UUID - GetUUID (); - - bool - RemoteIsEFI (); - - bool - RemoteIsDarwinKernel (); - - lldb::addr_t - GetLoadAddress (); - - bool - SendRequestResume (); - - bool - SendRequestSuspend (); - - bool - SendRequestBreakpoint (bool set, lldb::addr_t addr); + enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit }; + + const static uint32_t kMaxPacketSize = 1200; + const static uint32_t kMaxDataSize = 1024; + typedef lldb_private::StreamBuffer<1024> PacketStreamType; + typedef enum { + KDP_CONNECT = 0u, + KDP_DISCONNECT, + KDP_HOSTINFO, + KDP_VERSION, + KDP_MAXBYTES, + KDP_READMEM, + KDP_WRITEMEM, + KDP_READREGS, + KDP_WRITEREGS, + KDP_LOAD, + KDP_IMAGEPATH, + KDP_SUSPEND, + KDP_RESUMECPUS, + KDP_EXCEPTION, + KDP_TERMINATION, + KDP_BREAKPOINT_SET, + KDP_BREAKPOINT_REMOVE, + KDP_REGIONS, + KDP_REATTACH, + KDP_HOSTREBOOT, + KDP_READMEM64, + KDP_WRITEMEM64, + KDP_BREAKPOINT_SET64, + KDP_BREAKPOINT_REMOVE64, + KDP_KERNELVERSION, + KDP_READPHYSMEM64, + KDP_WRITEPHYSMEM64, + KDP_READIOPORT, + KDP_WRITEIOPORT, + KDP_READMSR64, + KDP_WRITEMSR64, + KDP_DUMPINFO + } CommandType; + + enum { KDP_FEATURE_BP = (1u << 0) }; + + typedef enum { + KDP_PROTERR_SUCCESS = 0, + KDP_PROTERR_ALREADY_CONNECTED, + KDP_PROTERR_BAD_NBYTES, + KDP_PROTERR_BADFLAVOR + } KDPError; + + typedef enum { + ePacketTypeRequest = 0x00u, + ePacketTypeReply = 0x80u, + ePacketTypeMask = 0x80u, + eCommandTypeMask = 0x7fu + } PacketType; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CommunicationKDP(const char *comm_name); + + virtual ~CommunicationKDP(); + + bool SendRequestPacket(const PacketStreamType &request_packet); + + // Wait for a packet within 'nsec' seconds + size_t + WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response, + uint32_t usec); + + bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock); + + bool CheckForPacket(const uint8_t *src, size_t src_len, + lldb_private::DataExtractor &packet); + bool IsRunning() const { return m_is_running.GetValue(); } + + //------------------------------------------------------------------ + // Set the global packet timeout. + // + // For clients, this is the timeout that gets used when sending + // packets and waiting for responses. For servers, this might not + // get used, and if it doesn't this should be moved to the + // CommunicationKDPClient. + //------------------------------------------------------------------ + uint32_t SetPacketTimeout(uint32_t packet_timeout) { + const uint32_t old_packet_timeout = m_packet_timeout; + m_packet_timeout = packet_timeout; + return old_packet_timeout; + } + + uint32_t GetPacketTimeoutInMicroSeconds() const { + return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec; + } + + //------------------------------------------------------------------ + // Public Request Packets + //------------------------------------------------------------------ + bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port, + const char *greeting); + + bool SendRequestReattach(uint16_t reply_port); + + bool SendRequestDisconnect(); + + uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst, + uint32_t dst_size, lldb_private::Error &error); + + uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src, + uint32_t src_len, lldb_private::Error &error); + + bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len, + lldb_private::DataExtractor &reply, + lldb_private::Error &error); + + uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst, + uint32_t dst_size, + lldb_private::Error &error); -protected: + uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor, + const void *src, uint32_t src_size, + lldb_private::Error &error); + + const char *GetKernelVersion(); + + // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... + // const char * + // GetImagePath (); + + uint32_t GetVersion(); + + uint32_t GetFeatureFlags(); + + bool LocalBreakpointsAreSupported() { + return (GetFeatureFlags() & KDP_FEATURE_BP) != 0; + } + + uint32_t GetCPUMask(); + + uint32_t GetCPUType(); - bool - SendRequestPacketNoLock (const PacketStreamType &request_packet); - - size_t - WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response, - uint32_t timeout_usec); - - bool - WaitForNotRunningPrivate(const std::chrono::microseconds &timeout); - - void - MakeRequestPacketHeader (CommandType request_type, - PacketStreamType &request_packet, - uint16_t request_length); - - //------------------------------------------------------------------ - // Protected Request Packets (use public accessors which will cache - // results. - //------------------------------------------------------------------ - bool - SendRequestVersion (); - - bool - SendRequestHostInfo (); - - bool - SendRequestKernelVersion (); - - // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... - //bool - //SendRequestImagePath (); - - void - DumpPacket (lldb_private::Stream &s, - const void *data, - uint32_t data_len); - - void - DumpPacket (lldb_private::Stream &s, - const lldb_private::DataExtractor& extractor); - - bool - VersionIsValid() const - { - return m_kdp_version_version != 0; - } - - bool - HostInfoIsValid() const - { - return m_kdp_hostinfo_cpu_type != 0; - } - - bool - ExtractIsReply (uint8_t first_packet_byte) const - { - // TODO: handle big endian... - return (first_packet_byte & ePacketTypeMask) != 0; - } - - CommandType - ExtractCommand (uint8_t first_packet_byte) const - { - // TODO: handle big endian... - return (CommandType)(first_packet_byte & eCommandTypeMask); - } - - static const char * - GetCommandAsCString (uint8_t command); - - void - ClearKDPSettings (); - - bool - SendRequestAndGetReply (const CommandType command, - const PacketStreamType &request_packet, - lldb_private::DataExtractor &reply_packet); - //------------------------------------------------------------------ - // Classes that inherit from CommunicationKDP can see and modify these - //------------------------------------------------------------------ - uint32_t m_addr_byte_size; - lldb::ByteOrder m_byte_order; - uint32_t m_packet_timeout; - std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time - lldb_private::Predicate<bool> m_is_running; - uint32_t m_session_key; - uint8_t m_request_sequence_id; - uint8_t m_exception_sequence_id; - uint32_t m_kdp_version_version; - uint32_t m_kdp_version_feature; - uint32_t m_kdp_hostinfo_cpu_mask; - uint32_t m_kdp_hostinfo_cpu_type; - uint32_t m_kdp_hostinfo_cpu_subtype; - std::string m_kernel_version; - //std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... - lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging + uint32_t GetCPUSubtype(); + + lldb_private::UUID GetUUID(); + + bool RemoteIsEFI(); + + bool RemoteIsDarwinKernel(); + + lldb::addr_t GetLoadAddress(); + + bool SendRequestResume(); + + bool SendRequestSuspend(); + + bool SendRequestBreakpoint(bool set, lldb::addr_t addr); + +protected: + bool SendRequestPacketNoLock(const PacketStreamType &request_packet); + + size_t WaitForPacketWithTimeoutMicroSecondsNoLock( + lldb_private::DataExtractor &response, uint32_t timeout_usec); + + bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout); + + void MakeRequestPacketHeader(CommandType request_type, + PacketStreamType &request_packet, + uint16_t request_length); + + //------------------------------------------------------------------ + // Protected Request Packets (use public accessors which will cache + // results. + //------------------------------------------------------------------ + bool SendRequestVersion(); + + bool SendRequestHostInfo(); + + bool SendRequestKernelVersion(); + + // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... + // bool + // SendRequestImagePath (); + + void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len); + + void DumpPacket(lldb_private::Stream &s, + const lldb_private::DataExtractor &extractor); + + bool VersionIsValid() const { return m_kdp_version_version != 0; } + + bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; } + + bool ExtractIsReply(uint8_t first_packet_byte) const { + // TODO: handle big endian... + return (first_packet_byte & ePacketTypeMask) != 0; + } + + CommandType ExtractCommand(uint8_t first_packet_byte) const { + // TODO: handle big endian... + return (CommandType)(first_packet_byte & eCommandTypeMask); + } + + static const char *GetCommandAsCString(uint8_t command); + + void ClearKDPSettings(); + + bool SendRequestAndGetReply(const CommandType command, + const PacketStreamType &request_packet, + lldb_private::DataExtractor &reply_packet); + //------------------------------------------------------------------ + // Classes that inherit from CommunicationKDP can see and modify these + //------------------------------------------------------------------ + uint32_t m_addr_byte_size; + lldb::ByteOrder m_byte_order; + uint32_t m_packet_timeout; + std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving + // packets to a single thread at a time + lldb_private::Predicate<bool> m_is_running; + uint32_t m_session_key; + uint8_t m_request_sequence_id; + uint8_t m_exception_sequence_id; + uint32_t m_kdp_version_version; + uint32_t m_kdp_version_feature; + uint32_t m_kdp_hostinfo_cpu_mask; + uint32_t m_kdp_hostinfo_cpu_type; + uint32_t m_kdp_hostinfo_cpu_subtype; + std::string m_kernel_version; + // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to + // hang the KDP connection... + lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging private: - //------------------------------------------------------------------ - // For CommunicationKDP only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (CommunicationKDP); + //------------------------------------------------------------------ + // For CommunicationKDP only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN(CommunicationKDP); }; -#endif // liblldb_CommunicationKDP_h_ +#endif // liblldb_CommunicationKDP_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 9b402ff63bf..756b145b3d6 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -16,9 +16,9 @@ // Other libraries and framework includes #include "lldb/Core/Debugger.h" -#include "lldb/Core/PluginManager.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #include "lldb/Core/UUID.h" #include "lldb/Host/ConnectionFileDescriptor.h" @@ -42,1168 +42,1000 @@ #define USEC_PER_SEC 1000000 // Project includes +#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" +#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" #include "ProcessKDP.h" #include "ProcessKDPLog.h" #include "ThreadKDP.h" -#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" -#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" using namespace lldb; using namespace lldb_private; namespace { - static PropertyDefinition - g_properties[] = - { - { "packet-timeout" , OptionValue::eTypeUInt64 , true , 5, NULL, NULL, "Specify the default packet timeout in seconds." }, - { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL } - }; - - enum - { - ePropertyPacketTimeout - }; - - class PluginProperties : public Properties - { - public: - - static ConstString - GetSettingName () - { - return ProcessKDP::GetPluginNameStatic(); - } +static PropertyDefinition g_properties[] = { + {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, NULL, + "Specify the default packet timeout in seconds."}, + {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; - PluginProperties() : - Properties () - { - m_collection_sp.reset (new OptionValueProperties(GetSettingName())); - m_collection_sp->Initialize(g_properties); - } - - virtual - ~PluginProperties() - { - } - - uint64_t - GetPacketTimeout() - { - const uint32_t idx = ePropertyPacketTimeout; - return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value); - } - }; +enum { ePropertyPacketTimeout }; - typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP; +class PluginProperties : public Properties { +public: + static ConstString GetSettingName() { + return ProcessKDP::GetPluginNameStatic(); + } + + PluginProperties() : Properties() { + m_collection_sp.reset(new OptionValueProperties(GetSettingName())); + m_collection_sp->Initialize(g_properties); + } + + virtual ~PluginProperties() {} + + uint64_t GetPacketTimeout() { + const uint32_t idx = ePropertyPacketTimeout; + return m_collection_sp->GetPropertyAtIndexAsUInt64( + NULL, idx, g_properties[idx].default_uint_value); + } +}; + +typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP; + +static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { + static ProcessKDPPropertiesSP g_settings_sp; + if (!g_settings_sp) + g_settings_sp.reset(new PluginProperties()); + return g_settings_sp; +} - static const ProcessKDPPropertiesSP & - GetGlobalPluginProperties() - { - static ProcessKDPPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp.reset (new PluginProperties ()); - return g_settings_sp; - } - } // anonymous namespace end static const lldb::tid_t g_kernel_tid = 1; -ConstString -ProcessKDP::GetPluginNameStatic() -{ - static ConstString g_name("kdp-remote"); - return g_name; +ConstString ProcessKDP::GetPluginNameStatic() { + static ConstString g_name("kdp-remote"); + return g_name; } -const char * -ProcessKDP::GetPluginDescriptionStatic() -{ - return "KDP Remote protocol based debugging plug-in for darwin kernel debugging."; +const char *ProcessKDP::GetPluginDescriptionStatic() { + return "KDP Remote protocol based debugging plug-in for darwin kernel " + "debugging."; } -void -ProcessKDP::Terminate() -{ - PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance); +void ProcessKDP::Terminate() { + PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance); } - -lldb::ProcessSP -ProcessKDP::CreateInstance (TargetSP target_sp, - ListenerSP listener_sp, - const FileSpec *crash_file_path) -{ - lldb::ProcessSP process_sp; - if (crash_file_path == NULL) - process_sp.reset(new ProcessKDP (target_sp, listener_sp)); - return process_sp; +lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp, + ListenerSP listener_sp, + const FileSpec *crash_file_path) { + lldb::ProcessSP process_sp; + if (crash_file_path == NULL) + process_sp.reset(new ProcessKDP(target_sp, listener_sp)); + return process_sp; } -bool -ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) -{ - if (plugin_specified_by_name) - return true; - - // For now we are just making sure the file exists for a given module - Module *exe_module = target_sp->GetExecutableModulePointer(); - if (exe_module) - { - const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple(); - switch (triple_ref.getOS()) - { - case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for iOS, but accept darwin just in case - case llvm::Triple::MacOSX: // For desktop targets - case llvm::Triple::IOS: // For arm targets - case llvm::Triple::TvOS: - case llvm::Triple::WatchOS: - if (triple_ref.getVendor() == llvm::Triple::Apple) - { - ObjectFile *exe_objfile = exe_module->GetObjectFile(); - if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && - exe_objfile->GetStrata() == ObjectFile::eStrataKernel) - return true; - } - break; - - default: - break; - } +bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) { + if (plugin_specified_by_name) + return true; + + // For now we are just making sure the file exists for a given module + Module *exe_module = target_sp->GetExecutableModulePointer(); + if (exe_module) { + const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple(); + switch (triple_ref.getOS()) { + case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for + // iOS, but accept darwin just in case + case llvm::Triple::MacOSX: // For desktop targets + case llvm::Triple::IOS: // For arm targets + case llvm::Triple::TvOS: + case llvm::Triple::WatchOS: + if (triple_ref.getVendor() == llvm::Triple::Apple) { + ObjectFile *exe_objfile = exe_module->GetObjectFile(); + if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && + exe_objfile->GetStrata() == ObjectFile::eStrataKernel) + return true; + } + break; + + default: + break; } - return false; + } + return false; } //---------------------------------------------------------------------- // ProcessKDP constructor //---------------------------------------------------------------------- -ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp) : - Process (target_sp, listener_sp), - m_comm("lldb.process.kdp-remote.communication"), - m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"), - m_dyld_plugin_name (), - m_kernel_load_addr (LLDB_INVALID_ADDRESS), - m_command_sp(), - m_kernel_thread_wp() -{ - m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); - m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); - const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout(); - if (timeout_seconds > 0) - m_comm.SetPacketTimeout(timeout_seconds); +ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp) + : Process(target_sp, listener_sp), + m_comm("lldb.process.kdp-remote.communication"), + m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"), + m_dyld_plugin_name(), m_kernel_load_addr(LLDB_INVALID_ADDRESS), + m_command_sp(), m_kernel_thread_wp() { + m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, + "async thread should exit"); + m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, + "async thread continue"); + const uint64_t timeout_seconds = + GetGlobalPluginProperties()->GetPacketTimeout(); + if (timeout_seconds > 0) + m_comm.SetPacketTimeout(timeout_seconds); } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -ProcessKDP::~ProcessKDP() -{ - Clear(); - // We need to call finalize on the process before destroying ourselves - // to make sure all of the broadcaster cleanup goes as planned. If we - // destruct this class, then Process::~Process() might have problems - // trying to fully destroy the broadcaster. - Finalize(); +ProcessKDP::~ProcessKDP() { + Clear(); + // We need to call finalize on the process before destroying ourselves + // to make sure all of the broadcaster cleanup goes as planned. If we + // destruct this class, then Process::~Process() might have problems + // trying to fully destroy the broadcaster. + Finalize(); } //---------------------------------------------------------------------- // PluginInterface //---------------------------------------------------------------------- -lldb_private::ConstString -ProcessKDP::GetPluginName() -{ - return GetPluginNameStatic(); +lldb_private::ConstString ProcessKDP::GetPluginName() { + return GetPluginNameStatic(); } -uint32_t -ProcessKDP::GetPluginVersion() -{ - return 1; -} +uint32_t ProcessKDP::GetPluginVersion() { return 1; } -Error -ProcessKDP::WillLaunch (Module* module) -{ - Error error; - error.SetErrorString ("launching not supported in kdp-remote plug-in"); - return error; +Error ProcessKDP::WillLaunch(Module *module) { + Error error; + error.SetErrorString("launching not supported in kdp-remote plug-in"); + return error; } -Error -ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid) -{ - Error error; - error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in"); - return error; +Error ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) { + Error error; + error.SetErrorString( + "attaching to a by process ID not supported in kdp-remote plug-in"); + return error; } -Error -ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) -{ - Error error; - error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in"); - return error; +Error ProcessKDP::WillAttachToProcessWithName(const char *process_name, + bool wait_for_launch) { + Error error; + error.SetErrorString( + "attaching to a by process name not supported in kdp-remote plug-in"); + return error; } -bool -ProcessKDP::GetHostArchitecture(ArchSpec &arch) -{ - uint32_t cpu = m_comm.GetCPUType(); - if (cpu) - { - uint32_t sub = m_comm.GetCPUSubtype(); - arch.SetArchitecture(eArchTypeMachO, cpu, sub); - // Leave architecture vendor as unspecified unknown - arch.GetTriple().setVendor(llvm::Triple::UnknownVendor); - arch.GetTriple().setVendorName(llvm::StringRef()); - return true; - } - arch.Clear(); - return false; +bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) { + uint32_t cpu = m_comm.GetCPUType(); + if (cpu) { + uint32_t sub = m_comm.GetCPUSubtype(); + arch.SetArchitecture(eArchTypeMachO, cpu, sub); + // Leave architecture vendor as unspecified unknown + arch.GetTriple().setVendor(llvm::Triple::UnknownVendor); + arch.GetTriple().setVendorName(llvm::StringRef()); + return true; + } + arch.Clear(); + return false; } -Error -ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url) -{ - Error error; - - // Don't let any JIT happen when doing KDP as we can't allocate - // memory and we don't want to be mucking with threads that might - // already be handling exceptions - SetCanJIT(false); +Error ProcessKDP::DoConnectRemote(Stream *strm, const char *remote_url) { + Error error; - if (remote_url == NULL || remote_url[0] == '\0') - { - error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url); - return error; - } + // Don't let any JIT happen when doing KDP as we can't allocate + // memory and we don't want to be mucking with threads that might + // already be handling exceptions + SetCanJIT(false); - std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); - if (conn_ap.get()) - { - // Only try once for now. - // TODO: check if we should be retrying? - const uint32_t max_retry_count = 1; - for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count) - { - if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess) - break; - usleep (100000); - } + if (remote_url == NULL || remote_url[0] == '\0') { + error.SetErrorStringWithFormat("invalid connection URL '%s'", remote_url); + return error; + } + + std::unique_ptr<ConnectionFileDescriptor> conn_ap( + new ConnectionFileDescriptor()); + if (conn_ap.get()) { + // Only try once for now. + // TODO: check if we should be retrying? + const uint32_t max_retry_count = 1; + for (uint32_t retry_count = 0; retry_count < max_retry_count; + ++retry_count) { + if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess) + break; + usleep(100000); } - - if (conn_ap->IsConnected()) - { - const TCPSocket& socket = static_cast<const TCPSocket&>(*conn_ap->GetReadObject()); - const uint16_t reply_port = socket.GetLocalPortNumber(); - - if (reply_port != 0) - { - m_comm.SetConnection(conn_ap.release()); - - if (m_comm.SendRequestReattach(reply_port)) - { - if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB...")) - { - m_comm.GetVersion(); - - Target &target = GetTarget(); - ArchSpec kernel_arch; - // The host architecture - GetHostArchitecture(kernel_arch); - ArchSpec target_arch = target.GetArchitecture(); - // Merge in any unspecified stuff into the target architecture in - // case the target arch isn't set at all or incompletely. - target_arch.MergeFrom(kernel_arch); - target.SetArchitecture(target_arch); - - /* Get the kernel's UUID and load address via KDP_KERNELVERSION packet. */ - /* An EFI kdp session has neither UUID nor load address. */ - - UUID kernel_uuid = m_comm.GetUUID (); - addr_t kernel_load_addr = m_comm.GetLoadAddress (); - - if (m_comm.RemoteIsEFI ()) - { - // Select an invalid plugin name for the dynamic loader so one doesn't get used - // since EFI does its own manual loading via python scripting - static ConstString g_none_dynamic_loader("none"); - m_dyld_plugin_name = g_none_dynamic_loader; - - if (kernel_uuid.IsValid()) { - // If EFI passed in a UUID= try to lookup UUID - // The slide will not be provided. But the UUID - // lookup will be used to launch EFI debug scripts - // from the dSYM, that can load all of the symbols. - ModuleSpec module_spec; - module_spec.GetUUID() = kernel_uuid; - module_spec.GetArchitecture() = target.GetArchitecture(); - - // Lookup UUID locally, before attempting dsymForUUID like action - module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec); - if (module_spec.GetSymbolFileSpec()) - { - ModuleSpec executable_module_spec = Symbols::LocateExecutableObjectFile (module_spec); - if (executable_module_spec.GetFileSpec().Exists()) - { - module_spec.GetFileSpec() = executable_module_spec.GetFileSpec(); - } - } - if (!module_spec.GetSymbolFileSpec() || !module_spec.GetSymbolFileSpec()) - Symbols::DownloadObjectAndSymbolFile (module_spec, true); - - if (module_spec.GetFileSpec().Exists()) - { - ModuleSP module_sp(new Module (module_spec)); - if (module_sp.get() && module_sp->GetObjectFile()) - { - // Get the current target executable - ModuleSP exe_module_sp (target.GetExecutableModule ()); - - // Make sure you don't already have the right module loaded and they will be uniqued - if (exe_module_sp.get() != module_sp.get()) - target.SetExecutableModule (module_sp, false); - } - } - } - } - else if (m_comm.RemoteIsDarwinKernel ()) - { - m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); - if (kernel_load_addr != LLDB_INVALID_ADDRESS) - { - m_kernel_load_addr = kernel_load_addr; - } - } - - // Set the thread ID - UpdateThreadListIfNeeded (); - SetID (1); - GetThreadList (); - SetPrivateState (eStateStopped); - StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream()); - if (async_strm_sp) - { - const char *cstr; - if ((cstr = m_comm.GetKernelVersion ()) != NULL) - { - async_strm_sp->Printf ("Version: %s\n", cstr); - async_strm_sp->Flush(); - } -// if ((cstr = m_comm.GetImagePath ()) != NULL) -// { -// async_strm_sp->Printf ("Image Path: %s\n", cstr); -// async_strm_sp->Flush(); -// } - } + } + + if (conn_ap->IsConnected()) { + const TCPSocket &socket = + static_cast<const TCPSocket &>(*conn_ap->GetReadObject()); + const uint16_t reply_port = socket.GetLocalPortNumber(); + + if (reply_port != 0) { + m_comm.SetConnection(conn_ap.release()); + + if (m_comm.SendRequestReattach(reply_port)) { + if (m_comm.SendRequestConnect(reply_port, reply_port, + "Greetings from LLDB...")) { + m_comm.GetVersion(); + + Target &target = GetTarget(); + ArchSpec kernel_arch; + // The host architecture + GetHostArchitecture(kernel_arch); + ArchSpec target_arch = target.GetArchitecture(); + // Merge in any unspecified stuff into the target architecture in + // case the target arch isn't set at all or incompletely. + target_arch.MergeFrom(kernel_arch); + target.SetArchitecture(target_arch); + + /* Get the kernel's UUID and load address via KDP_KERNELVERSION + * packet. */ + /* An EFI kdp session has neither UUID nor load address. */ + + UUID kernel_uuid = m_comm.GetUUID(); + addr_t kernel_load_addr = m_comm.GetLoadAddress(); + + if (m_comm.RemoteIsEFI()) { + // Select an invalid plugin name for the dynamic loader so one + // doesn't get used + // since EFI does its own manual loading via python scripting + static ConstString g_none_dynamic_loader("none"); + m_dyld_plugin_name = g_none_dynamic_loader; + + if (kernel_uuid.IsValid()) { + // If EFI passed in a UUID= try to lookup UUID + // The slide will not be provided. But the UUID + // lookup will be used to launch EFI debug scripts + // from the dSYM, that can load all of the symbols. + ModuleSpec module_spec; + module_spec.GetUUID() = kernel_uuid; + module_spec.GetArchitecture() = target.GetArchitecture(); + + // Lookup UUID locally, before attempting dsymForUUID like action + module_spec.GetSymbolFileSpec() = + Symbols::LocateExecutableSymbolFile(module_spec); + if (module_spec.GetSymbolFileSpec()) { + ModuleSpec executable_module_spec = + Symbols::LocateExecutableObjectFile(module_spec); + if (executable_module_spec.GetFileSpec().Exists()) { + module_spec.GetFileSpec() = + executable_module_spec.GetFileSpec(); } - else - { - error.SetErrorString("KDP_REATTACH failed"); + } + if (!module_spec.GetSymbolFileSpec() || + !module_spec.GetSymbolFileSpec()) + Symbols::DownloadObjectAndSymbolFile(module_spec, true); + + if (module_spec.GetFileSpec().Exists()) { + ModuleSP module_sp(new Module(module_spec)); + if (module_sp.get() && module_sp->GetObjectFile()) { + // Get the current target executable + ModuleSP exe_module_sp(target.GetExecutableModule()); + + // Make sure you don't already have the right module loaded + // and they will be uniqued + if (exe_module_sp.get() != module_sp.get()) + target.SetExecutableModule(module_sp, false); } + } } - else - { - error.SetErrorString("KDP_REATTACH failed"); + } else if (m_comm.RemoteIsDarwinKernel()) { + m_dyld_plugin_name = + DynamicLoaderDarwinKernel::GetPluginNameStatic(); + if (kernel_load_addr != LLDB_INVALID_ADDRESS) { + m_kernel_load_addr = kernel_load_addr; } + } + + // Set the thread ID + UpdateThreadListIfNeeded(); + SetID(1); + GetThreadList(); + SetPrivateState(eStateStopped); + StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream()); + if (async_strm_sp) { + const char *cstr; + if ((cstr = m_comm.GetKernelVersion()) != NULL) { + async_strm_sp->Printf("Version: %s\n", cstr); + async_strm_sp->Flush(); + } + // if ((cstr = m_comm.GetImagePath ()) != NULL) + // { + // async_strm_sp->Printf ("Image Path: + // %s\n", cstr); + // async_strm_sp->Flush(); + // } + } + } else { + error.SetErrorString("KDP_REATTACH failed"); } - else - { - error.SetErrorString("invalid reply port from UDP connection"); - } - } - else - { - if (error.Success()) - error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url); + } else { + error.SetErrorString("KDP_REATTACH failed"); + } + } else { + error.SetErrorString("invalid reply port from UDP connection"); } - if (error.Fail()) - m_comm.Disconnect(); - - return error; + } else { + if (error.Success()) + error.SetErrorStringWithFormat("failed to connect to '%s'", remote_url); + } + if (error.Fail()) + m_comm.Disconnect(); + + return error; } //---------------------------------------------------------------------- // Process Control //---------------------------------------------------------------------- -Error -ProcessKDP::DoLaunch (Module *exe_module, - ProcessLaunchInfo &launch_info) -{ - Error error; - error.SetErrorString ("launching not supported in kdp-remote plug-in"); - return error; +Error ProcessKDP::DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) { + Error error; + error.SetErrorString("launching not supported in kdp-remote plug-in"); + return error; } -Error -ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) -{ - Error error; - error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); - return error; +Error ProcessKDP::DoAttachToProcessWithID( + lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) { + Error error; + error.SetErrorString( + "attach to process by ID is not suppported in kdp remote debugging"); + return error; } -Error -ProcessKDP::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info) -{ - Error error; - error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging"); - return error; +Error ProcessKDP::DoAttachToProcessWithName( + const char *process_name, const ProcessAttachInfo &attach_info) { + Error error; + error.SetErrorString( + "attach to process by name is not suppported in kdp remote debugging"); + return error; } +void ProcessKDP::DidAttach(ArchSpec &process_arch) { + Process::DidAttach(process_arch); -void -ProcessKDP::DidAttach (ArchSpec &process_arch) -{ - Process::DidAttach(process_arch); - - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::DidAttach()"); - if (GetID() != LLDB_INVALID_PROCESS_ID) - { - GetHostArchitecture(process_arch); - } + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); + if (log) + log->Printf("ProcessKDP::DidAttach()"); + if (GetID() != LLDB_INVALID_PROCESS_ID) { + GetHostArchitecture(process_arch); + } } -addr_t -ProcessKDP::GetImageInfoAddress() -{ - return m_kernel_load_addr; -} +addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; } -lldb_private::DynamicLoader * -ProcessKDP::GetDynamicLoader () -{ - if (m_dyld_ap.get() == NULL) - m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString())); - return m_dyld_ap.get(); +lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() { + if (m_dyld_ap.get() == NULL) + m_dyld_ap.reset(DynamicLoader::FindPlugin( + this, + m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString())); + return m_dyld_ap.get(); } -Error -ProcessKDP::WillResume () -{ - return Error(); -} +Error ProcessKDP::WillResume() { return Error(); } -Error -ProcessKDP::DoResume () -{ - Error error; - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); - // Only start the async thread if we try to do any process control - if (!m_async_thread.IsJoinable()) - StartAsyncThread(); - - bool resume = false; - - // With KDP there is only one thread we can tell what to do - ThreadSP kernel_thread_sp (m_thread_list.FindThreadByProtocolID(g_kernel_tid)); - - if (kernel_thread_sp) - { - const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState(); - - if (log) - log->Printf ("ProcessKDP::DoResume() thread_resume_state = %s", StateAsCString(thread_resume_state)); - switch (thread_resume_state) - { - case eStateSuspended: - // Nothing to do here when a thread will stay suspended - // we just leave the CPU mask bit set to zero for the thread - if (log) - log->Printf ("ProcessKDP::DoResume() = suspended???"); - break; - - case eStateStepping: - { - lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext()); - - if (reg_ctx_sp) - { - if (log) - log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);"); - reg_ctx_sp->HardwareSingleStep (true); - resume = true; - } - else - { - error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID()); - } - } - break; - - case eStateRunning: - { - lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext()); - - if (reg_ctx_sp) - { - if (log) - log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (false);"); - reg_ctx_sp->HardwareSingleStep (false); - resume = true; - } - else - { - error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID()); - } - } - break; +Error ProcessKDP::DoResume() { + Error error; + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); + // Only start the async thread if we try to do any process control + if (!m_async_thread.IsJoinable()) + StartAsyncThread(); - default: - // The only valid thread resume states are listed above - assert (!"invalid thread resume state"); - break; - } - } + bool resume = false; + + // With KDP there is only one thread we can tell what to do + ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid)); + + if (kernel_thread_sp) { + const StateType thread_resume_state = + kernel_thread_sp->GetTemporaryResumeState(); - if (resume) - { + if (log) + log->Printf("ProcessKDP::DoResume() thread_resume_state = %s", + StateAsCString(thread_resume_state)); + switch (thread_resume_state) { + case eStateSuspended: + // Nothing to do here when a thread will stay suspended + // we just leave the CPU mask bit set to zero for the thread + if (log) + log->Printf("ProcessKDP::DoResume() = suspended???"); + break; + + case eStateStepping: { + lldb::RegisterContextSP reg_ctx_sp( + kernel_thread_sp->GetRegisterContext()); + + if (reg_ctx_sp) { if (log) - log->Printf ("ProcessKDP::DoResume () sending resume"); - - if (m_comm.SendRequestResume ()) - { - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue); - SetPrivateState(eStateRunning); - } - else - error.SetErrorString ("KDP resume failed"); - } - else - { - error.SetErrorString ("kernel thread is suspended"); + log->Printf( + "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);"); + reg_ctx_sp->HardwareSingleStep(true); + resume = true; + } else { + error.SetErrorStringWithFormat( + "KDP thread 0x%llx has no register context", + kernel_thread_sp->GetID()); + } + } break; + + case eStateRunning: { + lldb::RegisterContextSP reg_ctx_sp( + kernel_thread_sp->GetRegisterContext()); + + if (reg_ctx_sp) { + if (log) + log->Printf("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep " + "(false);"); + reg_ctx_sp->HardwareSingleStep(false); + resume = true; + } else { + error.SetErrorStringWithFormat( + "KDP thread 0x%llx has no register context", + kernel_thread_sp->GetID()); + } + } break; + + default: + // The only valid thread resume states are listed above + assert(!"invalid thread resume state"); + break; } - - return error; -} + } -lldb::ThreadSP -ProcessKDP::GetKernelThread() -{ - // KDP only tells us about one thread/core. Any other threads will usually - // be the ones that are read from memory by the OS plug-ins. - - ThreadSP thread_sp (m_kernel_thread_wp.lock()); - if (!thread_sp) - { - thread_sp.reset(new ThreadKDP (*this, g_kernel_tid)); - m_kernel_thread_wp = thread_sp; - } - return thread_sp; + if (resume) { + if (log) + log->Printf("ProcessKDP::DoResume () sending resume"); + + if (m_comm.SendRequestResume()) { + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + SetPrivateState(eStateRunning); + } else + error.SetErrorString("KDP resume failed"); + } else { + error.SetErrorString("kernel thread is suspended"); + } + + return error; } +lldb::ThreadSP ProcessKDP::GetKernelThread() { + // KDP only tells us about one thread/core. Any other threads will usually + // be the ones that are read from memory by the OS plug-ins. + ThreadSP thread_sp(m_kernel_thread_wp.lock()); + if (!thread_sp) { + thread_sp.reset(new ThreadKDP(*this, g_kernel_tid)); + m_kernel_thread_wp = thread_sp; + } + return thread_sp; +} - -bool -ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - // locker will keep a mutex locked until it goes out of scope - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD)); - if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) - log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); - - // Even though there is a CPU mask, it doesn't mean we can see each CPU - // individually, there is really only one. Lets call this thread 1. - ThreadSP thread_sp (old_thread_list.FindThreadByProtocolID(g_kernel_tid, false)); - if (!thread_sp) - thread_sp = GetKernelThread (); - new_thread_list.AddThread(thread_sp); - - return new_thread_list.GetSize(false) > 0; +bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) { + // locker will keep a mutex locked until it goes out of scope + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD)); + if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) + log->Printf("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); + + // Even though there is a CPU mask, it doesn't mean we can see each CPU + // individually, there is really only one. Lets call this thread 1. + ThreadSP thread_sp( + old_thread_list.FindThreadByProtocolID(g_kernel_tid, false)); + if (!thread_sp) + thread_sp = GetKernelThread(); + new_thread_list.AddThread(thread_sp); + + return new_thread_list.GetSize(false) > 0; } -void -ProcessKDP::RefreshStateAfterStop () -{ - // Let all threads recover from stopping and do any clean up based - // on the previous thread state (if any). - m_thread_list.RefreshStateAfterStop(); +void ProcessKDP::RefreshStateAfterStop() { + // Let all threads recover from stopping and do any clean up based + // on the previous thread state (if any). + m_thread_list.RefreshStateAfterStop(); } -Error -ProcessKDP::DoHalt (bool &caused_stop) -{ - Error error; - - if (m_comm.IsRunning()) - { - if (m_destroy_in_process) - { - // If we are attemping to destroy, we need to not return an error to - // Halt or DoDestroy won't get called. - // We are also currently running, so send a process stopped event - SetPrivateState (eStateStopped); - } - else - { - error.SetErrorString ("KDP cannot interrupt a running kernel"); - } +Error ProcessKDP::DoHalt(bool &caused_stop) { + Error error; + + if (m_comm.IsRunning()) { + if (m_destroy_in_process) { + // If we are attemping to destroy, we need to not return an error to + // Halt or DoDestroy won't get called. + // We are also currently running, so send a process stopped event + SetPrivateState(eStateStopped); + } else { + error.SetErrorString("KDP cannot interrupt a running kernel"); } - return error; + } + return error; } -Error -ProcessKDP::DoDetach(bool keep_stopped) -{ - Error error; - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped); - - if (m_comm.IsRunning()) - { - // We are running and we can't interrupt a running kernel, so we need - // to just close the connection to the kernel and hope for the best - } - else - { - // If we are going to keep the target stopped, then don't send the disconnect message. - if (!keep_stopped && m_comm.IsConnected()) - { - const bool success = m_comm.SendRequestDisconnect(); - if (log) - { - if (success) - log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully"); - else - log->PutCString ("ProcessKDP::DoDetach() connection channel shutdown failed"); - } - m_comm.Disconnect (); - } +Error ProcessKDP::DoDetach(bool keep_stopped) { + Error error; + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); + if (log) + log->Printf("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped); + + if (m_comm.IsRunning()) { + // We are running and we can't interrupt a running kernel, so we need + // to just close the connection to the kernel and hope for the best + } else { + // If we are going to keep the target stopped, then don't send the + // disconnect message. + if (!keep_stopped && m_comm.IsConnected()) { + const bool success = m_comm.SendRequestDisconnect(); + if (log) { + if (success) + log->PutCString( + "ProcessKDP::DoDetach() detach packet sent successfully"); + else + log->PutCString( + "ProcessKDP::DoDetach() connection channel shutdown failed"); + } + m_comm.Disconnect(); } - StopAsyncThread (); - m_comm.Clear(); - - SetPrivateState (eStateDetached); - ResumePrivateStateThread(); - - //KillDebugserverProcess (); - return error; + } + StopAsyncThread(); + m_comm.Clear(); + + SetPrivateState(eStateDetached); + ResumePrivateStateThread(); + + // KillDebugserverProcess (); + return error; } -Error -ProcessKDP::DoDestroy () -{ - // For KDP there really is no difference between destroy and detach - bool keep_stopped = false; - return DoDetach(keep_stopped); +Error ProcessKDP::DoDestroy() { + // For KDP there really is no difference between destroy and detach + bool keep_stopped = false; + return DoDetach(keep_stopped); } //------------------------------------------------------------------ // Process Queries //------------------------------------------------------------------ -bool -ProcessKDP::IsAlive () -{ - return m_comm.IsConnected() && Process::IsAlive(); +bool ProcessKDP::IsAlive() { + return m_comm.IsConnected() && Process::IsAlive(); } //------------------------------------------------------------------ // Process Memory //------------------------------------------------------------------ -size_t -ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error) -{ - uint8_t *data_buffer = (uint8_t *) buf; - if (m_comm.IsConnected()) - { - const size_t max_read_size = 512; - size_t total_bytes_read = 0; - - // Read the requested amount of memory in 512 byte chunks - while (total_bytes_read < size) - { - size_t bytes_to_read_this_request = size - total_bytes_read; - if (bytes_to_read_this_request > max_read_size) - { - bytes_to_read_this_request = max_read_size; - } - size_t bytes_read = m_comm.SendRequestReadMemory (addr + total_bytes_read, - data_buffer + total_bytes_read, - bytes_to_read_this_request, error); - total_bytes_read += bytes_read; - if (error.Fail() || bytes_read == 0) - { - return total_bytes_read; - } - } - +size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size, + Error &error) { + uint8_t *data_buffer = (uint8_t *)buf; + if (m_comm.IsConnected()) { + const size_t max_read_size = 512; + size_t total_bytes_read = 0; + + // Read the requested amount of memory in 512 byte chunks + while (total_bytes_read < size) { + size_t bytes_to_read_this_request = size - total_bytes_read; + if (bytes_to_read_this_request > max_read_size) { + bytes_to_read_this_request = max_read_size; + } + size_t bytes_read = m_comm.SendRequestReadMemory( + addr + total_bytes_read, data_buffer + total_bytes_read, + bytes_to_read_this_request, error); + total_bytes_read += bytes_read; + if (error.Fail() || bytes_read == 0) { return total_bytes_read; + } } - error.SetErrorString ("not connected"); - return 0; -} -size_t -ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error) -{ - if (m_comm.IsConnected()) - return m_comm.SendRequestWriteMemory (addr, buf, size, error); - error.SetErrorString ("not connected"); - return 0; + return total_bytes_read; + } + error.SetErrorString("not connected"); + return 0; } -lldb::addr_t -ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) -{ - error.SetErrorString ("memory allocation not suppported in kdp remote debugging"); - return LLDB_INVALID_ADDRESS; +size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size, + Error &error) { + if (m_comm.IsConnected()) + return m_comm.SendRequestWriteMemory(addr, buf, size, error); + error.SetErrorString("not connected"); + return 0; } -Error -ProcessKDP::DoDeallocateMemory (lldb::addr_t addr) -{ - Error error; - error.SetErrorString ("memory deallocation not suppported in kdp remote debugging"); - return error; +lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions, + Error &error) { + error.SetErrorString( + "memory allocation not suppported in kdp remote debugging"); + return LLDB_INVALID_ADDRESS; } -Error -ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site) -{ - if (m_comm.LocalBreakpointsAreSupported ()) - { - Error error; - if (!bp_site->IsEnabled()) - { - if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) - { - bp_site->SetEnabled(true); - bp_site->SetType (BreakpointSite::eExternal); - } - else - { - error.SetErrorString ("KDP set breakpoint failed"); - } - } - return error; - } - return EnableSoftwareBreakpoint (bp_site); +Error ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) { + Error error; + error.SetErrorString( + "memory deallocation not suppported in kdp remote debugging"); + return error; } -Error -ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site) -{ - if (m_comm.LocalBreakpointsAreSupported ()) - { - Error error; - if (bp_site->IsEnabled()) - { - BreakpointSite::Type bp_type = bp_site->GetType(); - if (bp_type == BreakpointSite::eExternal) - { - if (m_destroy_in_process && m_comm.IsRunning()) - { - // We are trying to destroy our connection and we are running - bp_site->SetEnabled(false); - } - else - { - if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress())) - bp_site->SetEnabled(false); - else - error.SetErrorString ("KDP remove breakpoint failed"); - } - } - else - { - error = DisableSoftwareBreakpoint (bp_site); - } - } - return error; +Error ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) { + if (m_comm.LocalBreakpointsAreSupported()) { + Error error; + if (!bp_site->IsEnabled()) { + if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) { + bp_site->SetEnabled(true); + bp_site->SetType(BreakpointSite::eExternal); + } else { + error.SetErrorString("KDP set breakpoint failed"); + } } - return DisableSoftwareBreakpoint (bp_site); + return error; + } + return EnableSoftwareBreakpoint(bp_site); } -Error -ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify) -{ +Error ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) { + if (m_comm.LocalBreakpointsAreSupported()) { Error error; - error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); + if (bp_site->IsEnabled()) { + BreakpointSite::Type bp_type = bp_site->GetType(); + if (bp_type == BreakpointSite::eExternal) { + if (m_destroy_in_process && m_comm.IsRunning()) { + // We are trying to destroy our connection and we are running + bp_site->SetEnabled(false); + } else { + if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress())) + bp_site->SetEnabled(false); + else + error.SetErrorString("KDP remove breakpoint failed"); + } + } else { + error = DisableSoftwareBreakpoint(bp_site); + } + } return error; + } + return DisableSoftwareBreakpoint(bp_site); } -Error -ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify) -{ - Error error; - error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); - return error; +Error ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) { + Error error; + error.SetErrorString( + "watchpoints are not suppported in kdp remote debugging"); + return error; } -void -ProcessKDP::Clear() -{ - m_thread_list.Clear(); +Error ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) { + Error error; + error.SetErrorString( + "watchpoints are not suppported in kdp remote debugging"); + return error; } -Error -ProcessKDP::DoSignal (int signo) -{ - Error error; - error.SetErrorString ("sending signals is not suppported in kdp remote debugging"); - return error; +void ProcessKDP::Clear() { m_thread_list.Clear(); } + +Error ProcessKDP::DoSignal(int signo) { + Error error; + error.SetErrorString( + "sending signals is not suppported in kdp remote debugging"); + return error; } -void -ProcessKDP::Initialize() -{ - static std::once_flag g_once_flag; - - std::call_once(g_once_flag, []() - { - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance, - DebuggerInitialize); - - Log::Callbacks log_callbacks = { - ProcessKDPLog::DisableLog, - ProcessKDPLog::EnableLog, - ProcessKDPLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks); - }); +void ProcessKDP::Initialize() { + static std::once_flag g_once_flag; + + std::call_once(g_once_flag, []() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); + + Log::Callbacks log_callbacks = {ProcessKDPLog::DisableLog, + ProcessKDPLog::EnableLog, + ProcessKDPLog::ListLogCategories}; + + Log::RegisterLogChannel(ProcessKDP::GetPluginNameStatic(), log_callbacks); + }); } -void -ProcessKDP::DebuggerInitialize (lldb_private::Debugger &debugger) -{ - if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName())) - { - const bool is_global_setting = true; - PluginManager::CreateSettingForProcessPlugin (debugger, - GetGlobalPluginProperties()->GetValueProperties(), - ConstString ("Properties for the kdp-remote process plug-in."), - is_global_setting); - } +void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) { + if (!PluginManager::GetSettingForProcessPlugin( + debugger, PluginProperties::GetSettingName())) { + const bool is_global_setting = true; + PluginManager::CreateSettingForProcessPlugin( + debugger, GetGlobalPluginProperties()->GetValueProperties(), + ConstString("Properties for the kdp-remote process plug-in."), + is_global_setting); + } } -bool -ProcessKDP::StartAsyncThread () -{ - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessKDP::StartAsyncThread ()"); +bool ProcessKDP::StartAsyncThread() { + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - if (m_async_thread.IsJoinable()) - return true; + if (log) + log->Printf("ProcessKDP::StartAsyncThread ()"); - m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL); - return m_async_thread.IsJoinable(); -} + if (m_async_thread.IsJoinable()) + return true; -void -ProcessKDP::StopAsyncThread () -{ - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessKDP::StopAsyncThread ()"); - - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); - - // Stop the stdio thread - if (m_async_thread.IsJoinable()) - m_async_thread.Join(nullptr); + m_async_thread = ThreadLauncher::LaunchThread( + "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL); + return m_async_thread.IsJoinable(); } +void ProcessKDP::StopAsyncThread() { + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); -void * -ProcessKDP::AsyncThread (void *arg) -{ - ProcessKDP *process = (ProcessKDP*) arg; - - const lldb::pid_t pid = process->GetID(); + if (log) + log->Printf("ProcessKDP::StopAsyncThread ()"); - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid); - - ListenerSP listener_sp (Listener::MakeListener("ProcessKDP::AsyncThread")); - EventSP event_sp; - const uint32_t desired_event_mask = eBroadcastBitAsyncContinue | - eBroadcastBitAsyncThreadShouldExit; - - - if (listener_sp->StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) - { - bool done = false; - while (!done) - { - if (log) - log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", - pid); - if (listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp)) - { - uint32_t event_type = event_sp->GetType(); - if (log) - log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...", - pid, - event_type); - - // When we are running, poll for 1 second to try and get an exception - // to indicate the process has stopped. If we don't get one, check to - // make sure no one asked us to exit - bool is_running = false; - DataExtractor exc_reply_packet; - do - { - switch (event_type) - { - case eBroadcastBitAsyncContinue: - { - is_running = true; - if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC)) - { - ThreadSP thread_sp (process->GetKernelThread()); - if (thread_sp) - { - lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext()); - if (reg_ctx_sp) - reg_ctx_sp->InvalidateAllRegisters(); - static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet); - } - - // TODO: parse the stop reply packet - is_running = false; - process->SetPrivateState(eStateStopped); - } - else - { - // Check to see if we are supposed to exit. There is no way to - // interrupt a running kernel, so all we can do is wait for an - // exception or detach... - if (listener_sp->GetNextEvent(event_sp)) - { - // We got an event, go through the loop again - event_type = event_sp->GetType(); - } - } - } - break; - - case eBroadcastBitAsyncThreadShouldExit: - if (log) - log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", - pid); - done = true; - is_running = false; - break; - - default: - if (log) - log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x", - pid, - event_type); - done = true; - is_running = false; - break; - } - } while (is_running); - } - else - { - if (log) - log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", - pid); - done = true; + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit); + + // Stop the stdio thread + if (m_async_thread.IsJoinable()) + m_async_thread.Join(nullptr); +} + +void *ProcessKDP::AsyncThread(void *arg) { + ProcessKDP *process = (ProcessKDP *)arg; + + const lldb::pid_t pid = process->GetID(); + + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); + if (log) + log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 + ") thread starting...", + arg, pid); + + ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread")); + EventSP event_sp; + const uint32_t desired_event_mask = + eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit; + + if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster, + desired_event_mask) == + desired_event_mask) { + bool done = false; + while (!done) { + if (log) + log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64 + ") listener.WaitForEvent (NULL, event_sp)...", + pid); + if (listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp)) { + uint32_t event_type = event_sp->GetType(); + if (log) + log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64 + ") Got an event of type: %d...", + pid, event_type); + + // When we are running, poll for 1 second to try and get an exception + // to indicate the process has stopped. If we don't get one, check to + // make sure no one asked us to exit + bool is_running = false; + DataExtractor exc_reply_packet; + do { + switch (event_type) { + case eBroadcastBitAsyncContinue: { + is_running = true; + if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds( + exc_reply_packet, 1 * USEC_PER_SEC)) { + ThreadSP thread_sp(process->GetKernelThread()); + if (thread_sp) { + lldb::RegisterContextSP reg_ctx_sp( + thread_sp->GetRegisterContext()); + if (reg_ctx_sp) + reg_ctx_sp->InvalidateAllRegisters(); + static_cast<ThreadKDP *>(thread_sp.get()) + ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet); + } + + // TODO: parse the stop reply packet + is_running = false; + process->SetPrivateState(eStateStopped); + } else { + // Check to see if we are supposed to exit. There is no way to + // interrupt a running kernel, so all we can do is wait for an + // exception or detach... + if (listener_sp->GetNextEvent(event_sp)) { + // We got an event, go through the loop again + event_type = event_sp->GetType(); + } } - } + } break; + + case eBroadcastBitAsyncThreadShouldExit: + if (log) + log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64 + ") got eBroadcastBitAsyncThreadShouldExit...", + pid); + done = true; + is_running = false; + break; + + default: + if (log) + log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64 + ") got unknown event 0x%8.8x", + pid, event_type); + done = true; + is_running = false; + break; + } + } while (is_running); + } else { + if (log) + log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64 + ") listener.WaitForEvent (NULL, event_sp) => false", + pid); + done = true; + } } - - if (log) - log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...", - arg, - pid); + } - process->m_async_thread.Reset(); - return NULL; -} + if (log) + log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 + ") thread exiting...", + arg, pid); + process->m_async_thread.Reset(); + return NULL; +} -class CommandObjectProcessKDPPacketSend : public CommandObjectParsed -{ +class CommandObjectProcessKDPPacketSend : public CommandObjectParsed { private: - - OptionGroupOptions m_option_group; - OptionGroupUInt64 m_command_byte; - OptionGroupString m_packet_data; - - virtual Options * - GetOptions () - { - return &m_option_group; - } - + OptionGroupOptions m_option_group; + OptionGroupUInt64 m_command_byte; + OptionGroupString m_packet_data; + + virtual Options *GetOptions() { return &m_option_group; } public: - CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) : - CommandObjectParsed (interpreter, - "process plugin packet send", - "Send a custom packet through the KDP protocol by specifying the command byte and the packet payload data. A packet will be sent with a correct header and payload, and the raw result bytes will be displayed as a string value. ", - NULL), + CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "process plugin packet send", + "Send a custom packet through the KDP protocol by " + "specifying the command byte and the packet " + "payload data. A packet will be sent with a " + "correct header and payload, and the raw result " + "bytes will be displayed as a string value. ", + NULL), m_option_group(), - m_command_byte(LLDB_OPT_SET_1, true , "command", 'c', 0, eArgTypeNone, "Specify the command byte to use when sending the KDP request packet.", 0), - m_packet_data (LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, "Specify packet payload bytes as a hex ASCII string with no spaces or hex prefixes.", NULL) - { - m_option_group.Append (&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); - m_option_group.Append (&m_packet_data , LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); - m_option_group.Finalize(); - } - - ~CommandObjectProcessKDPPacketSend () - { - } - - bool - DoExecute (Args& command, CommandReturnObject &result) - { - const size_t argc = command.GetArgumentCount(); - if (argc == 0) - { - if (!m_command_byte.GetOptionValue().OptionWasSet()) - { - result.AppendError ("the --command option must be set to a valid command byte"); - result.SetStatus (eReturnStatusFailed); - } - else - { - const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0); - if (command_byte > 0 && command_byte <= UINT8_MAX) - { - ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr(); - if (process) - { - const StateType state = process->GetState(); - - if (StateIsStoppedState (state, true)) - { - std::vector<uint8_t> payload_bytes; - const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue(); - if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) - { - StringExtractor extractor(ascii_hex_bytes_cstr); - const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size(); - if (ascii_hex_bytes_cstr_len & 1) - { - result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr); - result.SetStatus (eReturnStatusFailed); - return false; - } - payload_bytes.resize(ascii_hex_bytes_cstr_len/2); - if (extractor.GetHexBytes(payload_bytes, '\xdd') != payload_bytes.size()) - { - result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - Error error; - DataExtractor reply; - process->GetCommunication().SendRawRequest (command_byte, - payload_bytes.empty() ? NULL : payload_bytes.data(), - payload_bytes.size(), - reply, - error); - - if (error.Success()) - { - // Copy the binary bytes into a hex ASCII string for the result - StreamString packet; - packet.PutBytesAsRawHex8(reply.GetDataStart(), - reply.GetByteSize(), - endian::InlHostByteOrder(), - endian::InlHostByteOrder()); - result.AppendMessage(packet.GetString().c_str()); - result.SetStatus (eReturnStatusSuccessFinishResult); - return true; - } - else - { - const char *error_cstr = error.AsCString(); - if (error_cstr && error_cstr[0]) - result.AppendError (error_cstr); - else - result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError()); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - else - { - result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state)); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - result.AppendError ("invalid process"); - result.SetStatus (eReturnStatusFailed); - } + m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone, + "Specify the command byte to use when sending the KDP " + "request packet.", + 0), + m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone, + "Specify packet payload bytes as a hex ASCII string with " + "no spaces or hex prefixes.", + NULL) { + m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); + } + + ~CommandObjectProcessKDPPacketSend() {} + + bool DoExecute(Args &command, CommandReturnObject &result) { + const size_t argc = command.GetArgumentCount(); + if (argc == 0) { + if (!m_command_byte.GetOptionValue().OptionWasSet()) { + result.AppendError( + "the --command option must be set to a valid command byte"); + result.SetStatus(eReturnStatusFailed); + } else { + const uint64_t command_byte = + m_command_byte.GetOptionValue().GetUInt64Value(0); + if (command_byte > 0 && command_byte <= UINT8_MAX) { + ProcessKDP *process = + (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr(); + if (process) { + const StateType state = process->GetState(); + + if (StateIsStoppedState(state, true)) { + std::vector<uint8_t> payload_bytes; + const char *ascii_hex_bytes_cstr = + m_packet_data.GetOptionValue().GetCurrentValue(); + if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) { + StringExtractor extractor(ascii_hex_bytes_cstr); + const size_t ascii_hex_bytes_cstr_len = + extractor.GetStringRef().size(); + if (ascii_hex_bytes_cstr_len & 1) { + result.AppendErrorWithFormat("payload data must contain an " + "even number of ASCII hex " + "characters: '%s'", + ascii_hex_bytes_cstr); + result.SetStatus(eReturnStatusFailed); + return false; } - else - { - result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte); - result.SetStatus (eReturnStatusFailed); + payload_bytes.resize(ascii_hex_bytes_cstr_len / 2); + if (extractor.GetHexBytes(payload_bytes, '\xdd') != + payload_bytes.size()) { + result.AppendErrorWithFormat("payload data must only contain " + "ASCII hex characters (no " + "spaces or hex prefixes): '%s'", + ascii_hex_bytes_cstr); + result.SetStatus(eReturnStatusFailed); + return false; } + } + Error error; + DataExtractor reply; + process->GetCommunication().SendRawRequest( + command_byte, + payload_bytes.empty() ? NULL : payload_bytes.data(), + payload_bytes.size(), reply, error); + + if (error.Success()) { + // Copy the binary bytes into a hex ASCII string for the result + StreamString packet; + packet.PutBytesAsRawHex8( + reply.GetDataStart(), reply.GetByteSize(), + endian::InlHostByteOrder(), endian::InlHostByteOrder()); + result.AppendMessage(packet.GetString().c_str()); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } else { + const char *error_cstr = error.AsCString(); + if (error_cstr && error_cstr[0]) + result.AppendError(error_cstr); + else + result.AppendErrorWithFormat("unknown error 0x%8.8x", + error.GetError()); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + result.AppendErrorWithFormat("process must be stopped in order " + "to send KDP packets, state is %s", + StateAsCString(state)); + result.SetStatus(eReturnStatusFailed); } + } else { + result.AppendError("invalid process"); + result.SetStatus(eReturnStatusFailed); + } + } else { + result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64 + ", valid values are 1 - 255", + command_byte); + result.SetStatus(eReturnStatusFailed); } - else - { - result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str()); - result.SetStatus (eReturnStatusFailed); - } - return false; + } + } else { + result.AppendErrorWithFormat("'%s' takes no arguments, only options.", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); } + return false; + } }; -class CommandObjectProcessKDPPacket : public CommandObjectMultiword -{ +class CommandObjectProcessKDPPacket : public CommandObjectMultiword { private: - public: - CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "process plugin packet", - "Commands that deal with KDP remote packets.", - NULL) - { - LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessKDPPacketSend (interpreter))); - } - - ~CommandObjectProcessKDPPacket () - { - } + CommandObjectProcessKDPPacket(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "process plugin packet", + "Commands that deal with KDP remote packets.", + NULL) { + LoadSubCommand( + "send", + CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter))); + } + + ~CommandObjectProcessKDPPacket() {} }; -class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword -{ +class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword { public: - CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessKDP process.", - "process plugin <subcommand> [<subcommand-options>]") - { - LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessKDPPacket (interpreter))); - } - - ~CommandObjectMultiwordProcessKDP () - { - } + CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "process plugin", + "Commands for operating on a ProcessKDP process.", + "process plugin <subcommand> [<subcommand-options>]") { + LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket( + interpreter))); + } + + ~CommandObjectMultiwordProcessKDP() {} }; -CommandObject * -ProcessKDP::GetPluginCommandObject() -{ - if (!m_command_sp) - m_command_sp.reset (new CommandObjectMultiwordProcessKDP (GetTarget().GetDebugger().GetCommandInterpreter())); - return m_command_sp.get(); +CommandObject *ProcessKDP::GetPluginCommandObject() { + if (!m_command_sp) + m_command_sp.reset(new CommandObjectMultiwordProcessKDP( + GetTarget().GetDebugger().GetCommandInterpreter())); + return m_command_sp.get(); } - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h index 49f63624251..c4b046990ea 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h @@ -32,243 +32,192 @@ class ThreadKDP; -class ProcessKDP : public lldb_private::Process -{ +class ProcessKDP : public lldb_private::Process { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - static lldb::ProcessSP - CreateInstance (lldb::TargetSP target_sp, - lldb::ListenerSP listener_sp, - const lldb_private::FileSpec *crash_file_path); - - static void - Initialize(); - - static void - DebuggerInitialize (lldb_private::Debugger &debugger); - - static void - Terminate(); - - static lldb_private::ConstString - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener); - - virtual - ~ProcessKDP(); - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - virtual bool - CanDebug (lldb::TargetSP target_sp, - bool plugin_specified_by_name); - - virtual lldb_private::CommandObject * - GetPluginCommandObject(); - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - virtual lldb_private::Error - WillLaunch (lldb_private::Module* module); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - lldb_private::ProcessLaunchInfo &launch_info); - - virtual lldb_private::Error - WillAttachToProcessWithID (lldb::pid_t pid); - - virtual lldb_private::Error - WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); - - virtual lldb_private::Error - DoConnectRemote (lldb_private::Stream *strm, const char *remote_url); - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info); - - virtual lldb_private::Error - DoAttachToProcessWithName (const char *process_name, const lldb_private::ProcessAttachInfo &attach_info); - - virtual void - DidAttach (lldb_private::ArchSpec &process_arch); - - lldb::addr_t - GetImageInfoAddress(); - - lldb_private::DynamicLoader * - GetDynamicLoader (); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual lldb_private::ConstString - GetPluginName(); - - virtual uint32_t - GetPluginVersion(); - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ - virtual lldb_private::Error - WillResume (); - - virtual lldb_private::Error - DoResume (); - - virtual lldb_private::Error - DoHalt (bool &caused_stop); - - virtual lldb_private::Error - DoDetach (bool keep_stopped); - - virtual lldb_private::Error - DoSignal (int signal); - - virtual lldb_private::Error - DoDestroy (); - - virtual void - RefreshStateAfterStop(); - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - virtual bool - IsAlive (); - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); - - virtual size_t - DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error); - - virtual lldb_private::Error - DoDeallocateMemory (lldb::addr_t ptr); - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableBreakpointSite (lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpointSite (lldb_private::BreakpointSite *bp_site); - - //---------------------------------------------------------------------- - // Process Watchpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true); - - virtual lldb_private::Error - DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true); - - CommunicationKDP & - GetCommunication() - { - return m_comm; - } + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + static lldb::ProcessSP + CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, + const lldb_private::FileSpec *crash_file_path); + + static void Initialize(); + + static void DebuggerInitialize(lldb_private::Debugger &debugger); + + static void Terminate(); + + static lldb_private::ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic(); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener); + + virtual ~ProcessKDP(); + + //------------------------------------------------------------------ + // Check if a given Process + //------------------------------------------------------------------ + virtual bool CanDebug(lldb::TargetSP target_sp, + bool plugin_specified_by_name); + + virtual lldb_private::CommandObject *GetPluginCommandObject(); + + //------------------------------------------------------------------ + // Creating a new process, or attaching to an existing one + //------------------------------------------------------------------ + virtual lldb_private::Error WillLaunch(lldb_private::Module *module); + + virtual lldb_private::Error + DoLaunch(lldb_private::Module *exe_module, + lldb_private::ProcessLaunchInfo &launch_info); + + virtual lldb_private::Error WillAttachToProcessWithID(lldb::pid_t pid); + + virtual lldb_private::Error + WillAttachToProcessWithName(const char *process_name, bool wait_for_launch); + + virtual lldb_private::Error DoConnectRemote(lldb_private::Stream *strm, + const char *remote_url); + + virtual lldb_private::Error + DoAttachToProcessWithID(lldb::pid_t pid, + const lldb_private::ProcessAttachInfo &attach_info); + + virtual lldb_private::Error + DoAttachToProcessWithName(const char *process_name, + const lldb_private::ProcessAttachInfo &attach_info); + + virtual void DidAttach(lldb_private::ArchSpec &process_arch); + + lldb::addr_t GetImageInfoAddress(); + + lldb_private::DynamicLoader *GetDynamicLoader(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual lldb_private::ConstString GetPluginName(); + + virtual uint32_t GetPluginVersion(); + + //------------------------------------------------------------------ + // Process Control + //------------------------------------------------------------------ + virtual lldb_private::Error WillResume(); + + virtual lldb_private::Error DoResume(); + + virtual lldb_private::Error DoHalt(bool &caused_stop); + + virtual lldb_private::Error DoDetach(bool keep_stopped); + + virtual lldb_private::Error DoSignal(int signal); + + virtual lldb_private::Error DoDestroy(); + + virtual void RefreshStateAfterStop(); + + //------------------------------------------------------------------ + // Process Queries + //------------------------------------------------------------------ + virtual bool IsAlive(); + + //------------------------------------------------------------------ + // Process Memory + //------------------------------------------------------------------ + virtual size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, + lldb_private::Error &error); + + virtual size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, + lldb_private::Error &error); + + virtual lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, + lldb_private::Error &error); + + virtual lldb_private::Error DoDeallocateMemory(lldb::addr_t ptr); + + //---------------------------------------------------------------------- + // Process Breakpoints + //---------------------------------------------------------------------- + virtual lldb_private::Error + EnableBreakpointSite(lldb_private::BreakpointSite *bp_site); + + virtual lldb_private::Error + DisableBreakpointSite(lldb_private::BreakpointSite *bp_site); + + //---------------------------------------------------------------------- + // Process Watchpoints + //---------------------------------------------------------------------- + virtual lldb_private::Error EnableWatchpoint(lldb_private::Watchpoint *wp, + bool notify = true); + + virtual lldb_private::Error DisableWatchpoint(lldb_private::Watchpoint *wp, + bool notify = true); + + CommunicationKDP &GetCommunication() { return m_comm; } protected: - friend class ThreadKDP; - friend class CommunicationKDP; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - bool - IsRunning ( lldb::StateType state ) - { - return state == lldb::eStateRunning || IsStepping(state); - } - - bool - IsStepping ( lldb::StateType state) - { - return state == lldb::eStateStepping; - } - - bool - CanResume ( lldb::StateType state) - { - return state == lldb::eStateStopped; - } - - bool - HasExited (lldb::StateType state) - { - return state == lldb::eStateExited; - } - - bool - GetHostArchitecture (lldb_private::ArchSpec &arch); - - bool - ProcessIDIsValid ( ) const; - - void - Clear ( ); - - virtual bool - UpdateThreadList (lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); - - enum - { - eBroadcastBitAsyncContinue = (1 << 0), - eBroadcastBitAsyncThreadShouldExit = (1 << 1) - }; - - lldb::ThreadSP - GetKernelThread (); - - //------------------------------------------------------------------ - /// Broadcaster event bits definitions. - //------------------------------------------------------------------ - CommunicationKDP m_comm; - lldb_private::Broadcaster m_async_broadcaster; - lldb_private::HostThread m_async_thread; - lldb_private::ConstString m_dyld_plugin_name; - lldb::addr_t m_kernel_load_addr; - lldb::CommandObjectSP m_command_sp; - lldb::ThreadWP m_kernel_thread_wp; - - - bool - StartAsyncThread (); - - void - StopAsyncThread (); - - static void * - AsyncThread (void *arg); - + friend class ThreadKDP; + friend class CommunicationKDP; + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + bool IsRunning(lldb::StateType state) { + return state == lldb::eStateRunning || IsStepping(state); + } + + bool IsStepping(lldb::StateType state) { + return state == lldb::eStateStepping; + } + + bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; } + + bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; } + + bool GetHostArchitecture(lldb_private::ArchSpec &arch); + + bool ProcessIDIsValid() const; + + void Clear(); + + virtual bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, + lldb_private::ThreadList &new_thread_list); + + enum { + eBroadcastBitAsyncContinue = (1 << 0), + eBroadcastBitAsyncThreadShouldExit = (1 << 1) + }; + + lldb::ThreadSP GetKernelThread(); + + //------------------------------------------------------------------ + /// Broadcaster event bits definitions. + //------------------------------------------------------------------ + CommunicationKDP m_comm; + lldb_private::Broadcaster m_async_broadcaster; + lldb_private::HostThread m_async_thread; + lldb_private::ConstString m_dyld_plugin_name; + lldb::addr_t m_kernel_load_addr; + lldb::CommandObjectSP m_command_sp; + lldb::ThreadWP m_kernel_thread_wp; + + bool StartAsyncThread(); + + void StopAsyncThread(); + + static void *AsyncThread(void *arg); + private: - //------------------------------------------------------------------ - // For ProcessKDP only - //------------------------------------------------------------------ - - DISALLOW_COPY_AND_ASSIGN (ProcessKDP); - + //------------------------------------------------------------------ + // For ProcessKDP only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN(ProcessKDP); }; -#endif // liblldb_ProcessKDP_h_ +#endif // liblldb_ProcessKDP_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp index 79cb62aa006..479f09aa898 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp @@ -9,178 +9,184 @@ #include "ProcessKDPLog.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/Args.h" #include "ProcessKDP.h" using namespace lldb; using namespace lldb_private; - // We want to avoid global constructors where code needs to be run so here we // control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_log_sp the first time this function is +// that will construct the static g_log_sp the first time this function is // called. static bool g_log_enabled = false; -static Log * g_log = NULL; -static Log * -GetLog () -{ - if (!g_log_enabled) - return NULL; - return g_log; +static Log *g_log = NULL; +static Log *GetLog() { + if (!g_log_enabled) + return NULL; + return g_log; } -Log * -ProcessKDPLog::GetLogIfAllCategoriesSet (uint32_t mask) -{ - Log *log(GetLog ()); - if (log && mask) - { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return NULL; - } - return log; +Log *ProcessKDPLog::GetLogIfAllCategoriesSet(uint32_t mask) { + Log *log(GetLog()); + if (log && mask) { + uint32_t log_mask = log->GetMask().Get(); + if ((log_mask & mask) != mask) + return NULL; + } + return log; } -void -ProcessKDPLog::DisableLog (const char **categories, Stream *feedback_strm) -{ - Log *log (GetLog ()); - if (log) - { - uint32_t flag_bits = 0; - - if (categories[0] != NULL) - { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~KDP_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~KDP_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~KDP_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~KDP_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~KDP_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~KDP_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~KDP_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~KDP_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~KDP_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~KDP_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~KDP_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~KDP_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories (feedback_strm); - } - - } +void ProcessKDPLog::DisableLog(const char **categories, Stream *feedback_strm) { + Log *log(GetLog()); + if (log) { + uint32_t flag_bits = 0; + + if (categories[0] != NULL) { + flag_bits = log->GetMask().Get(); + for (size_t i = 0; categories[i] != NULL; ++i) { + const char *arg = categories[i]; + + if (::strcasecmp(arg, "all") == 0) + flag_bits &= ~KDP_LOG_ALL; + else if (::strcasecmp(arg, "async") == 0) + flag_bits &= ~KDP_LOG_ASYNC; + else if (::strncasecmp(arg, "break", 5) == 0) + flag_bits &= ~KDP_LOG_BREAKPOINTS; + else if (::strncasecmp(arg, "comm", 4) == 0) + flag_bits &= ~KDP_LOG_COMM; + else if (::strcasecmp(arg, "default") == 0) + flag_bits &= ~KDP_LOG_DEFAULT; + else if (::strcasecmp(arg, "packets") == 0) + flag_bits &= ~KDP_LOG_PACKETS; + else if (::strcasecmp(arg, "memory") == 0) + flag_bits &= ~KDP_LOG_MEMORY; + else if (::strcasecmp(arg, "data-short") == 0) + flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT; + else if (::strcasecmp(arg, "data-long") == 0) + flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG; + else if (::strcasecmp(arg, "process") == 0) + flag_bits &= ~KDP_LOG_PROCESS; + else if (::strcasecmp(arg, "step") == 0) + flag_bits &= ~KDP_LOG_STEP; + else if (::strcasecmp(arg, "thread") == 0) + flag_bits &= ~KDP_LOG_THREAD; + else if (::strcasecmp(arg, "verbose") == 0) + flag_bits &= ~KDP_LOG_VERBOSE; + else if (::strncasecmp(arg, "watch", 5) == 0) + flag_bits &= ~KDP_LOG_WATCHPOINTS; + else { + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); + ListLogCategories(feedback_strm); } - - log->GetMask().Reset (flag_bits); - if (flag_bits == 0) - g_log_enabled = false; + } } - - return; -} -Log * -ProcessKDPLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - if (g_log) - flag_bits = g_log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - if (g_log) - g_log->SetStream(log_stream_sp); - else - g_log = new Log(log_stream_sp); - } + log->GetMask().Reset(flag_bits); + if (flag_bits == 0) + g_log_enabled = false; + } + return; +} + +Log *ProcessKDPLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, + const char **categories, Stream *feedback_strm) { + // Try see if there already is a log - that way we can reuse its settings. + // We could reuse the log in toto, but we don't know that the stream is the + // same. + uint32_t flag_bits = 0; + if (g_log) + flag_bits = g_log->GetMask().Get(); + + // Now make a new log with this stream if one was provided + if (log_stream_sp) { if (g_log) - { - bool got_unknown_category = false; - for (size_t i=0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= KDP_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= KDP_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= KDP_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= KDP_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= KDP_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= KDP_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= KDP_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= KDP_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= KDP_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= KDP_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= KDP_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= KDP_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } + g_log->SetStream(log_stream_sp); + else + g_log = new Log(log_stream_sp); + } + + if (g_log) { + bool got_unknown_category = false; + for (size_t i = 0; categories[i] != NULL; ++i) { + const char *arg = categories[i]; + + if (::strcasecmp(arg, "all") == 0) + flag_bits |= KDP_LOG_ALL; + else if (::strcasecmp(arg, "async") == 0) + flag_bits |= KDP_LOG_ASYNC; + else if (::strncasecmp(arg, "break", 5) == 0) + flag_bits |= KDP_LOG_BREAKPOINTS; + else if (::strncasecmp(arg, "comm", 4) == 0) + flag_bits |= KDP_LOG_COMM; + else if (::strcasecmp(arg, "default") == 0) + flag_bits |= KDP_LOG_DEFAULT; + else if (::strcasecmp(arg, "packets") == 0) + flag_bits |= KDP_LOG_PACKETS; + else if (::strcasecmp(arg, "memory") == 0) + flag_bits |= KDP_LOG_MEMORY; + else if (::strcasecmp(arg, "data-short") == 0) + flag_bits |= KDP_LOG_MEMORY_DATA_SHORT; + else if (::strcasecmp(arg, "data-long") == 0) + flag_bits |= KDP_LOG_MEMORY_DATA_LONG; + else if (::strcasecmp(arg, "process") == 0) + flag_bits |= KDP_LOG_PROCESS; + else if (::strcasecmp(arg, "step") == 0) + flag_bits |= KDP_LOG_STEP; + else if (::strcasecmp(arg, "thread") == 0) + flag_bits |= KDP_LOG_THREAD; + else if (::strcasecmp(arg, "verbose") == 0) + flag_bits |= KDP_LOG_VERBOSE; + else if (::strncasecmp(arg, "watch", 5) == 0) + flag_bits |= KDP_LOG_WATCHPOINTS; + else { + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); + if (got_unknown_category == false) { + got_unknown_category = true; + ListLogCategories(feedback_strm); } - if (flag_bits == 0) - flag_bits = KDP_LOG_DEFAULT; - g_log->GetMask().Reset(flag_bits); - g_log->GetOptions().Reset(log_options); + } } - g_log_enabled = true; - return g_log; + if (flag_bits == 0) + flag_bits = KDP_LOG_DEFAULT; + g_log->GetMask().Reset(flag_bits); + g_log->GetOptions().Reset(log_options); + } + g_log_enabled = true; + return g_log; } -void -ProcessKDPLog::ListLogCategories (Stream *strm) -{ - strm->Printf ("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short transactions only\n" - " data-long - log memory bytes for memory reads and writes for all transactions\n" - " process - log process events and activities\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", - ProcessKDP::GetPluginNameStatic().GetCString()); +void ProcessKDPLog::ListLogCategories(Stream *strm) { + strm->Printf( + "Logging categories for '%s':\n" + " all - turn on all available logging categories\n" + " async - log asynchronous activity\n" + " break - log breakpoints\n" + " communication - log communication activity\n" + " default - enable the default set of logging categories for liblldb\n" + " packets - log gdb remote packets\n" + " memory - log memory reads and writes\n" + " data-short - log memory bytes for memory reads and writes for short " + "transactions only\n" + " data-long - log memory bytes for memory reads and writes for all " + "transactions\n" + " process - log process events and activities\n" + " thread - log thread events and activities\n" + " step - log step related activities\n" + " verbose - enable verbose logging\n" + " watch - log watchpoint related activities\n", + ProcessKDP::GetPluginNameStatic().GetCString()); } - -void -ProcessKDPLog::LogIf (uint32_t mask, const char *format, ...) -{ - Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask)); - if (log) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } +void ProcessKDPLog::LogIf(uint32_t mask, const char *format, ...) { + Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(mask)); + if (log) { + va_list args; + va_start(args, format); + log->VAPrintf(format, args); + va_end(args); + } } diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h index 0cb32d9b2dc..703c775268d 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h @@ -17,38 +17,37 @@ // Project includes #include "lldb/Core/Log.h" -#define KDP_LOG_VERBOSE (1u << 0) -#define KDP_LOG_PROCESS (1u << 1) -#define KDP_LOG_THREAD (1u << 2) -#define KDP_LOG_PACKETS (1u << 3) -#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls -#define KDP_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes -#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes -#define KDP_LOG_BREAKPOINTS (1u << 7) -#define KDP_LOG_WATCHPOINTS (1u << 8) -#define KDP_LOG_STEP (1u << 9) -#define KDP_LOG_COMM (1u << 10) -#define KDP_LOG_ASYNC (1u << 11) -#define KDP_LOG_ALL (UINT32_MAX) -#define KDP_LOG_DEFAULT KDP_LOG_PACKETS - -class ProcessKDPLog -{ +#define KDP_LOG_VERBOSE (1u << 0) +#define KDP_LOG_PROCESS (1u << 1) +#define KDP_LOG_THREAD (1u << 2) +#define KDP_LOG_PACKETS (1u << 3) +#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls +#define KDP_LOG_MEMORY_DATA_SHORT \ + (1u << 5) // Log short memory reads/writes bytes +#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes +#define KDP_LOG_BREAKPOINTS (1u << 7) +#define KDP_LOG_WATCHPOINTS (1u << 8) +#define KDP_LOG_STEP (1u << 9) +#define KDP_LOG_COMM (1u << 10) +#define KDP_LOG_ASYNC (1u << 11) +#define KDP_LOG_ALL (UINT32_MAX) +#define KDP_LOG_DEFAULT KDP_LOG_PACKETS + +class ProcessKDPLog { public: - static lldb_private::Log * - GetLogIfAllCategoriesSet(uint32_t mask = 0); + static lldb_private::Log *GetLogIfAllCategoriesSet(uint32_t mask = 0); - static void - DisableLog (const char **categories, lldb_private::Stream *feedback_strm); + static void DisableLog(const char **categories, + lldb_private::Stream *feedback_strm); - static lldb_private::Log * - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm); + static lldb_private::Log *EnableLog(lldb::StreamSP &log_stream_sp, + uint32_t log_options, + const char **categories, + lldb_private::Stream *feedback_strm); - static void - ListLogCategories (lldb_private::Stream *strm); + static void ListLogCategories(lldb_private::Stream *strm); - static void - LogIf (uint32_t mask, const char *format, ...); + static void LogIf(uint32_t mask, const char *format, ...); }; -#endif // liblldb_ProcessKDPLog_h_ +#endif // liblldb_ProcessKDPLog_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp index 449ac646ab3..06c33dba857 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp @@ -19,143 +19,133 @@ using namespace lldb; using namespace lldb_private; - -RegisterContextKDP_arm::RegisterContextKDP_arm (ThreadKDP &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_arm (thread, concrete_frame_idx), - m_kdp_thread (thread) -{ -} - -RegisterContextKDP_arm::~RegisterContextKDP_arm() -{ -} - -int -RegisterContextKDP_arm::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; - } +RegisterContextKDP_arm::RegisterContextKDP_arm(ThreadKDP &thread, + uint32_t concrete_frame_idx) + : RegisterContextDarwin_arm(thread, concrete_frame_idx), + m_kdp_thread(thread) {} + +RegisterContextKDP_arm::~RegisterContextKDP_arm() {} + +int RegisterContextKDP_arm::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; + } + return -1; } -int -RegisterContextKDP_arm::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; - } +int RegisterContextKDP_arm::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; + } + return -1; } -int -RegisterContextKDP_arm::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; - } +int RegisterContextKDP_arm::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; + } + return -1; } -int -RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) -{ - ProcessSP process_sp (CalculateProcess()); - if (process_sp) - { - Error error; - if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error)) - { - if (error.Success()) - return 0; - } +int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + Error error; + if (static_cast<ProcessKDP *>(process_sp.get()) + ->GetCommunication() + .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg), + error)) { + if (error.Success()) + return 0; } - return -1; + } + return -1; } -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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + return -1; } - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h index 1e547289d9c..fe02b064822 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h @@ -19,43 +19,30 @@ class ThreadKDP; -class RegisterContextKDP_arm : public RegisterContextDarwin_arm -{ +class RegisterContextKDP_arm : public RegisterContextDarwin_arm { public: + RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx); - RegisterContextKDP_arm (ThreadKDP &thread, - uint32_t concrete_frame_idx); - - virtual - ~RegisterContextKDP_arm(); + virtual ~RegisterContextKDP_arm(); protected: + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr); + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu); + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc); + + int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg); + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr); + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu); + + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); + + int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg); - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); - - int - DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg); - - ThreadKDP &m_kdp_thread; + ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_arm_h_ +#endif // liblldb_RegisterContextKDP_arm_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp index ed62f1982d3..6a2733e6275 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp @@ -1,4 +1,5 @@ -//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ -*-===// +//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -19,143 +20,133 @@ using namespace lldb; using namespace lldb_private; - -RegisterContextKDP_arm64::RegisterContextKDP_arm64 (ThreadKDP &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_arm64 (thread, concrete_frame_idx), - m_kdp_thread (thread) -{ -} - -RegisterContextKDP_arm64::~RegisterContextKDP_arm64() -{ -} - -int -RegisterContextKDP_arm64::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; - } +RegisterContextKDP_arm64::RegisterContextKDP_arm64(ThreadKDP &thread, + uint32_t concrete_frame_idx) + : RegisterContextDarwin_arm64(thread, concrete_frame_idx), + m_kdp_thread(thread) {} + +RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {} + +int RegisterContextKDP_arm64::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; + } + return -1; } -int -RegisterContextKDP_arm64::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; - } +int RegisterContextKDP_arm64::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; + } + return -1; } -int -RegisterContextKDP_arm64::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; - } +int RegisterContextKDP_arm64::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; + } + return -1; } -int -RegisterContextKDP_arm64::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) -{ - ProcessSP process_sp (CalculateProcess()); - if (process_sp) - { - Error error; - if (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().SendRequestReadRegisters (tid, DBGRegSet, &dbg, sizeof(dbg), error)) - { - if (error.Success()) - return 0; - } +int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + Error error; + if (static_cast<ProcessKDP *>(process_sp.get()) + ->GetCommunication() + .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg), + error)) { + if (error.Success()) + return 0; } - return -1; + } + return -1; } -int -RegisterContextKDP_arm64::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; - } +int RegisterContextKDP_arm64::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; + } + return -1; } -int -RegisterContextKDP_arm64::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; - } +int RegisterContextKDP_arm64::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; + } + return -1; } -int -RegisterContextKDP_arm64::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; - } +int RegisterContextKDP_arm64::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; + } + return -1; } -int -RegisterContextKDP_arm64::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; - } +int RegisterContextKDP_arm64::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; + } + return -1; } - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h index 8780b7be4a9..0922654de2c 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h @@ -1,4 +1,5 @@ -//===-- RegisterContextKDP_arm64.h --------------------------------*- C++ -*-===// +//===-- RegisterContextKDP_arm64.h --------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -19,43 +20,30 @@ class ThreadKDP; -class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 -{ +class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 { public: + RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx); - RegisterContextKDP_arm64 (ThreadKDP &thread, - uint32_t concrete_frame_idx); - - virtual - ~RegisterContextKDP_arm64(); + virtual ~RegisterContextKDP_arm64(); protected: + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr); + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu); + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc); + + int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg); + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr); + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu); + + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); + + int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg); - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); - - int - DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg); - - ThreadKDP &m_kdp_thread; + ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_arm64_h_ +#endif // liblldb_RegisterContextKDP_arm64_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp index 882b0c2e931..4a130c18d07 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// - // C Includes // C++ Includes // Other libraries and framework includes @@ -19,111 +18,102 @@ using namespace lldb; using namespace lldb_private; +RegisterContextKDP_i386::RegisterContextKDP_i386(ThreadKDP &thread, + uint32_t concrete_frame_idx) + : RegisterContextDarwin_i386(thread, concrete_frame_idx), + m_kdp_thread(thread) {} -RegisterContextKDP_i386::RegisterContextKDP_i386 (ThreadKDP &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_i386 (thread, concrete_frame_idx), - m_kdp_thread (thread) -{ -} - -RegisterContextKDP_i386::~RegisterContextKDP_i386() -{ -} +RegisterContextKDP_i386::~RegisterContextKDP_i386() {} -int -RegisterContextKDP_i386::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; - } +int RegisterContextKDP_i386::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; + } + return -1; } -int -RegisterContextKDP_i386::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; - } +int RegisterContextKDP_i386::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; + } + return -1; } -int -RegisterContextKDP_i386::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; - } +int RegisterContextKDP_i386::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; + } + return -1; } -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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + return -1; } - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h index 4b6bc5b262f..5803670a08b 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h @@ -18,36 +18,26 @@ class ThreadKDP; -class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 -{ +class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 { public: - RegisterContextKDP_i386 (ThreadKDP &thread, - uint32_t concrete_frame_idx); - - virtual - ~RegisterContextKDP_i386(); - + RegisterContextKDP_i386(ThreadKDP &thread, uint32_t concrete_frame_idx); + + virtual ~RegisterContextKDP_i386(); + protected: - - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); - - ThreadKDP &m_kdp_thread; + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr); + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu); + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc); + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr); + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu); + + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); + + ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_i386_h_ +#endif // liblldb_RegisterContextKDP_i386_h_ 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 f4247a5da27..ad10d3f6be5 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// - // C Includes // C++ Includes // Other libraries and framework includes @@ -19,109 +18,105 @@ using namespace lldb; using namespace lldb_private; +RegisterContextKDP_x86_64::RegisterContextKDP_x86_64( + ThreadKDP &thread, uint32_t concrete_frame_idx) + : RegisterContextDarwin_x86_64(thread, concrete_frame_idx), + m_kdp_thread(thread) {} -RegisterContextKDP_x86_64::RegisterContextKDP_x86_64 (ThreadKDP &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_x86_64 (thread, concrete_frame_idx), - m_kdp_thread (thread) -{ -} - -RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() -{ -} +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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + 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; - } +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; + } + return -1; } diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h index a426349198f..7a40bb62638 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h @@ -18,37 +18,26 @@ class ThreadKDP; -class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 -{ +class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 { public: - - RegisterContextKDP_x86_64 (ThreadKDP &thread, - uint32_t concrete_frame_idx); - - virtual - ~RegisterContextKDP_x86_64(); - + RegisterContextKDP_x86_64(ThreadKDP &thread, uint32_t concrete_frame_idx); + + virtual ~RegisterContextKDP_x86_64(); + protected: - - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr); - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu); - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc); - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr); - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu); - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc); - - ThreadKDP &m_kdp_thread; + virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr); + + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu); + + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc); + + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr); + + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu); + + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc); + + ThreadKDP &m_kdp_thread; }; -#endif // liblldb_RegisterContextKDP_x86_64_h_ +#endif // liblldb_RegisterContextKDP_x86_64_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp index 3b8bed101a8..273e1966f3f 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp @@ -7,29 +7,28 @@ // //===----------------------------------------------------------------------===// - #include "ThreadKDP.h" #include "lldb/Utility/SafeMachO.h" +#include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataExtractor.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/State.h" +#include "lldb/Core/StreamString.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Unwind.h" -#include "lldb/Breakpoint/Watchpoint.h" +#include "Plugins/Process/Utility/StopInfoMachException.h" #include "ProcessKDP.h" #include "ProcessKDPLog.h" #include "RegisterContextKDP_arm.h" #include "RegisterContextKDP_arm64.h" #include "RegisterContextKDP_i386.h" #include "RegisterContextKDP_x86_64.h" -#include "Plugins/Process/Utility/StopInfoMachException.h" using namespace lldb; using namespace lldb_private; @@ -38,174 +37,137 @@ using namespace lldb_private; // Thread Registers //---------------------------------------------------------------------- -ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) : - Thread(process, tid), - m_thread_name (), - m_dispatch_queue_name (), - m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) -{ - ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID()); -} - -ThreadKDP::~ThreadKDP () -{ - ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID()); - DestroyThread(); +ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid) + : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(), + m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) { + ProcessKDPLog::LogIf(KDP_LOG_THREAD, + "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, + GetID()); } -const char * -ThreadKDP::GetName () -{ - if (m_thread_name.empty()) - return NULL; - return m_thread_name.c_str(); +ThreadKDP::~ThreadKDP() { + ProcessKDPLog::LogIf(KDP_LOG_THREAD, + "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, + GetID()); + DestroyThread(); } -const char * -ThreadKDP::GetQueueName () -{ +const char *ThreadKDP::GetName() { + if (m_thread_name.empty()) return NULL; + return m_thread_name.c_str(); } -void -ThreadKDP::RefreshStateAfterStop() -{ - // Invalidate all registers in our register context. We don't set "force" to - // true because the stop reply packet might have had some register values - // that were expedited and these will already be copied into the register - // context by the time this function gets called. The KDPRegisterContext - // class has been made smart enough to detect when it needs to invalidate - // which registers are valid by putting hooks in the register read and - // register supply functions where they check the process stop ID and do - // the right thing. - const bool force = false; - lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext()); - if (reg_ctx_sp) - reg_ctx_sp->InvalidateIfNeeded (force); +const char *ThreadKDP::GetQueueName() { return NULL; } + +void ThreadKDP::RefreshStateAfterStop() { + // Invalidate all registers in our register context. We don't set "force" to + // true because the stop reply packet might have had some register values + // that were expedited and these will already be copied into the register + // context by the time this function gets called. The KDPRegisterContext + // class has been made smart enough to detect when it needs to invalidate + // which registers are valid by putting hooks in the register read and + // register supply functions where they check the process stop ID and do + // the right thing. + const bool force = false; + lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext()); + if (reg_ctx_sp) + reg_ctx_sp->InvalidateIfNeeded(force); } -bool -ThreadKDP::ThreadIDIsValid (lldb::tid_t thread) -{ - return thread != 0; -} - -void -ThreadKDP::Dump(Log *log, uint32_t index) -{ -} +bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; } +void ThreadKDP::Dump(Log *log, uint32_t index) {} -bool -ThreadKDP::ShouldStop (bool &step_more) -{ - return true; -} -lldb::RegisterContextSP -ThreadKDP::GetRegisterContext () -{ - if (m_reg_context_sp.get() == NULL) - m_reg_context_sp = CreateRegisterContextForFrame (NULL); - return m_reg_context_sp; +bool ThreadKDP::ShouldStop(bool &step_more) { return true; } +lldb::RegisterContextSP ThreadKDP::GetRegisterContext() { + if (m_reg_context_sp.get() == NULL) + m_reg_context_sp = CreateRegisterContextForFrame(NULL); + return m_reg_context_sp; } lldb::RegisterContextSP -ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_frame_idx = 0; - - if (frame) - concrete_frame_idx = frame->GetConcreteFrameIndex (); - - if (concrete_frame_idx == 0) - { - ProcessSP process_sp (CalculateProcess()); - if (process_sp) - { - switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType()) - { - case llvm::MachO::CPU_TYPE_ARM: - reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx)); - break; - case llvm::MachO::CPU_TYPE_ARM64: - reg_ctx_sp.reset (new RegisterContextKDP_arm64 (*this, concrete_frame_idx)); - break; - case llvm::MachO::CPU_TYPE_I386: - reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx)); - break; - case llvm::MachO::CPU_TYPE_X86_64: - reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx)); - break; - default: - assert (!"Add CPU type support in KDP"); - break; - } - } - } - else - { - Unwind *unwinder = GetUnwinder (); - if (unwinder) - reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame); +ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) { + lldb::RegisterContextSP reg_ctx_sp; + uint32_t concrete_frame_idx = 0; + + if (frame) + concrete_frame_idx = frame->GetConcreteFrameIndex(); + + if (concrete_frame_idx == 0) { + ProcessSP process_sp(CalculateProcess()); + if (process_sp) { + switch (static_cast<ProcessKDP *>(process_sp.get()) + ->GetCommunication() + .GetCPUType()) { + case llvm::MachO::CPU_TYPE_ARM: + reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx)); + break; + case llvm::MachO::CPU_TYPE_ARM64: + reg_ctx_sp.reset( + new RegisterContextKDP_arm64(*this, concrete_frame_idx)); + break; + case llvm::MachO::CPU_TYPE_I386: + reg_ctx_sp.reset( + new RegisterContextKDP_i386(*this, concrete_frame_idx)); + break; + case llvm::MachO::CPU_TYPE_X86_64: + reg_ctx_sp.reset( + new RegisterContextKDP_x86_64(*this, concrete_frame_idx)); + break; + default: + assert(!"Add CPU type support in KDP"); + break; + } } - return reg_ctx_sp; + } else { + Unwind *unwinder = GetUnwinder(); + if (unwinder) + reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); + } + return reg_ctx_sp; } -bool -ThreadKDP::CalculateStopInfo () -{ - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - if (m_cached_stop_info_sp) - { - SetStopInfo (m_cached_stop_info_sp); - } - else - { - SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP)); - } - return true; +bool ThreadKDP::CalculateStopInfo() { + ProcessSP process_sp(GetProcess()); + if (process_sp) { + if (m_cached_stop_info_sp) { + SetStopInfo(m_cached_stop_info_sp); + } else { + SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP)); } - return false; + return true; + } + return false; } -void -ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet) -{ - lldb::offset_t offset = 0; - uint8_t reply_command = exc_reply_packet.GetU8(&offset); - if (reply_command == CommunicationKDP::KDP_EXCEPTION) - { - offset = 8; - const uint32_t count = exc_reply_packet.GetU32 (&offset); - if (count >= 1) - { - //const uint32_t cpu = exc_reply_packet.GetU32 (&offset); - offset += 4; // Skip the useless CPU field - const uint32_t exc_type = exc_reply_packet.GetU32 (&offset); - const uint32_t exc_code = exc_reply_packet.GetU32 (&offset); - const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset); - // We have to make a copy of the stop info because the thread list - // will iterate through the threads and clear all stop infos.. - - // Let the StopInfoMachException::CreateStopReasonWithMachException() - // function update the PC if needed as we might hit a software breakpoint - // and need to decrement the PC (i386 and x86_64 need this) and KDP - // doesn't do this for us. - const bool pc_already_adjusted = false; - const bool adjust_pc_if_needed = true; - - m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this, - exc_type, - 2, - exc_code, - exc_subcode, - 0, - pc_already_adjusted, - adjust_pc_if_needed); - } +void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION( + const DataExtractor &exc_reply_packet) { + lldb::offset_t offset = 0; + uint8_t reply_command = exc_reply_packet.GetU8(&offset); + if (reply_command == CommunicationKDP::KDP_EXCEPTION) { + offset = 8; + const uint32_t count = exc_reply_packet.GetU32(&offset); + if (count >= 1) { + // const uint32_t cpu = exc_reply_packet.GetU32 (&offset); + offset += 4; // Skip the useless CPU field + const uint32_t exc_type = exc_reply_packet.GetU32(&offset); + const uint32_t exc_code = exc_reply_packet.GetU32(&offset); + const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset); + // We have to make a copy of the stop info because the thread list + // will iterate through the threads and clear all stop infos.. + + // Let the StopInfoMachException::CreateStopReasonWithMachException() + // function update the PC if needed as we might hit a software breakpoint + // and need to decrement the PC (i386 and x86_64 need this) and KDP + // doesn't do this for us. + const bool pc_already_adjusted = false; + const bool adjust_pc_if_needed = true; + + m_cached_stop_info_sp = + StopInfoMachException::CreateStopReasonWithMachException( + *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted, + adjust_pc_if_needed); } + } } - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h index 7dc373f0355..ea517b4254f 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h @@ -17,82 +17,61 @@ class ProcessKDP; -class ThreadKDP : public lldb_private::Thread -{ +class ThreadKDP : public lldb_private::Thread { public: - ThreadKDP (lldb_private::Process &process, - lldb::tid_t tid); + ThreadKDP(lldb_private::Process &process, lldb::tid_t tid); - virtual - ~ThreadKDP (); + virtual ~ThreadKDP(); - virtual void - RefreshStateAfterStop(); + virtual void RefreshStateAfterStop(); - virtual const char * - GetName (); + virtual const char *GetName(); - virtual const char * - GetQueueName (); + virtual const char *GetQueueName(); - virtual lldb::RegisterContextSP - GetRegisterContext (); + virtual lldb::RegisterContextSP GetRegisterContext(); - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); + virtual lldb::RegisterContextSP + CreateRegisterContextForFrame(lldb_private::StackFrame *frame); - void - Dump (lldb_private::Log *log, uint32_t index); + void Dump(lldb_private::Log *log, uint32_t index); - static bool - ThreadIDIsValid (lldb::tid_t thread); + static bool ThreadIDIsValid(lldb::tid_t thread); - bool - ShouldStop (bool &step_more); + bool ShouldStop(bool &step_more); - const char * - GetBasicInfoAsString (); + const char *GetBasicInfoAsString(); - void - SetName (const char *name) - { - if (name && name[0]) - m_thread_name.assign (name); - else - m_thread_name.clear(); - } + void SetName(const char *name) { + if (name && name[0]) + m_thread_name.assign(name); + else + m_thread_name.clear(); + } - lldb::addr_t - GetThreadDispatchQAddr () - { - return m_thread_dispatch_qaddr; - } + lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; } - void - SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr) - { - m_thread_dispatch_qaddr = thread_dispatch_qaddr; - } - - void - SetStopInfoFrom_KDP_EXCEPTION (const lldb_private::DataExtractor &exc_reply_packet); + void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) { + m_thread_dispatch_qaddr = thread_dispatch_qaddr; + } + + void SetStopInfoFrom_KDP_EXCEPTION( + const lldb_private::DataExtractor &exc_reply_packet); protected: - - friend class ProcessKDP; - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - std::string m_thread_name; - std::string m_dispatch_queue_name; - lldb::addr_t m_thread_dispatch_qaddr; - lldb::StopInfoSP m_cached_stop_info_sp; - //------------------------------------------------------------------ - // Protected member functions. - //------------------------------------------------------------------ - virtual bool - CalculateStopInfo (); + friend class ProcessKDP; + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + std::string m_thread_name; + std::string m_dispatch_queue_name; + lldb::addr_t m_thread_dispatch_qaddr; + lldb::StopInfoSP m_cached_stop_info_sp; + //------------------------------------------------------------------ + // Protected member functions. + //------------------------------------------------------------------ + virtual bool CalculateStopInfo(); }; -#endif // liblldb_ThreadKDP_h_ +#endif // liblldb_ThreadKDP_h_ |