1
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// Created by Greg Clayton on 12/12/07.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H
14#define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H
15
16#include "DNB.h"
17#include "RNBContext.h"
18#include "RNBDefs.h"
19#include "RNBSocket.h"
20#include <deque>
21#include <map>
22#include <string>
23#include <vector>
24
25class RNBSocket;
26class RNBContext;
27
28enum event_loop_mode { debug_nub, gdb_remote_protocol, done };
29
30enum class compression_types { zlib_deflate, lz4, lzma, lzfse, none };
31
32class RNBRemote {
33public:
34 // clang-format off
35 enum PacketEnum {
36 invalid_packet = 0,
37 ack, // '+'
38 nack, // '-'
39 halt, // ^C (async halt)
40 use_extended_mode, // '!'
41 why_halted, // '?'
42 set_argv, // 'A'
43 set_bp, // 'B'
44 cont, // 'c'
45 continue_with_sig, // 'C'
46 detach, // 'D'
47 set_thread, // 'H'
48 step_inferior_one_cycle, // 'i'
49 signal_and_step_inf_one_cycle, // 'I'
50 kill, // 'k'
51 read_memory, // 'm'
52 write_memory, // 'M'
53 read_register, // 'p'
54 write_register, // 'P'
55 restart, // 'R'
56 single_step, // 's'
57 single_step_with_sig, // 'S'
58 search_mem_backwards, // 't'
59 thread_alive_p, // 'T'
60 vattach, // 'vAttach;pid'
61 vattachwait, // 'vAttachWait:XX...' where XX is one or more hex encoded
62 // process name ASCII bytes
63 vattachorwait, // 'vAttachOrWait:XX...' where XX is one or more hex encoded
64 // process name ASCII bytes
65 vattachname, // 'vAttachName:XX...' where XX is one or more hex encoded
66 // process name ASCII bytes
67 vcont, // 'vCont'
68 vcont_list_actions, // 'vCont?'
69 read_data_from_memory, // 'x'
70 write_data_to_memory, // 'X'
71 insert_mem_bp, // 'Z0'
72 remove_mem_bp, // 'z0'
73 insert_hardware_bp, // 'Z1'
74 remove_hardware_bp, // 'z1'
75 insert_write_watch_bp, // 'Z2'
76 remove_write_watch_bp, // 'z2'
77 insert_read_watch_bp, // 'Z3'
78 remove_read_watch_bp, // 'z3'
79 insert_access_watch_bp, // 'Z4'
80 remove_access_watch_bp, // 'z4'
81
82 query_monitor, // 'qRcmd'
83 query_current_thread_id, // 'qC'
84 query_get_pid, // 'qGetPid'
85 query_echo, // 'qEcho'
86 query_thread_ids_first, // 'qfThreadInfo'
87 query_thread_ids_subsequent, // 'qsThreadInfo'
88 query_thread_extra_info, // 'qThreadExtraInfo'
89 query_thread_stop_info, // 'qThreadStopInfo'
90 query_image_offsets, // 'qOffsets'
91 query_symbol_lookup, // 'qSymbol'
92 query_launch_success, // 'qLaunchSuccess'
93 query_register_info, // 'qRegisterInfo'
94 query_shlib_notify_info_addr, // 'qShlibInfoAddr'
95 query_step_packet_supported, // 'qStepPacketSupported'
96 query_supported_features, // 'qSupported'
97 query_vattachorwait_supported, // 'qVAttachOrWaitSupported'
98 query_sync_thread_state_supported, // 'QSyncThreadState'
99 query_host_info, // 'qHostInfo'
100 query_gdb_server_version, // 'qGDBServerVersion'
101 query_process_info, // 'qProcessInfo'
102 json_query_thread_extended_info, // 'jThreadExtendedInfo'
103 json_query_get_loaded_dynamic_libraries_infos, // 'jGetLoadedDynamicLibrariesInfos'
104 json_query_threads_info, // 'jThreadsInfo'
105 json_query_get_shared_cache_info, // 'jGetSharedCacheInfo'
106 pass_signals_to_inferior, // 'QPassSignals'
107 start_noack_mode, // 'QStartNoAckMode'
108 prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
109 set_logging_mode, // 'QSetLogging:'
110 set_ignored_exceptions, // 'QSetIgnoredExceptions'
111 set_max_packet_size, // 'QSetMaxPacketSize:'
112 set_max_payload_size, // 'QSetMaxPayloadSize:'
113 set_environment_variable, // 'QEnvironment:'
114 set_environment_variable_hex, // 'QEnvironmentHexEncoded:'
115 set_launch_arch, // 'QLaunchArch:'
116 set_disable_aslr, // 'QSetDisableASLR:'
117 set_stdin, // 'QSetSTDIN:'
118 set_stdout, // 'QSetSTDOUT:'
119 set_stderr, // 'QSetSTDERR:'
120 set_working_dir, // 'QSetWorkingDir:'
121 set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:'
122 sync_thread_state, // 'QSyncThreadState:'
123 memory_region_info, // 'qMemoryRegionInfo:'
124 get_profile_data, // 'qGetProfileData'
125 set_enable_profiling, // 'QSetEnableAsyncProfiling'
126 enable_compression, // 'QEnableCompression:'
127 watchpoint_support_info, // 'qWatchpointSupportInfo:'
128 allocate_memory, // '_M'
129 deallocate_memory, // '_m'
130 set_process_event, // 'QSetProcessEvent:'
131 save_register_state, // '_g'
132 restore_register_state, // '_G'
133 speed_test, // 'qSpeedTest:'
134 set_detach_on_error, // 'QSetDetachOnError:'
135 query_transfer, // 'qXfer:'
136 json_query_dyld_process_state, // 'jGetDyldProcessState'
137 enable_error_strings, // 'QEnableErrorStrings'
138 unknown_type
139 };
140 // clang-format on
141
142 typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
143
144 RNBRemote();
145 ~RNBRemote();
146
147 void Initialize();
148
149 bool InitializeRegisters(bool force = false);
150
151 rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL);
152 rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL);
153
154 nub_thread_t GetContinueThread() const { return m_continue_thread; }
155
156 void SetContinueThread(nub_thread_t tid) { m_continue_thread = tid; }
157
158 nub_thread_t GetCurrentThread() const {
159 if (m_thread == 0 || m_thread == (nub_thread_t)-1)
160 return DNBProcessGetCurrentThread(m_ctx.ProcessID());
161 return m_thread;
162 }
163
164 void SetCurrentThread(nub_thread_t tid) {
165 DNBProcessSetCurrentThread(m_ctx.ProcessID(), tid);
166 m_thread = tid;
167 }
168
169 static void *ThreadFunctionReadRemoteData(void *arg);
170 void StartReadRemoteDataThread();
171 void StopReadRemoteDataThread();
172
173 void NotifyThatProcessStopped(void);
174
175 rnb_err_t HandlePacket_A(const char *p);
176 rnb_err_t HandlePacket_H(const char *p);
177 rnb_err_t HandlePacket_qC(const char *p);
178 rnb_err_t HandlePacket_qRcmd(const char *p);
179 rnb_err_t HandlePacket_qGetPid(const char *p);
180 rnb_err_t HandlePacket_qEcho(const char *p);
181 rnb_err_t HandlePacket_qLaunchSuccess(const char *p);
182 rnb_err_t HandlePacket_qRegisterInfo(const char *p);
183 rnb_err_t HandlePacket_qShlibInfoAddr(const char *p);
184 rnb_err_t HandlePacket_qStepPacketSupported(const char *p);
185 rnb_err_t HandlePacket_qVAttachOrWaitSupported(const char *p);
186 rnb_err_t HandlePacket_qSyncThreadStateSupported(const char *p);
187 rnb_err_t HandlePacket_qThreadInfo(const char *p);
188 rnb_err_t HandlePacket_jThreadExtendedInfo(const char *p);
189 rnb_err_t HandlePacket_jGetLoadedDynamicLibrariesInfos(const char *p);
190 rnb_err_t HandlePacket_jThreadsInfo(const char *p);
191 rnb_err_t HandlePacket_jGetSharedCacheInfo(const char *p);
192 rnb_err_t HandlePacket_qThreadExtraInfo(const char *p);
193 rnb_err_t HandlePacket_qThreadStopInfo(const char *p);
194 rnb_err_t HandlePacket_qHostInfo(const char *p);
195 rnb_err_t HandlePacket_qGDBServerVersion(const char *p);
196 rnb_err_t HandlePacket_qProcessInfo(const char *p);
197 rnb_err_t HandlePacket_qSymbol(const char *p);
198 rnb_err_t HandlePacket_QEnableErrorStrings(const char *p);
199 rnb_err_t HandlePacket_QStartNoAckMode(const char *p);
200 rnb_err_t HandlePacket_QThreadSuffixSupported(const char *p);
201 rnb_err_t HandlePacket_QSetLogging(const char *p);
202 rnb_err_t HandlePacket_QSetIgnoredExceptions(const char *p);
203 rnb_err_t HandlePacket_QSetDisableASLR(const char *p);
204 rnb_err_t HandlePacket_QSetSTDIO(const char *p);
205 rnb_err_t HandlePacket_QSetWorkingDir(const char *p);
206 rnb_err_t HandlePacket_QSetMaxPayloadSize(const char *p);
207 rnb_err_t HandlePacket_QSetMaxPacketSize(const char *p);
208 rnb_err_t HandlePacket_QEnvironment(const char *p);
209 rnb_err_t HandlePacket_QEnvironmentHexEncoded(const char *p);
210 rnb_err_t HandlePacket_QLaunchArch(const char *p);
211 rnb_err_t HandlePacket_QListThreadsInStopReply(const char *p);
212 rnb_err_t HandlePacket_QSyncThreadState(const char *p);
213 rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID(const char *p);
214 rnb_err_t HandlePacket_QSetProcessEvent(const char *p);
215 rnb_err_t HandlePacket_last_signal(const char *p);
216 rnb_err_t HandlePacket_m(const char *p);
217 rnb_err_t HandlePacket_M(const char *p);
218 rnb_err_t HandlePacket_x(const char *p);
219 rnb_err_t HandlePacket_X(const char *p);
220 rnb_err_t HandlePacket_z(const char *p);
221 rnb_err_t HandlePacket_T(const char *p);
222 rnb_err_t HandlePacket_p(const char *p);
223 rnb_err_t HandlePacket_P(const char *p);
224 rnb_err_t HandlePacket_c(const char *p);
225 rnb_err_t HandlePacket_C(const char *p);
226 rnb_err_t HandlePacket_D(const char *p);
227 rnb_err_t HandlePacket_k(const char *p);
228 rnb_err_t HandlePacket_s(const char *p);
229 rnb_err_t HandlePacket_S(const char *p);
230 rnb_err_t HandlePacket_qSupported(const char *p);
231 rnb_err_t HandlePacket_v(const char *p);
232 rnb_err_t HandlePacket_UNIMPLEMENTED(const char *p);
233 rnb_err_t HandlePacket_ILLFORMED(const char *file, int line, const char *p,
234 const char *description);
235 rnb_err_t HandlePacket_AllocateMemory(const char *p);
236 rnb_err_t HandlePacket_DeallocateMemory(const char *p);
237 rnb_err_t HandlePacket_SaveRegisterState(const char *p);
238 rnb_err_t HandlePacket_RestoreRegisterState(const char *p);
239 rnb_err_t HandlePacket_MemoryRegionInfo(const char *p);
240 rnb_err_t HandlePacket_GetProfileData(const char *p);
241 rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
242 rnb_err_t HandlePacket_QEnableCompression(const char *p);
243 rnb_err_t HandlePacket_WatchpointSupportInfo(const char *p);
244 rnb_err_t HandlePacket_qSpeedTest(const char *p);
245 rnb_err_t HandlePacket_qXfer(const char *p);
246 rnb_err_t HandlePacket_stop_process(const char *p);
247 rnb_err_t HandlePacket_QSetDetachOnError(const char *p);
248 rnb_err_t HandlePacket_jGetDyldProcessState(const char *p);
249 rnb_err_t SendStopReplyPacketForThread(nub_thread_t tid);
250 rnb_err_t SendHexEncodedBytePacket(const char *header, const void *buf,
251 size_t buf_len, const char *footer);
252 rnb_err_t SendSTDOUTPacket(char *buf, nub_size_t buf_size);
253 rnb_err_t SendSTDERRPacket(char *buf, nub_size_t buf_size);
254 void FlushSTDIO();
255 void SendAsyncProfileData();
256 rnb_err_t SendAsyncProfileDataPacket(char *buf, nub_size_t buf_size);
257 rnb_err_t SendAsyncJSONPacket(const JSONGenerator::Dictionary &dictionary);
258
259 RNBContext &Context() { return m_ctx; }
260 RNBSocket &Comm() { return m_comm; }
261
262private:
263 RNBRemote(const RNBRemote &) = delete;
264
265protected:
266 rnb_err_t GetCommData();
267 void CommDataReceived(const std::string &data);
268 struct Packet {
269 typedef std::vector<Packet> collection;
270 typedef collection::iterator iterator;
271 typedef collection::const_iterator const_iterator;
272 PacketEnum type;
273 HandlePacketCallback normal; // Function to call when inferior is halted
274 HandlePacketCallback async; // Function to call when inferior is running
275 std::string abbrev;
276 std::string printable_name;
277
278 bool IsPlatformPacket() const {
279 switch (type) {
280 case set_logging_mode:
281 case query_host_info:
282 return true;
283 default:
284 break;
285 }
286 return false;
287 }
288 Packet()
289 : type(invalid_packet), normal(NULL), async(NULL), abbrev(),
290 printable_name() {}
291
292 Packet(PacketEnum in_type, HandlePacketCallback in_normal,
293 HandlePacketCallback in_async, const char *in_abbrev,
294 const char *in_printable_name)
295 : type(in_type), normal(in_normal), async(in_async), abbrev(in_abbrev),
296 printable_name(in_printable_name) {}
297 };
298
299 struct DispatchQueueOffsets {
300 uint16_t dqo_version;
301 uint16_t dqo_label;
302 uint16_t dqo_label_size;
303 uint16_t dqo_flags;
304 uint16_t dqo_flags_size;
305 uint16_t dqo_serialnum;
306 uint16_t dqo_serialnum_size;
307 uint16_t dqo_width;
308 uint16_t dqo_width_size;
309 uint16_t dqo_running;
310 uint16_t dqo_running_size;
311 uint16_t dqo_suspend_cnt; // version 5 and later, starting with Mac OS X
312 // 10.10/iOS 8
313 uint16_t dqo_suspend_cnt_size; // version 5 and later, starting with Mac OS
314 // X 10.10/iOS 8
315 uint16_t dqo_target_queue; // version 5 and later, starting with Mac OS X
316 // 10.10/iOS 8
317 uint16_t dqo_target_queue_size; // version 5 and later, starting with Mac OS
318 // X 10.10/iOS 8
319 uint16_t
320 dqo_priority; // version 5 and later, starting with Mac OS X 10.10/iOS 8
321 uint16_t dqo_priority_size; // version 5 and later, starting with Mac OS X
322 // 10.10/iOS 8
323
324 DispatchQueueOffsets() { Clear(); }
325
326 void Clear() {
327 dqo_version = UINT16_MAX;
328 dqo_label = UINT16_MAX;
329 dqo_label_size = UINT16_MAX;
330 dqo_flags = UINT16_MAX;
331 dqo_flags_size = UINT16_MAX;
332 dqo_serialnum = UINT16_MAX;
333 dqo_serialnum_size = UINT16_MAX;
334 dqo_width = UINT16_MAX;
335 dqo_width_size = UINT16_MAX;
336 dqo_running = UINT16_MAX;
337 dqo_running_size = UINT16_MAX;
338 dqo_suspend_cnt = UINT16_MAX;
339 dqo_suspend_cnt_size = UINT16_MAX;
340 dqo_target_queue = UINT16_MAX;
341 dqo_target_queue_size = UINT16_MAX;
342 dqo_priority = UINT16_MAX;
343 dqo_priority_size = UINT16_MAX;
344 }
345
346 bool IsValid() const { return dqo_version != UINT16_MAX; }
347
348 void GetThreadQueueInfo(nub_process_t pid, nub_addr_t dispatch_qaddr,
349 nub_addr_t &dispatch_queue_t,
350 std::string &queue_name, uint64_t &queue_width,
351 uint64_t &queue_serialnum) const;
352 };
353
354 rnb_err_t GetPacket(std::string &packet_data, RNBRemote::Packet &packet_info,
355 bool wait);
356 rnb_err_t SendPacket(const std::string &);
357 rnb_err_t SendErrorPacket(std::string errcode,
358 const std::string &errmsg = "");
359 std::string CompressString(const std::string &);
360
361 void CreatePacketTable();
362 rnb_err_t GetPacketPayload(std::string &);
363
364 nub_thread_t ExtractThreadIDFromThreadSuffix(const char *p);
365
366 void EnableCompressionNextSendPacket(compression_types);
367
368 compression_types GetCompressionType();
369
370 const DispatchQueueOffsets *GetDispatchQueueOffsets();
371
372 JSONGenerator::ObjectSP
373 GetJSONThreadsInfo(bool threads_with_valid_stop_info_only);
374
375 RNBContext m_ctx; // process context
376 RNBSocket m_comm; // communication port
377 std::string m_arch;
378 nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all
379 nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all
380 std::mutex m_mutex; // Mutex that protects
381 DispatchQueueOffsets m_dispatch_queue_offsets;
382 nub_addr_t m_dispatch_queue_offsets_addr;
383 uint32_t m_qSymbol_index;
384 uint32_t m_packets_recvd;
385 Packet::collection m_packets;
386 std::deque<std::string> m_rx_packets;
387 std::string m_rx_partial_data; // For packets that may come in more than one
388 // batch, anything left over can be left here
389 pthread_t m_rx_pthread;
390 uint32_t
391 m_max_payload_size; // the maximum sized payload we should send to gdb
392 bool m_extended_mode; // are we in extended mode?
393 bool m_noack_mode; // are we in no-ack mode?
394 bool m_thread_suffix_supported; // Set to true if the 'p', 'P', 'g', and 'G'
395 // packets should be prefixed with the thread
396 // ID and colon:
397 // "$pRR;thread:TTTT;" instead of "$pRR"
398 // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
399 // "$g;thread:TTTT" instead of "$g"
400 // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
401 bool m_list_threads_in_stop_reply;
402
403 size_t m_compression_minsize; // only packets larger than this size will be
404 // compressed
405 bool m_enable_compression_next_send_packet;
406
407 compression_types m_compression_mode;
408
409 bool m_enable_error_strings; // Whether we can append asciihex error strings
410 // after Exx error replies
411};
412
413/* We translate the /usr/include/mach/exception_types.h exception types
414 (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
415 in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard
416 coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
417 values in its include/gdb/signals.h. */
418
419#define TARGET_EXC_BAD_ACCESS 0x91
420#define TARGET_EXC_BAD_INSTRUCTION 0x92
421#define TARGET_EXC_ARITHMETIC 0x93
422#define TARGET_EXC_EMULATION 0x94
423#define TARGET_EXC_SOFTWARE 0x95
424#define TARGET_EXC_BREAKPOINT 0x96
425
426/* Generally speaking, you can't assume gdb can receive more than 399 bytes
427 at a time with a random gdb. This bufsize constant is only specifying
428 how many bytes gdb can *receive* from debugserver -- it tells us nothing
429 about how many bytes gdb might try to send in a single packet. */
430#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399
431
432#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBREMOTE_H
433

source code of lldb/tools/debugserver/source/RNBRemote.h