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