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