diff options
Diffstat (limited to 'source/Plugins/Process/MacOSX-Kernel')
17 files changed, 0 insertions, 3848 deletions
diff --git a/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt b/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt deleted file mode 100644 index bed0e3b7ab37..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -add_lldb_library(lldbPluginProcessMacOSXKernel PLUGIN - CommunicationKDP.cpp - ProcessKDP.cpp - ProcessKDPLog.cpp - RegisterContextKDP_arm.cpp - RegisterContextKDP_arm64.cpp - RegisterContextKDP_i386.cpp - RegisterContextKDP_x86_64.cpp - ThreadKDP.cpp - - LINK_LIBS - lldbBreakpoint - lldbCore - lldbHost - lldbInterpreter - lldbSymbol - lldbTarget - lldbUtility - lldbPluginDynamicLoaderDarwinKernel - lldbPluginDynamicLoaderStatic - lldbPluginProcessUtility - ) diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp deleted file mode 100644 index 8908108eff4b..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ /dev/null @@ -1,1289 +0,0 @@ -//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommunicationKDP.h" - -#include <errno.h> -#include <limits.h> -#include <string.h> - - -#include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Process.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/State.h" -#include "lldb/Utility/UUID.h" - -#include "ProcessKDPLog.h" - -using namespace lldb; -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) {} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -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); -} - -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; - } - - 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() == - *((const 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, - std::chrono::microseconds(GetPacketTimeout()).count())) { - 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; -} - -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); - } - return false; -} - -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(); -} - -bool CommunicationKDP::WaitForNotRunningPrivate( - const std::chrono::microseconds &timeout) { - return m_is_running.WaitForValueEqualTo(false, timeout); -} - -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); -} - -size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock( - DataExtractor &packet, uint32_t timeout_usec) { - uint8_t buffer[8192]; - Status error; - - Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); - - // 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 == UINT32_MAX - ? Timeout<std::micro>(llvm::None) - : std::chrono::microseconds(timeout_usec), - status, &error); - - LLDB_LOGV(log, - "Read (buffer, sizeof(buffer), timeout_usec = 0x{0:x}, " - "status = {1}, error = {2}) => bytes_read = {4}", - timeout_usec, - Communication::ConnectionStatusAsCString(status), - error, 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; - } - } - } - 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); - - Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); - - if (src && src_len > 0) { - if (log && log->GetVerbose()) { - PacketStreamType log_strm; - 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); - } - - // 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; -} - -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; -} - -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::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; -} - -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::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; - - if (uuid.SetFromStringRef(uuid_str) == 0) { - UUID invalid_uuid; - return invalid_uuid; - } - - return uuid; -} - -bool CommunicationKDP::RemoteIsEFI() { - if (GetKernelVersion() == NULL) - return false; - return strncmp(m_kernel_version.c_str(), "EFI", 3) == 0; -} - -bool CommunicationKDP::RemoteIsDarwinKernel() { - if (GetKernelVersion() == NULL) - return false; - return m_kernel_version.find("Darwin Kernel") != std::string::npos; -} - -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::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; -} - -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; -} - -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; -} - -uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst, - uint32_t dst_len, - Status &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; -} - -uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr, - const void *src, - uint32_t src_len, - Status &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; - } - } 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, Status &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"); - } - return false; -} - -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 void *data, - uint32_t data_len) { - DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size); - DumpPacket(s, extractor); -} - -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) - DumpDataExtractor(packet, - &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) - DumpDataExtractor(packet, - &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) - DumpDataExtractor(packet, - &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) - DumpDataExtractor(packet, - &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) - 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) - 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) - 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) - DumpDataExtractor(packet, - &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) - DumpDataExtractor(packet, - &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) - DumpDataExtractor(packet, - &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) - DumpDataExtractor(packet, - &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); - - DumpDataExtractor(packet, - &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::SendRequestReadRegisters(uint32_t cpu, - uint32_t flavor, void *dst, - uint32_t dst_len, - Status &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.SetErrorStringWithFormat( - "failed to read kdp registers for cpu %u flavor %u", cpu, flavor); - } else { - error.SetErrorString("failed to send packet"); - } - return 0; -} - -uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu, - uint32_t flavor, - const void *src, - uint32_t src_len, - Status &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::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; - return SendRequestAndGetReply(command, request_packet, reply_packet); -} - -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; - return SendRequestAndGetReply(command, request_packet, reply_packet); -} diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h deleted file mode 100644 index 64bfe5514735..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ /dev/null @@ -1,260 +0,0 @@ -//===-- CommunicationKDP.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommunicationKDP_h_ -#define liblldb_CommunicationKDP_h_ - -#include <list> -#include <mutex> -#include <string> - -#include "lldb/Core/Communication.h" -#include "lldb/Core/StreamBuffer.h" -#include "lldb/Utility/Listener.h" -#include "lldb/Utility/Predicate.h" -#include "lldb/lldb-private.h" - -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. - //------------------------------------------------------------------ - std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) { - const auto old_packet_timeout = m_packet_timeout; - m_packet_timeout = packet_timeout; - return old_packet_timeout; - } - - std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; } - - //------------------------------------------------------------------ - // 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::Status &error); - - uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src, - uint32_t src_len, - lldb_private::Status &error); - - bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len, - lldb_private::DataExtractor &reply, - lldb_private::Status &error); - - uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst, - uint32_t dst_size, - lldb_private::Status &error); - - uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor, - const void *src, uint32_t src_size, - lldb_private::Status &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); - -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; - std::chrono::seconds 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); -}; - -#endif // liblldb_CommunicationKDP_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp deleted file mode 100644 index c1c3678617c0..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ /dev/null @@ -1,1037 +0,0 @@ -//===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <errno.h> -#include <stdlib.h> - -#include <mutex> - -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/Symbols.h" -#include "lldb/Host/ThreadLauncher.h" -#include "lldb/Host/common/TCPSocket.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandObject.h" -#include "lldb/Interpreter/CommandObjectMultiword.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/OptionGroupString.h" -#include "lldb/Interpreter/OptionGroupUInt64.h" -#include "lldb/Interpreter/OptionValueProperties.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/State.h" -#include "lldb/Utility/StringExtractor.h" -#include "lldb/Utility/UUID.h" - -#include "llvm/Support/Threading.h" - -#define USEC_PER_SEC 1000000 - -#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" -#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" -#include "ProcessKDP.h" -#include "ProcessKDPLog.h" -#include "ThreadKDP.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { - -static constexpr PropertyDefinition g_properties[] = { - {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, {}, - "Specify the default packet timeout in seconds."}}; - -enum { ePropertyPacketTimeout }; - -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; -} - -} // anonymous namespace end - -static const lldb::tid_t g_kernel_tid = 1; - -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."; -} - -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; -} - -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; -} - -//---------------------------------------------------------------------- -// 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(std::chrono::seconds(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(); -} - -//---------------------------------------------------------------------- -// PluginInterface -//---------------------------------------------------------------------- -lldb_private::ConstString ProcessKDP::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ProcessKDP::GetPluginVersion() { return 1; } - -Status ProcessKDP::WillLaunch(Module *module) { - Status error; - error.SetErrorString("launching not supported in kdp-remote plug-in"); - return error; -} - -Status ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) { - Status error; - error.SetErrorString( - "attaching to a by process ID not supported in kdp-remote plug-in"); - return error; -} - -Status ProcessKDP::WillAttachToProcessWithName(const char *process_name, - bool wait_for_launch) { - Status 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; -} - -Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) { - Status 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); - - if (remote_url.empty()) { - error.SetErrorStringWithFormat("empty connection 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 (FileSystem::Instance().Exists( - executable_module_spec.GetFileSpec())) { - module_spec.GetFileSpec() = - executable_module_spec.GetFileSpec(); - } - } - if (!module_spec.GetSymbolFileSpec() || - !module_spec.GetSymbolFileSpec()) - Symbols::DownloadObjectAndSymbolFile(module_spec, true); - - if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { - 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, eLoadDependentsNo); - } - } - } - } 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("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.str().c_str()); - } - if (error.Fail()) - m_comm.Disconnect(); - - return error; -} - -//---------------------------------------------------------------------- -// Process Control -//---------------------------------------------------------------------- -Status ProcessKDP::DoLaunch(Module *exe_module, - ProcessLaunchInfo &launch_info) { - Status error; - error.SetErrorString("launching not supported in kdp-remote plug-in"); - return error; -} - -Status -ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid, - const ProcessAttachInfo &attach_info) { - Status error; - error.SetErrorString( - "attach to process by ID is not supported in kdp remote debugging"); - return error; -} - -Status -ProcessKDP::DoAttachToProcessWithName(const char *process_name, - const ProcessAttachInfo &attach_info) { - Status error; - error.SetErrorString( - "attach to process by name is not supported in kdp remote debugging"); - return error; -} - -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); - } -} - -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(); -} - -Status ProcessKDP::WillResume() { return Status(); } - -Status ProcessKDP::DoResume() { - Status 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; - - default: - // The only valid thread resume states are listed above - llvm_unreachable("invalid thread resume state"); - } - } - - 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)); - LLDB_LOGV(log, "pid = {0}", 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(); -} - -Status ProcessKDP::DoHalt(bool &caused_stop) { - Status error; - - if (m_comm.IsRunning()) { - if (m_destroy_in_process) { - // If we are attempting 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; -} - -Status ProcessKDP::DoDetach(bool keep_stopped) { - Status 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; -} - -Status 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(); -} - -//------------------------------------------------------------------ -// Process Memory -//------------------------------------------------------------------ -size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size, - Status &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; - } - } - - return total_bytes_read; - } - error.SetErrorString("not connected"); - return 0; -} - -size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size, - Status &error) { - if (m_comm.IsConnected()) - return m_comm.SendRequestWriteMemory(addr, buf, size, error); - error.SetErrorString("not connected"); - return 0; -} - -lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions, - Status &error) { - error.SetErrorString( - "memory allocation not supported in kdp remote debugging"); - return LLDB_INVALID_ADDRESS; -} - -Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) { - Status error; - error.SetErrorString( - "memory deallocation not supported in kdp remote debugging"); - return error; -} - -Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) { - if (m_comm.LocalBreakpointsAreSupported()) { - Status 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); -} - -Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) { - if (m_comm.LocalBreakpointsAreSupported()) { - Status 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; - } - return DisableSoftwareBreakpoint(bp_site); -} - -Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) { - Status error; - error.SetErrorString( - "watchpoints are not supported in kdp remote debugging"); - return error; -} - -Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) { - Status error; - error.SetErrorString( - "watchpoints are not supported in kdp remote debugging"); - return error; -} - -void ProcessKDP::Clear() { m_thread_list.Clear(); } - -Status ProcessKDP::DoSignal(int signo) { - Status error; - error.SetErrorString( - "sending signals is not supported in kdp remote debugging"); - return error; -} - -void ProcessKDP::Initialize() { - static llvm::once_flag g_once_flag; - - llvm::call_once(g_once_flag, []() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); - - ProcessKDPLog::Initialize(); - }); -} - -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 ()"); - - if (m_async_thread.IsJoinable()) - return true; - - 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)); - - 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); -} - -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->GetEvent(event_sp, llvm::None)) { - 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->GetEvent(event_sp, - std::chrono::microseconds(0))) { - // 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; -} - -class CommandObjectProcessKDPPacketSend : public CommandObjectParsed { -private: - 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), - 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; - } - } - Status 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()); - 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; - } -}; - -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() {} -}; - -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() {} -}; - -CommandObject *ProcessKDP::GetPluginCommandObject() { - if (!m_command_sp) - m_command_sp.reset(new CommandObjectMultiwordProcessKDP( - GetTarget().GetDebugger().GetCommandInterpreter())); - return m_command_sp.get(); -} diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h deleted file mode 100644 index f9102442de93..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ /dev/null @@ -1,220 +0,0 @@ -//===-- ProcessKDP.h --------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ProcessKDP_h_ -#define liblldb_ProcessKDP_h_ - - -#include <list> -#include <vector> - -#include "lldb/Core/ThreadSafeValue.h" -#include "lldb/Host/HostThread.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Broadcaster.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/Status.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StringList.h" - -#include "CommunicationKDP.h" - -class ThreadKDP; - -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); - - ~ProcessKDP() override; - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - bool CanDebug(lldb::TargetSP target_sp, - bool plugin_specified_by_name) override; - lldb_private::CommandObject *GetPluginCommandObject() override; - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - lldb_private::Status WillLaunch(lldb_private::Module *module) override; - - lldb_private::Status - DoLaunch(lldb_private::Module *exe_module, - lldb_private::ProcessLaunchInfo &launch_info) override; - - lldb_private::Status WillAttachToProcessWithID(lldb::pid_t pid) override; - - lldb_private::Status - WillAttachToProcessWithName(const char *process_name, - bool wait_for_launch) override; - - lldb_private::Status DoConnectRemote(lldb_private::Stream *strm, - llvm::StringRef remote_url) override; - - lldb_private::Status DoAttachToProcessWithID( - lldb::pid_t pid, - const lldb_private::ProcessAttachInfo &attach_info) override; - - lldb_private::Status DoAttachToProcessWithName( - const char *process_name, - const lldb_private::ProcessAttachInfo &attach_info) override; - - void DidAttach(lldb_private::ArchSpec &process_arch) override; - - lldb::addr_t GetImageInfoAddress() override; - - lldb_private::DynamicLoader *GetDynamicLoader() override; - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ - lldb_private::Status WillResume() override; - - lldb_private::Status DoResume() override; - - lldb_private::Status DoHalt(bool &caused_stop) override; - - lldb_private::Status DoDetach(bool keep_stopped) override; - - lldb_private::Status DoSignal(int signal) override; - - lldb_private::Status DoDestroy() override; - - void RefreshStateAfterStop() override; - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - bool IsAlive() override; - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, - lldb_private::Status &error) override; - - size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, - lldb_private::Status &error) override; - - lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, - lldb_private::Status &error) override; - - lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override; - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - lldb_private::Status - EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; - - lldb_private::Status - DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; - - //---------------------------------------------------------------------- - // Process Watchpoints - //---------------------------------------------------------------------- - lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp, - bool notify = true) override; - - lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp, - bool notify = true) override; - - 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(); - - bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list) override; - - 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); -}; - -#endif // liblldb_ProcessKDP_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp deleted file mode 100644 index ffab3e5e23c7..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp +++ /dev/null @@ -1,35 +0,0 @@ -//===-- ProcessKDPLog.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessKDPLog.h" - -using namespace lldb_private; - -static constexpr Log::Category g_categories[] = { - {{"async"}, {"log asynchronous activity"}, KDP_LOG_ASYNC}, - {{"break"}, {"log breakpoints"}, KDP_LOG_BREAKPOINTS}, - {{"comm"}, {"log communication activity"}, KDP_LOG_COMM}, - {{"data-long"}, - {"log memory bytes for memory reads and writes for all transactions"}, - KDP_LOG_MEMORY_DATA_LONG}, - {{"data-short"}, - {"log memory bytes for memory reads and writes for short transactions " - "only"}, - KDP_LOG_MEMORY_DATA_SHORT}, - {{"memory"}, {"log memory reads and writes"}, KDP_LOG_MEMORY}, - {{"packets"}, {"log gdb remote packets"}, KDP_LOG_PACKETS}, - {{"process"}, {"log process events and activities"}, KDP_LOG_PROCESS}, - {{"step"}, {"log step related activities"}, KDP_LOG_STEP}, - {{"thread"}, {"log thread events and activities"}, KDP_LOG_THREAD}, - {{"watch"}, {"log watchpoint related activities"}, KDP_LOG_WATCHPOINTS}, -}; - -Log::Channel ProcessKDPLog::g_channel(g_categories, KDP_LOG_DEFAULT); - -void ProcessKDPLog::Initialize() { Log::Register("kdp-remote", g_channel); } diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h deleted file mode 100644 index 908754ec992b..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- ProcessKDPLog.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ProcessKDPLog_h_ -#define liblldb_ProcessKDPLog_h_ - -#include "lldb/Utility/Log.h" - -#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 - -namespace lldb_private { -class ProcessKDPLog { - static Log::Channel g_channel; - -public: - static void Initialize(); - - static Log *GetLogIfAllCategoriesSet(uint32_t mask) { - return g_channel.GetLogIfAll(mask); - } -}; -} - -#endif // liblldb_ProcessKDPLog_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp deleted file mode 100644 index 0f9e62ce355a..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp +++ /dev/null @@ -1,147 +0,0 @@ -//===-- RegisterContextKDP_arm.cpp ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextKDP_arm.h" - -#include "ProcessKDP.h" -#include "ThreadKDP.h" - -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) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoWriteGPR(lldb::tid_t tid, int flavor, - const GPR &gpr) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoWriteFPU(lldb::tid_t tid, int flavor, - const FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoWriteEXC(lldb::tid_t tid, int flavor, - const EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm::DoWriteDBG(lldb::tid_t tid, int flavor, - const DBG &dbg) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h deleted file mode 100644 index 1532f23207f4..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h +++ /dev/null @@ -1,44 +0,0 @@ -//===-- RegisterContextKDP_arm.h --------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextKDP_arm_h_ -#define liblldb_RegisterContextKDP_arm_h_ - - -#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h" - -class ThreadKDP; - -class RegisterContextKDP_arm : public RegisterContextDarwin_arm { -public: - RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx); - - 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); - - ThreadKDP &m_kdp_thread; -}; - -#endif // liblldb_RegisterContextKDP_arm_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp deleted file mode 100644 index e13a7f3ad907..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextKDP_arm64.h" - -#include "ProcessKDP.h" -#include "ThreadKDP.h" - -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) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoWriteGPR(lldb::tid_t tid, int flavor, - const GPR &gpr) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoWriteFPU(lldb::tid_t tid, int flavor, - const FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoWriteEXC(lldb::tid_t tid, int flavor, - const EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_arm64::DoWriteDBG(lldb::tid_t tid, int flavor, - const DBG &dbg) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h deleted file mode 100644 index be4038ba96ea..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h +++ /dev/null @@ -1,45 +0,0 @@ -//===-- RegisterContextKDP_arm64.h --------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextKDP_arm64_h_ -#define liblldb_RegisterContextKDP_arm64_h_ - - -#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h" - -class ThreadKDP; - -class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 { -public: - RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx); - - 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); - - ThreadKDP &m_kdp_thread; -}; - -#endif // liblldb_RegisterContextKDP_arm64_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp deleted file mode 100644 index 096aa0f95d00..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp +++ /dev/null @@ -1,115 +0,0 @@ -//===-- RegisterContextKDP_i386.cpp -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextKDP_i386.h" -#include "ProcessKDP.h" -#include "ThreadKDP.h" - -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() {} - -int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_i386::DoWriteGPR(lldb::tid_t tid, int flavor, - const GPR &gpr) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_i386::DoWriteFPU(lldb::tid_t tid, int flavor, - const FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_i386::DoWriteEXC(lldb::tid_t tid, int flavor, - const EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h deleted file mode 100644 index 699d5fabe157..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h +++ /dev/null @@ -1,39 +0,0 @@ -//===-- RegisterContextKDP_i386.h -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextKDP_i386_h_ -#define liblldb_RegisterContextKDP_i386_h_ - -#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h" - -class ThreadKDP; - -class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 { -public: - 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; -}; - -#endif // liblldb_RegisterContextKDP_i386_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp deleted file mode 100644 index 9d85145f2eaf..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp +++ /dev/null @@ -1,118 +0,0 @@ -//===-- RegisterContextKDP_x86_64.cpp ---------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextKDP_x86_64.h" -#include "ProcessKDP.h" -#include "ThreadKDP.h" - -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() {} - -int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor, - GPR &gpr) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_x86_64::DoReadFPU(lldb::tid_t tid, int flavor, - FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_x86_64::DoReadEXC(lldb::tid_t tid, int flavor, - EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor, - const GPR &gpr) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor, - const FPU &fpu) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} - -int RegisterContextKDP_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor, - const EXC &exc) { - ProcessSP process_sp(CalculateProcess()); - if (process_sp) { - Status error; - if (static_cast<ProcessKDP *>(process_sp.get()) - ->GetCommunication() - .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc), - error)) { - if (error.Success()) - return 0; - } - } - return -1; -} diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h deleted file mode 100644 index 9841ad77b004..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h +++ /dev/null @@ -1,39 +0,0 @@ -//===-- RegisterContextKDP_x86_64.h -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextKDP_x86_64_h_ -#define liblldb_RegisterContextKDP_x86_64_h_ - -#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h" - -class ThreadKDP; - -class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 { -public: - 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; -}; - -#endif // liblldb_RegisterContextKDP_x86_64_h_ diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp deleted file mode 100644 index 6f26acd0b8aa..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ThreadKDP.h" - -#include "lldb/Host/SafeMachO.h" - -#include "lldb/Breakpoint/Watchpoint.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/Utility/ArchSpec.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/State.h" -#include "lldb/Utility/StreamString.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" - -using namespace lldb; -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) { - Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD); - LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID()); -} - -ThreadKDP::~ThreadKDP() { - Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD); - LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID()); - DestroyThread(); -} - -const char *ThreadKDP::GetName() { - if (m_thread_name.empty()) - return nullptr; - return m_thread_name.c_str(); -} - -const char *ThreadKDP::GetQueueName() { return nullptr; } - -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::ShouldStop(bool &step_more) { return true; } -lldb::RegisterContextSP ThreadKDP::GetRegisterContext() { - if (!m_reg_context_sp) - m_reg_context_sp = CreateRegisterContextForFrame(nullptr); - 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: - llvm_unreachable("Add CPU type support in KDP"); - } - } - } else { - Unwind *unwinder = GetUnwinder(); - if (unwinder != nullptr) - 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; - } - 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); - } - } -} diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h deleted file mode 100644 index ea517b4254fc..000000000000 --- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h +++ /dev/null @@ -1,77 +0,0 @@ -//===-- ThreadKDP.h ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ThreadKDP_h_ -#define liblldb_ThreadKDP_h_ - -#include <string> - -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -class ProcessKDP; - -class ThreadKDP : public lldb_private::Thread { -public: - ThreadKDP(lldb_private::Process &process, lldb::tid_t tid); - - virtual ~ThreadKDP(); - - virtual void RefreshStateAfterStop(); - - virtual const char *GetName(); - - virtual const char *GetQueueName(); - - virtual lldb::RegisterContextSP GetRegisterContext(); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame(lldb_private::StackFrame *frame); - - void Dump(lldb_private::Log *log, uint32_t index); - - static bool ThreadIDIsValid(lldb::tid_t thread); - - bool ShouldStop(bool &step_more); - - const char *GetBasicInfoAsString(); - - 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; } - - 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(); -}; - -#endif // liblldb_ThreadKDP_h_ |