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