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