diff options
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_ |