1 //===-- CommunicationKDP.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H 10 #define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H 11 12 #include <list> 13 #include <mutex> 14 #include <string> 15 16 #include "lldb/Core/Communication.h" 17 #include "lldb/Core/StreamBuffer.h" 18 #include "lldb/Utility/Listener.h" 19 #include "lldb/Utility/Predicate.h" 20 #include "lldb/lldb-private.h" 21 22 class CommunicationKDP : public lldb_private::Communication { 23 public: 24 enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit }; 25 26 const static uint32_t kMaxPacketSize = 1200; 27 const static uint32_t kMaxDataSize = 1024; 28 typedef lldb_private::StreamBuffer<4096> PacketStreamType; 29 enum CommandType { 30 KDP_CONNECT = 0u, 31 KDP_DISCONNECT, 32 KDP_HOSTINFO, 33 KDP_VERSION, 34 KDP_MAXBYTES, 35 KDP_READMEM, 36 KDP_WRITEMEM, 37 KDP_READREGS, 38 KDP_WRITEREGS, 39 KDP_LOAD, 40 KDP_IMAGEPATH, 41 KDP_SUSPEND, 42 KDP_RESUMECPUS, 43 KDP_EXCEPTION, 44 KDP_TERMINATION, 45 KDP_BREAKPOINT_SET, 46 KDP_BREAKPOINT_REMOVE, 47 KDP_REGIONS, 48 KDP_REATTACH, 49 KDP_HOSTREBOOT, 50 KDP_READMEM64, 51 KDP_WRITEMEM64, 52 KDP_BREAKPOINT_SET64, 53 KDP_BREAKPOINT_REMOVE64, 54 KDP_KERNELVERSION, 55 KDP_READPHYSMEM64, 56 KDP_WRITEPHYSMEM64, 57 KDP_READIOPORT, 58 KDP_WRITEIOPORT, 59 KDP_READMSR64, 60 KDP_WRITEMSR64, 61 KDP_DUMPINFO 62 }; 63 64 enum { KDP_FEATURE_BP = (1u << 0) }; 65 66 enum KDPError { 67 KDP_PROTERR_SUCCESS = 0, 68 KDP_PROTERR_ALREADY_CONNECTED, 69 KDP_PROTERR_BAD_NBYTES, 70 KDP_PROTERR_BADFLAVOR 71 }; 72 73 enum PacketType { 74 ePacketTypeRequest = 0x00u, 75 ePacketTypeReply = 0x80u, 76 ePacketTypeMask = 0x80u, 77 eCommandTypeMask = 0x7fu 78 }; 79 // Constructors and Destructors 80 CommunicationKDP(const char *comm_name); 81 82 virtual ~CommunicationKDP(); 83 84 bool SendRequestPacket(const PacketStreamType &request_packet); 85 86 // Wait for a packet within 'nsec' seconds 87 size_t 88 WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response, 89 uint32_t usec); 90 91 bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock); 92 93 bool CheckForPacket(const uint8_t *src, size_t src_len, 94 lldb_private::DataExtractor &packet); IsRunning()95 bool IsRunning() const { return m_is_running.GetValue(); } 96 97 // Set the global packet timeout. 98 // 99 // For clients, this is the timeout that gets used when sending 100 // packets and waiting for responses. For servers, this might not 101 // get used, and if it doesn't this should be moved to the 102 // CommunicationKDPClient. SetPacketTimeout(std::chrono::seconds packet_timeout)103 std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) { 104 const auto old_packet_timeout = m_packet_timeout; 105 m_packet_timeout = packet_timeout; 106 return old_packet_timeout; 107 } 108 GetPacketTimeout()109 std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; } 110 111 // Public Request Packets 112 bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port, 113 const char *greeting); 114 115 bool SendRequestReattach(uint16_t reply_port); 116 117 bool SendRequestDisconnect(); 118 119 uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst, 120 uint32_t dst_size, 121 lldb_private::Status &error); 122 123 uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src, 124 uint32_t src_len, 125 lldb_private::Status &error); 126 127 bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len, 128 lldb_private::DataExtractor &reply, 129 lldb_private::Status &error); 130 131 uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst, 132 uint32_t dst_size, 133 lldb_private::Status &error); 134 135 uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor, 136 const void *src, uint32_t src_size, 137 lldb_private::Status &error); 138 139 const char *GetKernelVersion(); 140 141 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... 142 // const char * 143 // GetImagePath (); 144 145 uint32_t GetVersion(); 146 147 uint32_t GetFeatureFlags(); 148 LocalBreakpointsAreSupported()149 bool LocalBreakpointsAreSupported() { 150 return (GetFeatureFlags() & KDP_FEATURE_BP) != 0; 151 } 152 153 uint32_t GetCPUMask(); 154 155 uint32_t GetCPUType(); 156 157 uint32_t GetCPUSubtype(); 158 159 lldb_private::UUID GetUUID(); 160 161 bool RemoteIsEFI(); 162 163 bool RemoteIsDarwinKernel(); 164 165 lldb::addr_t GetLoadAddress(); 166 167 bool SendRequestResume(); 168 169 bool SendRequestSuspend(); 170 171 bool SendRequestBreakpoint(bool set, lldb::addr_t addr); 172 173 protected: 174 bool SendRequestPacketNoLock(const PacketStreamType &request_packet); 175 176 size_t WaitForPacketWithTimeoutMicroSecondsNoLock( 177 lldb_private::DataExtractor &response, uint32_t timeout_usec); 178 179 bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout); 180 181 void MakeRequestPacketHeader(CommandType request_type, 182 PacketStreamType &request_packet, 183 uint16_t request_length); 184 185 // Protected Request Packets (use public accessors which will cache 186 // results. 187 bool SendRequestVersion(); 188 189 bool SendRequestHostInfo(); 190 191 bool SendRequestKernelVersion(); 192 193 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... 194 // bool 195 // SendRequestImagePath (); 196 197 void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len); 198 199 void DumpPacket(lldb_private::Stream &s, 200 const lldb_private::DataExtractor &extractor); 201 VersionIsValid()202 bool VersionIsValid() const { return m_kdp_version_version != 0; } 203 HostInfoIsValid()204 bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; } 205 ExtractIsReply(uint8_t first_packet_byte)206 bool ExtractIsReply(uint8_t first_packet_byte) const { 207 // TODO: handle big endian... 208 return (first_packet_byte & ePacketTypeMask) != 0; 209 } 210 ExtractCommand(uint8_t first_packet_byte)211 CommandType ExtractCommand(uint8_t first_packet_byte) const { 212 // TODO: handle big endian... 213 return (CommandType)(first_packet_byte & eCommandTypeMask); 214 } 215 216 static const char *GetCommandAsCString(uint8_t command); 217 218 void ClearKDPSettings(); 219 220 bool SendRequestAndGetReply(const CommandType command, 221 const PacketStreamType &request_packet, 222 lldb_private::DataExtractor &reply_packet); 223 // Classes that inherit from CommunicationKDP can see and modify these 224 uint32_t m_addr_byte_size; 225 lldb::ByteOrder m_byte_order; 226 std::chrono::seconds m_packet_timeout; 227 std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving 228 // packets to a single thread at a time 229 lldb_private::Predicate<bool> m_is_running; 230 uint32_t m_session_key; 231 uint8_t m_request_sequence_id; 232 uint8_t m_exception_sequence_id; 233 uint32_t m_kdp_version_version; 234 uint32_t m_kdp_version_feature; 235 uint32_t m_kdp_hostinfo_cpu_mask; 236 uint32_t m_kdp_hostinfo_cpu_type; 237 uint32_t m_kdp_hostinfo_cpu_subtype; 238 std::string m_kernel_version; 239 // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to 240 // hang the KDP connection... 241 lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging 242 private: 243 // For CommunicationKDP only 244 CommunicationKDP(const CommunicationKDP &) = delete; 245 const CommunicationKDP &operator=(const CommunicationKDP &) = delete; 246 }; 247 248 #endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H 249