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 const static uint32_t kMaxPacketSize = 1200; 25 const static uint32_t kMaxDataSize = 1024; 26 typedef lldb_private::StreamBuffer<4096> PacketStreamType; 27 enum CommandType { 28 KDP_CONNECT = 0u, 29 KDP_DISCONNECT, 30 KDP_HOSTINFO, 31 KDP_VERSION, 32 KDP_MAXBYTES, 33 KDP_READMEM, 34 KDP_WRITEMEM, 35 KDP_READREGS, 36 KDP_WRITEREGS, 37 KDP_LOAD, 38 KDP_IMAGEPATH, 39 KDP_SUSPEND, 40 KDP_RESUMECPUS, 41 KDP_EXCEPTION, 42 KDP_TERMINATION, 43 KDP_BREAKPOINT_SET, 44 KDP_BREAKPOINT_REMOVE, 45 KDP_REGIONS, 46 KDP_REATTACH, 47 KDP_HOSTREBOOT, 48 KDP_READMEM64, 49 KDP_WRITEMEM64, 50 KDP_BREAKPOINT_SET64, 51 KDP_BREAKPOINT_REMOVE64, 52 KDP_KERNELVERSION, 53 KDP_READPHYSMEM64, 54 KDP_WRITEPHYSMEM64, 55 KDP_READIOPORT, 56 KDP_WRITEIOPORT, 57 KDP_READMSR64, 58 KDP_WRITEMSR64, 59 KDP_DUMPINFO 60 }; 61 62 enum { KDP_FEATURE_BP = (1u << 0) }; 63 64 enum KDPError { 65 KDP_PROTERR_SUCCESS = 0, 66 KDP_PROTERR_ALREADY_CONNECTED, 67 KDP_PROTERR_BAD_NBYTES, 68 KDP_PROTERR_BADFLAVOR 69 }; 70 71 enum PacketType { 72 ePacketTypeRequest = 0x00u, 73 ePacketTypeReply = 0x80u, 74 ePacketTypeMask = 0x80u, 75 eCommandTypeMask = 0x7fu 76 }; 77 // Constructors and Destructors 78 CommunicationKDP(const char *comm_name); 79 80 ~CommunicationKDP() override; 81 82 bool SendRequestPacket(const PacketStreamType &request_packet); 83 84 // Wait for a packet within 'nsec' seconds 85 size_t 86 WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response, 87 uint32_t usec); 88 89 bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock); 90 91 bool CheckForPacket(const uint8_t *src, size_t src_len, 92 lldb_private::DataExtractor &packet); IsRunning()93 bool IsRunning() const { return m_is_running.GetValue(); } 94 95 // Set the global packet timeout. 96 // 97 // For clients, this is the timeout that gets used when sending 98 // packets and waiting for responses. For servers, this might not 99 // get used, and if it doesn't this should be moved to the 100 // CommunicationKDPClient. SetPacketTimeout(std::chrono::seconds packet_timeout)101 std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) { 102 const auto old_packet_timeout = m_packet_timeout; 103 m_packet_timeout = packet_timeout; 104 return old_packet_timeout; 105 } 106 GetPacketTimeout()107 std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; } 108 109 // Public Request Packets 110 bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port, 111 const char *greeting); 112 113 bool SendRequestReattach(uint16_t reply_port); 114 115 bool SendRequestDisconnect(); 116 117 uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst, 118 uint32_t dst_size, 119 lldb_private::Status &error); 120 121 uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src, 122 uint32_t src_len, 123 lldb_private::Status &error); 124 125 bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len, 126 lldb_private::DataExtractor &reply, 127 lldb_private::Status &error); 128 129 uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst, 130 uint32_t dst_size, 131 lldb_private::Status &error); 132 133 uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor, 134 const void *src, uint32_t src_size, 135 lldb_private::Status &error); 136 137 const char *GetKernelVersion(); 138 139 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... 140 // const char * 141 // GetImagePath (); 142 143 uint32_t GetVersion(); 144 145 uint32_t GetFeatureFlags(); 146 LocalBreakpointsAreSupported()147 bool LocalBreakpointsAreSupported() { 148 return (GetFeatureFlags() & KDP_FEATURE_BP) != 0; 149 } 150 151 uint32_t GetCPUMask(); 152 153 uint32_t GetCPUType(); 154 155 uint32_t GetCPUSubtype(); 156 157 lldb_private::UUID GetUUID(); 158 159 bool RemoteIsEFI(); 160 161 bool RemoteIsDarwinKernel(); 162 163 lldb::addr_t GetLoadAddress(); 164 165 bool SendRequestResume(); 166 167 bool SendRequestSuspend(); 168 169 bool SendRequestBreakpoint(bool set, lldb::addr_t addr); 170 171 protected: 172 bool SendRequestPacketNoLock(const PacketStreamType &request_packet); 173 174 size_t WaitForPacketWithTimeoutMicroSecondsNoLock( 175 lldb_private::DataExtractor &response, uint32_t timeout_usec); 176 177 bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout); 178 179 void MakeRequestPacketHeader(CommandType request_type, 180 PacketStreamType &request_packet, 181 uint16_t request_length); 182 183 // Protected Request Packets (use public accessors which will cache 184 // results. 185 bool SendRequestVersion(); 186 187 bool SendRequestHostInfo(); 188 189 bool SendRequestKernelVersion(); 190 191 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... 192 // bool 193 // SendRequestImagePath (); 194 195 void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len); 196 197 void DumpPacket(lldb_private::Stream &s, 198 const lldb_private::DataExtractor &extractor); 199 VersionIsValid()200 bool VersionIsValid() const { return m_kdp_version_version != 0; } 201 HostInfoIsValid()202 bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; } 203 ExtractIsReply(uint8_t first_packet_byte)204 bool ExtractIsReply(uint8_t first_packet_byte) const { 205 // TODO: handle big endian... 206 return (first_packet_byte & ePacketTypeMask) != 0; 207 } 208 ExtractCommand(uint8_t first_packet_byte)209 CommandType ExtractCommand(uint8_t first_packet_byte) const { 210 // TODO: handle big endian... 211 return (CommandType)(first_packet_byte & eCommandTypeMask); 212 } 213 214 static const char *GetCommandAsCString(uint8_t command); 215 216 void ClearKDPSettings(); 217 218 bool SendRequestAndGetReply(const CommandType command, 219 const PacketStreamType &request_packet, 220 lldb_private::DataExtractor &reply_packet); 221 // Classes that inherit from CommunicationKDP can see and modify these 222 uint32_t m_addr_byte_size; 223 lldb::ByteOrder m_byte_order; 224 std::string m_bytes; 225 std::recursive_mutex m_bytes_mutex; 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