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

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