diff options
Diffstat (limited to 'source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h')
-rw-r--r-- | source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h new file mode 100644 index 0000000000000..98a146d5a06da --- /dev/null +++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h @@ -0,0 +1,347 @@ +//===-- 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_ + +// C Includes +// C++ Includes +#include <list> +#include <string> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Communication.h" +#include "lldb/Core/Listener.h" +#include "lldb/Core/StreamBuffer.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Host/Predicate.h" +#include "lldb/Host/TimeValue.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(lldb_private::Mutex::Locker& locker); + + bool + CheckForPacket (const uint8_t *src, + size_t src_len, + lldb_private::DataExtractor &packet); + bool + IsRunning() const + { + return m_is_running.GetValue(); + } + + //------------------------------------------------------------------ + // Set the global packet timeout. + // + // For clients, this is the timeout that gets used when sending + // packets and waiting for responses. For servers, this might not + // get used, and if it doesn't this should be moved to the + // CommunicationKDPClient. + //------------------------------------------------------------------ + uint32_t + SetPacketTimeout (uint32_t packet_timeout) + { + const uint32_t old_packet_timeout = m_packet_timeout; + m_packet_timeout = packet_timeout; + return old_packet_timeout; + } + + uint32_t + GetPacketTimeoutInMicroSeconds () const + { + return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec; + } + + //------------------------------------------------------------------ + // Public Request Packets + //------------------------------------------------------------------ + bool + SendRequestConnect (uint16_t reply_port, + uint16_t exc_port, + const char *greeting); + + bool + SendRequestReattach (uint16_t reply_port); + + bool + SendRequestDisconnect (); + + uint32_t + SendRequestReadMemory (lldb::addr_t addr, + void *dst, + uint32_t dst_size, + lldb_private::Error &error); + + uint32_t + SendRequestWriteMemory (lldb::addr_t addr, + const void *src, + uint32_t src_len, + lldb_private::Error &error); + + bool + SendRawRequest (uint8_t command_byte, + const void *src, + uint32_t src_len, + lldb_private::DataExtractor &reply, + lldb_private::Error &error); + + uint32_t + SendRequestReadRegisters (uint32_t cpu, + uint32_t flavor, + void *dst, + uint32_t dst_size, + lldb_private::Error &error); + + uint32_t + SendRequestWriteRegisters (uint32_t cpu, + uint32_t flavor, + const void *src, + uint32_t src_size, + lldb_private::Error &error); + + const char * + GetKernelVersion (); + + // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... + // const char * + // GetImagePath (); + + uint32_t + GetVersion (); + + uint32_t + GetFeatureFlags (); + + bool + LocalBreakpointsAreSupported () + { + return (GetFeatureFlags() & KDP_FEATURE_BP) != 0; + } + + uint32_t + GetCPUMask (); + + uint32_t + GetCPUType (); + + uint32_t + GetCPUSubtype (); + + lldb_private::UUID + GetUUID (); + + bool + RemoteIsEFI (); + + bool + RemoteIsDarwinKernel (); + + lldb::addr_t + GetLoadAddress (); + + bool + SendRequestResume (); + + bool + SendRequestSuspend (); + + bool + SendRequestBreakpoint (bool set, lldb::addr_t addr); + +protected: + + bool + SendRequestPacketNoLock (const PacketStreamType &request_packet); + + size_t + WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response, + uint32_t timeout_usec); + + bool + WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr); + + void + MakeRequestPacketHeader (CommandType request_type, + PacketStreamType &request_packet, + uint16_t request_length); + + //------------------------------------------------------------------ + // Protected Request Packets (use public accessors which will cache + // results. + //------------------------------------------------------------------ + bool + SendRequestVersion (); + + bool + SendRequestHostInfo (); + + bool + SendRequestKernelVersion (); + + // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... + //bool + //SendRequestImagePath (); + + void + DumpPacket (lldb_private::Stream &s, + const void *data, + uint32_t data_len); + + void + DumpPacket (lldb_private::Stream &s, + const lldb_private::DataExtractor& extractor); + + bool + VersionIsValid() const + { + return m_kdp_version_version != 0; + } + + bool + HostInfoIsValid() const + { + return m_kdp_hostinfo_cpu_type != 0; + } + + bool + ExtractIsReply (uint8_t first_packet_byte) const + { + // TODO: handle big endian... + return (first_packet_byte & ePacketTypeMask) != 0; + } + + CommandType + ExtractCommand (uint8_t first_packet_byte) const + { + // TODO: handle big endian... + return (CommandType)(first_packet_byte & eCommandTypeMask); + } + + static const char * + GetCommandAsCString (uint8_t command); + + void + ClearKDPSettings (); + + bool + SendRequestAndGetReply (const CommandType command, + const PacketStreamType &request_packet, + lldb_private::DataExtractor &reply_packet); + //------------------------------------------------------------------ + // Classes that inherit from CommunicationKDP can see and modify these + //------------------------------------------------------------------ + uint32_t m_addr_byte_size; + lldb::ByteOrder m_byte_order; + uint32_t m_packet_timeout; + lldb_private::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_ |