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