1 //===-- RNBRemote.cpp -------------------------------------------*- 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 //  Created by Greg Clayton on 12/12/07.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "RNBRemote.h"
15 
16 #include <errno.h>
17 #include <unistd.h>
18 #include <signal.h>
19 #include <mach/exception_types.h>
20 #include <mach-o/loader.h>
21 #include <sys/stat.h>
22 #include <sys/sysctl.h>
23 
24 #if defined (__APPLE__)
25 #include <pthread.h>
26 #include <sched.h>
27 #endif
28 
29 #include "DarwinLogCollector.h"
30 #include "DarwinLogEvent.h"
31 #include "DNB.h"
32 #include "DNBDataRef.h"
33 #include "DNBLog.h"
34 #include "DNBThreadResumeActions.h"
35 #include "JSONGenerator.h"
36 #include "OsLogger.h"
37 #include "RNBContext.h"
38 #include "RNBServices.h"
39 #include "RNBSocket.h"
40 #include "JSON.h"
41 #include "lldb/Utility/StringExtractor.h"
42 #include "MacOSX/Genealogy.h"
43 #include "JSONGenerator.h"
44 
45 #if defined (HAVE_LIBCOMPRESSION)
46 #include <compression.h>
47 #endif
48 
49 #if defined (HAVE_LIBZ)
50 #include <zlib.h>
51 #endif
52 
53 #include <iomanip>
54 #include <sstream>
55 #include <unordered_set>
56 #include <TargetConditionals.h> // for endianness predefines
57 
58 //----------------------------------------------------------------------
59 // constants
60 //----------------------------------------------------------------------
61 
62 static const std::string OS_LOG_EVENTS_KEY_NAME("events");
63 static const std::string JSON_ASYNC_TYPE_KEY_NAME("type");
64 static const DarwinLogEventVector::size_type
65                                           DARWIN_LOG_MAX_EVENTS_PER_PACKET = 10;
66 
67 //----------------------------------------------------------------------
68 // std::iostream formatting macros
69 //----------------------------------------------------------------------
70 #define RAW_HEXBASE     std::setfill('0') << std::hex << std::right
71 #define HEXBASE         '0' << 'x' << RAW_HEXBASE
72 #define RAWHEX8(x)      RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x))
73 #define RAWHEX16        RAW_HEXBASE << std::setw(4)
74 #define RAWHEX32        RAW_HEXBASE << std::setw(8)
75 #define RAWHEX64        RAW_HEXBASE << std::setw(16)
76 #define HEX8(x)         HEXBASE << std::setw(2) << ((uint32_t)(x))
77 #define HEX16           HEXBASE << std::setw(4)
78 #define HEX32           HEXBASE << std::setw(8)
79 #define HEX64           HEXBASE << std::setw(16)
80 #define RAW_HEX(x)      RAW_HEXBASE << std::setw(sizeof(x)*2) << (x)
81 #define HEX(x)          HEXBASE << std::setw(sizeof(x)*2) << (x)
82 #define RAWHEX_SIZE(x, sz)  RAW_HEXBASE << std::setw((sz)) << (x)
83 #define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x)
84 #define STRING_WIDTH(w) std::setfill(' ') << std::setw(w)
85 #define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right
86 #define DECIMAL         std::dec << std::setfill(' ')
87 #define DECIMAL_WIDTH(w) DECIMAL << std::setw(w)
88 #define FLOAT(n, d)     std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed
89 #define INDENT_WITH_SPACES(iword_idx)   std::setfill(' ') << std::setw((iword_idx)) << ""
90 #define INDENT_WITH_TABS(iword_idx)     std::setfill('\t') << std::setw((iword_idx)) << ""
91 // Class to handle communications via gdb remote protocol.
92 
93 //----------------------------------------------------------------------
94 // Prototypes
95 //----------------------------------------------------------------------
96 
97 static std::string
98 binary_encode_string (const std::string &s);
99 
100 //----------------------------------------------------------------------
101 // Decode a single hex character and return the hex value as a number or
102 // -1 if "ch" is not a hex character.
103 //----------------------------------------------------------------------
104 static inline int
105 xdigit_to_sint (char ch)
106 {
107     if (ch >= 'a' && ch <= 'f')
108         return 10 + ch - 'a';
109     if (ch >= 'A' && ch <= 'F')
110         return 10 + ch - 'A';
111     if (ch >= '0' && ch <= '9')
112         return ch - '0';
113     return -1;
114 }
115 
116 //----------------------------------------------------------------------
117 // Decode a single hex ASCII byte. Return -1 on failure, a value 0-255
118 // on success.
119 //----------------------------------------------------------------------
120 static inline int
121 decoded_hex_ascii_char(const char *p)
122 {
123     const int hi_nibble = xdigit_to_sint(p[0]);
124     if (hi_nibble == -1)
125         return -1;
126     const int lo_nibble = xdigit_to_sint(p[1]);
127     if (lo_nibble == -1)
128         return -1;
129     return (uint8_t)((hi_nibble << 4) + lo_nibble);
130 }
131 
132 //----------------------------------------------------------------------
133 // Decode a hex ASCII string back into a string
134 //----------------------------------------------------------------------
135 static std::string
136 decode_hex_ascii_string(const char *p, uint32_t max_length = UINT32_MAX)
137 {
138     std::string arg;
139     if (p)
140     {
141         for (const char *c = p; ((c - p)/2) < max_length; c += 2)
142         {
143             int ch = decoded_hex_ascii_char(c);
144             if (ch == -1)
145                 break;
146             else
147                 arg.push_back(ch);
148         }
149     }
150     return arg;
151 }
152 
153 uint64_t
154 decode_uint64 (const char *p, int base, char **end = nullptr, uint64_t fail_value = 0)
155 {
156     nub_addr_t addr = strtoull (p, end, 16);
157     if (addr == 0 && errno != 0)
158         return fail_value;
159     return addr;
160 }
161 
162 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
163 
164 #if defined (__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000)
165 // from System.framework/Versions/B/PrivateHeaders/sys/codesign.h
166 extern "C" {
167 #define CS_OPS_STATUS           0       /* return status */
168 #define CS_RESTRICT             0x0000800       /* tell dyld to treat restricted */
169 int csops(pid_t pid, unsigned int  ops, void * useraddr, size_t usersize);
170 
171 // from rootless.h
172 bool rootless_allows_task_for_pid (pid_t pid);
173 
174 // from sys/csr.h
175 typedef uint32_t csr_config_t;
176 #define CSR_ALLOW_TASK_FOR_PID            (1 << 2)
177 int csr_check(csr_config_t mask);
178 }
179 #endif
180 
181 RNBRemote::RNBRemote () :
182     m_ctx (),
183     m_comm (),
184     m_arch (),
185     m_continue_thread(-1),
186     m_thread(-1),
187     m_mutex(),
188     m_dispatch_queue_offsets (),
189     m_dispatch_queue_offsets_addr (INVALID_NUB_ADDRESS),
190     m_qSymbol_index (UINT32_MAX),
191     m_packets_recvd(0),
192     m_packets(),
193     m_rx_packets(),
194     m_rx_partial_data(),
195     m_rx_pthread(0),
196     m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
197     m_extended_mode(false),
198     m_noack_mode(false),
199     m_thread_suffix_supported (false),
200     m_list_threads_in_stop_reply (false),
201     m_compression_minsize (384),
202     m_enable_compression_next_send_packet (false),
203     m_compression_mode (compression_types::none)
204 {
205     DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
206     CreatePacketTable ();
207 }
208 
209 
210 RNBRemote::~RNBRemote()
211 {
212     DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
213     StopReadRemoteDataThread();
214 }
215 
216 void
217 RNBRemote::CreatePacketTable  ()
218 {
219     // Step required to add new packets:
220     // 1 - Add new enumeration to RNBRemote::PacketEnum
221     // 2 - Create the RNBRemote::HandlePacket_ function if a new function is needed
222     // 3 - Register the Packet definition with any needed callbacks in this function
223     //          - If no response is needed for a command, then use NULL for the normal callback
224     //          - If the packet is not supported while the target is running, use NULL for the async callback
225     // 4 - If the packet is a standard packet (starts with a '$' character
226     //      followed by the payload and then '#' and checksum, then you are done
227     //      else go on to step 5
228     // 5 - if the packet is a fixed length packet:
229     //      - modify the switch statement for the first character in the payload
230     //        in RNBRemote::CommDataReceived so it doesn't reject the new packet
231     //        type as invalid
232     //      - modify the switch statement for the first character in the payload
233     //        in RNBRemote::GetPacketPayload and make sure the payload of the packet
234     //        is returned correctly
235 
236     std::vector <Packet> &t = m_packets;
237     t.push_back (Packet (ack,                           NULL,                                   NULL, "+", "ACK"));
238     t.push_back (Packet (nack,                          NULL,                                   NULL, "-", "!ACK"));
239     t.push_back (Packet (read_memory,                   &RNBRemote::HandlePacket_m,             NULL, "m", "Read memory"));
240     t.push_back (Packet (read_register,                 &RNBRemote::HandlePacket_p,             NULL, "p", "Read one register"));
241     t.push_back (Packet (read_general_regs,             &RNBRemote::HandlePacket_g,             NULL, "g", "Read registers"));
242     t.push_back (Packet (write_memory,                  &RNBRemote::HandlePacket_M,             NULL, "M", "Write memory"));
243     t.push_back (Packet (write_register,                &RNBRemote::HandlePacket_P,             NULL, "P", "Write one register"));
244     t.push_back (Packet (write_general_regs,            &RNBRemote::HandlePacket_G,             NULL, "G", "Write registers"));
245     t.push_back (Packet (insert_mem_bp,                 &RNBRemote::HandlePacket_z,             NULL, "Z0", "Insert memory breakpoint"));
246     t.push_back (Packet (remove_mem_bp,                 &RNBRemote::HandlePacket_z,             NULL, "z0", "Remove memory breakpoint"));
247     t.push_back (Packet (single_step,                   &RNBRemote::HandlePacket_s,             NULL, "s", "Single step"));
248     t.push_back (Packet (cont,                          &RNBRemote::HandlePacket_c,             NULL, "c", "continue"));
249     t.push_back (Packet (single_step_with_sig,          &RNBRemote::HandlePacket_S,             NULL, "S", "Single step with signal"));
250     t.push_back (Packet (set_thread,                    &RNBRemote::HandlePacket_H,             NULL, "H", "Set thread"));
251     t.push_back (Packet (halt,                          &RNBRemote::HandlePacket_last_signal,   &RNBRemote::HandlePacket_stop_process, "\x03", "^C"));
252 //  t.push_back (Packet (use_extended_mode,             &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode"));
253     t.push_back (Packet (why_halted,                    &RNBRemote::HandlePacket_last_signal,   NULL, "?", "Why did target halt"));
254     t.push_back (Packet (set_argv,                      &RNBRemote::HandlePacket_A,             NULL, "A", "Set argv"));
255 //  t.push_back (Packet (set_bp,                        &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear breakpoint"));
256     t.push_back (Packet (continue_with_sig,             &RNBRemote::HandlePacket_C,             NULL, "C", "Continue with signal"));
257     t.push_back (Packet (detach,                        &RNBRemote::HandlePacket_D,             NULL, "D", "Detach gdb from remote system"));
258 //  t.push_back (Packet (step_inferior_one_cycle,       &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one clock cycle"));
259 //  t.push_back (Packet (signal_and_step_inf_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then step one clock cycle"));
260     t.push_back (Packet (kill,                          &RNBRemote::HandlePacket_k,             NULL, "k", "Kill"));
261 //  t.push_back (Packet (restart,                       &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior"));
262 //  t.push_back (Packet (search_mem_backwards,          &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards"));
263     t.push_back (Packet (thread_alive_p,                &RNBRemote::HandlePacket_T,             NULL, "T", "Is thread alive"));
264     t.push_back (Packet (query_supported_features,      &RNBRemote::HandlePacket_qSupported,    NULL, "qSupported", "Query about supported features"));
265     t.push_back (Packet (vattach,                       &RNBRemote::HandlePacket_v,             NULL, "vAttach", "Attach to a new process"));
266     t.push_back (Packet (vattachwait,                   &RNBRemote::HandlePacket_v,             NULL, "vAttachWait", "Wait for a process to start up then attach to it"));
267     t.push_back (Packet (vattachorwait,                 &RNBRemote::HandlePacket_v,             NULL, "vAttachOrWait", "Attach to the process or if it doesn't exist, wait for the process to start up then attach to it"));
268     t.push_back (Packet (vattachname,                   &RNBRemote::HandlePacket_v,             NULL, "vAttachName", "Attach to an existing process by name"));
269     t.push_back (Packet (vcont_list_actions,            &RNBRemote::HandlePacket_v,             NULL, "vCont;", "Verbose resume with thread actions"));
270     t.push_back (Packet (vcont_list_actions,            &RNBRemote::HandlePacket_v,             NULL, "vCont?", "List valid continue-with-thread-actions actions"));
271   t.push_back (Packet (read_data_from_memory,           &RNBRemote::HandlePacket_x,             NULL, "x", "Read data from memory"));
272   t.push_back (Packet (write_data_to_memory,            &RNBRemote::HandlePacket_X,             NULL, "X", "Write data to memory"));
273 //  t.push_back (Packet (insert_hardware_bp,            &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware breakpoint"));
274 //  t.push_back (Packet (remove_hardware_bp,            &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware breakpoint"));
275     t.push_back (Packet (insert_write_watch_bp,         &RNBRemote::HandlePacket_z,             NULL, "Z2", "Insert write watchpoint"));
276     t.push_back (Packet (remove_write_watch_bp,         &RNBRemote::HandlePacket_z,             NULL, "z2", "Remove write watchpoint"));
277     t.push_back (Packet (insert_read_watch_bp,          &RNBRemote::HandlePacket_z,             NULL, "Z3", "Insert read watchpoint"));
278     t.push_back (Packet (remove_read_watch_bp,          &RNBRemote::HandlePacket_z,             NULL, "z3", "Remove read watchpoint"));
279     t.push_back (Packet (insert_access_watch_bp,        &RNBRemote::HandlePacket_z,             NULL, "Z4", "Insert access watchpoint"));
280     t.push_back (Packet (remove_access_watch_bp,        &RNBRemote::HandlePacket_z,             NULL, "z4", "Remove access watchpoint"));
281     t.push_back (Packet (query_monitor,                 &RNBRemote::HandlePacket_qRcmd,          NULL, "qRcmd", "Monitor command"));
282     t.push_back (Packet (query_current_thread_id,       &RNBRemote::HandlePacket_qC,            NULL, "qC", "Query current thread ID"));
283     t.push_back (Packet (query_echo,                    &RNBRemote::HandlePacket_qEcho,         NULL, "qEcho:", "Echo the packet back to allow the debugger to sync up with this server"));
284     t.push_back (Packet (query_get_pid,                 &RNBRemote::HandlePacket_qGetPid,       NULL, "qGetPid", "Query process id"));
285     t.push_back (Packet (query_thread_ids_first,        &RNBRemote::HandlePacket_qThreadInfo,   NULL, "qfThreadInfo", "Get list of active threads (first req)"));
286     t.push_back (Packet (query_thread_ids_subsequent,   &RNBRemote::HandlePacket_qThreadInfo,   NULL, "qsThreadInfo", "Get list of active threads (subsequent req)"));
287     // APPLE LOCAL: qThreadStopInfo
288     // syntax: qThreadStopInfoTTTT
289     //  TTTT is hex thread ID
290     t.push_back (Packet (query_thread_stop_info,        &RNBRemote::HandlePacket_qThreadStopInfo,   NULL, "qThreadStopInfo", "Get detailed info on why the specified thread stopped"));
291     t.push_back (Packet (query_thread_extra_info,       &RNBRemote::HandlePacket_qThreadExtraInfo,NULL, "qThreadExtraInfo", "Get printable status of a thread"));
292 //  t.push_back (Packet (query_image_offsets,           &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset of loaded program"));
293     t.push_back (Packet (query_launch_success,          &RNBRemote::HandlePacket_qLaunchSuccess,NULL, "qLaunchSuccess", "Report the success or failure of the launch attempt"));
294     t.push_back (Packet (query_register_info,           &RNBRemote::HandlePacket_qRegisterInfo, NULL, "qRegisterInfo", "Dynamically discover remote register context information."));
295     t.push_back (Packet (query_shlib_notify_info_addr,  &RNBRemote::HandlePacket_qShlibInfoAddr,NULL, "qShlibInfoAddr", "Returns the address that contains info needed for getting shared library notifications"));
296     t.push_back (Packet (query_step_packet_supported,   &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported."));
297     t.push_back (Packet (query_vattachorwait_supported, &RNBRemote::HandlePacket_qVAttachOrWaitSupported,NULL, "qVAttachOrWaitSupported", "Replys with OK if the 'vAttachOrWait' packet is supported."));
298     t.push_back (Packet (query_sync_thread_state_supported, &RNBRemote::HandlePacket_qSyncThreadStateSupported,NULL, "qSyncThreadStateSupported", "Replys with OK if the 'QSyncThreadState:' packet is supported."));
299     t.push_back (Packet (query_host_info,               &RNBRemote::HandlePacket_qHostInfo              , NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
300     t.push_back (Packet (query_gdb_server_version,      &RNBRemote::HandlePacket_qGDBServerVersion      , NULL, "qGDBServerVersion", "Replies with multiple 'key:value;' tuples appended to each other."));
301     t.push_back (Packet (query_process_info,            &RNBRemote::HandlePacket_qProcessInfo           , NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
302     t.push_back (Packet (query_symbol_lookup,           &RNBRemote::HandlePacket_qSymbol                , NULL, "qSymbol:", "Notify that host debugger is ready to do symbol lookups"));
303     t.push_back (Packet (json_query_thread_extended_info,&RNBRemote::HandlePacket_jThreadExtendedInfo   , NULL, "jThreadExtendedInfo", "Replies with JSON data of thread extended information."));
304     t.push_back (Packet (json_query_get_loaded_dynamic_libraries_infos,          &RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos,     NULL, "jGetLoadedDynamicLibrariesInfos", "Replies with JSON data of all the shared libraries loaded in this process."));
305     t.push_back (Packet (json_query_threads_info,       &RNBRemote::HandlePacket_jThreadsInfo           , NULL, "jThreadsInfo", "Replies with JSON data with information about all threads."));
306     t.push_back (Packet (json_query_get_shared_cache_info,          &RNBRemote::HandlePacket_jGetSharedCacheInfo,     NULL, "jGetSharedCacheInfo", "Replies with JSON data about the location and uuid of the shared cache in the inferior process."));
307     t.push_back (Packet (start_noack_mode,              &RNBRemote::HandlePacket_QStartNoAckMode        , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
308     t.push_back (Packet (prefix_reg_packets_with_tid,   &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specific packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
309     t.push_back (Packet (set_logging_mode,              &RNBRemote::HandlePacket_QSetLogging            , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
310     t.push_back (Packet (set_max_packet_size,           &RNBRemote::HandlePacket_QSetMaxPacketSize      , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
311     t.push_back (Packet (set_max_payload_size,          &RNBRemote::HandlePacket_QSetMaxPayloadSize     , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
312     t.push_back (Packet (set_environment_variable,      &RNBRemote::HandlePacket_QEnvironment           , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
313     t.push_back (Packet (set_environment_variable_hex,  &RNBRemote::HandlePacket_QEnvironmentHexEncoded , NULL, "QEnvironmentHexEncoded:", "Add an environment variable to the inferior's environment"));
314     t.push_back (Packet (set_launch_arch,               &RNBRemote::HandlePacket_QLaunchArch            , NULL, "QLaunchArch:", "Set the architecture to use when launching a process for hosts that can run multiple architecture slices from universal files."));
315     t.push_back (Packet (set_disable_aslr,              &RNBRemote::HandlePacket_QSetDisableASLR        , NULL, "QSetDisableASLR:", "Set whether to disable ASLR when launching the process with the set argv ('A') packet"));
316     t.push_back (Packet (set_stdin,                     &RNBRemote::HandlePacket_QSetSTDIO              , NULL, "QSetSTDIN:", "Set the standard input for a process to be launched with the 'A' packet"));
317     t.push_back (Packet (set_stdout,                    &RNBRemote::HandlePacket_QSetSTDIO              , NULL, "QSetSTDOUT:", "Set the standard output for a process to be launched with the 'A' packet"));
318     t.push_back (Packet (set_stderr,                    &RNBRemote::HandlePacket_QSetSTDIO              , NULL, "QSetSTDERR:", "Set the standard error for a process to be launched with the 'A' packet"));
319     t.push_back (Packet (set_working_dir,               &RNBRemote::HandlePacket_QSetWorkingDir         , NULL, "QSetWorkingDir:", "Set the working directory for a process to be launched with the 'A' packet"));
320     t.push_back (Packet (set_list_threads_in_stop_reply,&RNBRemote::HandlePacket_QListThreadsInStopReply , NULL, "QListThreadsInStopReply", "Set if the 'threads' key should be added to the stop reply packets with a list of all thread IDs."));
321     t.push_back (Packet (sync_thread_state,             &RNBRemote::HandlePacket_QSyncThreadState , NULL, "QSyncThreadState:", "Do whatever is necessary to make sure 'thread' is in a safe state to call functions on."));
322 //  t.push_back (Packet (pass_signals_to_inferior,      &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
323     t.push_back (Packet (allocate_memory,               &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
324     t.push_back (Packet (deallocate_memory,             &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
325     t.push_back (Packet (save_register_state,           &RNBRemote::HandlePacket_SaveRegisterState, NULL, "QSaveRegisterState", "Save the register state for the current thread and return a decimal save ID."));
326     t.push_back (Packet (restore_register_state,        &RNBRemote::HandlePacket_RestoreRegisterState, NULL, "QRestoreRegisterState:", "Restore the register state given a save ID previously returned from a call to QSaveRegisterState."));
327     t.push_back (Packet (memory_region_info,            &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, "qMemoryRegionInfo", "Return size and attributes of a memory region that contains the given address"));
328     t.push_back (Packet (get_profile_data,              &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target."));
329     t.push_back (Packet (set_enable_profiling,          &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "Enable or disable the profiling of current target."));
330     t.push_back (Packet (enable_compression,            &RNBRemote::HandlePacket_QEnableCompression, NULL, "QEnableCompression:", "Enable compression for the remainder of the connection"));
331     t.push_back (Packet (watchpoint_support_info,       &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints"));
332     t.push_back (Packet (set_process_event,             &RNBRemote::HandlePacket_QSetProcessEvent, NULL, "QSetProcessEvent:", "Set a process event, to be passed to the process, can be set before the process is started, or after."));
333     t.push_back (Packet (set_detach_on_error,           &RNBRemote::HandlePacket_QSetDetachOnError, NULL, "QSetDetachOnError:", "Set whether debugserver will detach (1) or kill (0) from the process it is controlling if it loses connection to lldb."));
334     t.push_back (Packet (speed_test,                    &RNBRemote::HandlePacket_qSpeedTest, NULL, "qSpeedTest:", "Test the maximum speed at which packet can be sent/received."));
335     t.push_back (Packet (query_transfer,                &RNBRemote::HandlePacket_qXfer, NULL, "qXfer:", "Support the qXfer packet."));
336     t.push_back (Packet (query_supported_async_json_packets, &RNBRemote::HandlePacket_qStructuredDataPlugins, NULL, "qStructuredDataPlugins", "Query for the structured data plugins supported by the remote."));
337     t.push_back (Packet (configure_darwin_log,          &RNBRemote::HandlePacket_QConfigureDarwinLog, NULL, "QConfigureDarwinLog:", "Configure the DarwinLog structured data plugin support."));
338 }
339 
340 void
341 RNBRemote::FlushSTDIO ()
342 {
343     if (m_ctx.HasValidProcessID())
344     {
345         nub_process_t pid = m_ctx.ProcessID();
346         char buf[256];
347         nub_size_t count;
348         do
349         {
350             count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf));
351             if (count > 0)
352             {
353                 SendSTDOUTPacket (buf, count);
354             }
355         } while (count > 0);
356 
357         do
358         {
359             count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf));
360             if (count > 0)
361             {
362                 SendSTDERRPacket (buf, count);
363             }
364         } while (count > 0);
365     }
366 }
367 
368 void
369 RNBRemote::SendAsyncProfileData ()
370 {
371     if (m_ctx.HasValidProcessID())
372     {
373         nub_process_t pid = m_ctx.ProcessID();
374         char buf[1024];
375         nub_size_t count;
376         do
377         {
378             count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf));
379             if (count > 0)
380             {
381                 SendAsyncProfileDataPacket (buf, count);
382             }
383         } while (count > 0);
384     }
385 }
386 
387 void
388 RNBRemote::SendAsyncDarwinLogData ()
389 {
390     DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): enter",
391                      __FUNCTION__);
392 
393     if (!m_ctx.HasValidProcessID())
394     {
395         DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): ignoring due to"
396                          "invalid process id", __FUNCTION__);
397         return;
398     }
399 
400     nub_process_t pid = m_ctx.ProcessID();
401     DarwinLogEventVector::size_type entry_count = 0;
402 
403     // NOTE: the current looping structure here does nothing
404     // to guarantee that we can send off async packets faster
405     // than we generate them.  It will keep sending as long
406     // as there's data to send.
407     do
408     {
409         DarwinLogEventVector events =
410             DNBProcessGetAvailableDarwinLogEvents(pid);
411         entry_count = events.size();
412 
413         DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): outer loop enter",
414                          __FUNCTION__);
415 
416         for (DarwinLogEventVector::size_type base_entry = 0;
417              base_entry < entry_count;
418              base_entry += DARWIN_LOG_MAX_EVENTS_PER_PACKET)
419         {
420             DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): inner loop enter",
421                              __FUNCTION__);
422 
423             // We limit the total number of entries we pack
424             // into a single JSON async packet just so it
425             // doesn't get too large.
426             JSONGenerator::Dictionary async_dictionary;
427 
428             // Specify the type of the JSON async data we're sending.
429             async_dictionary.AddStringItem(
430                 JSON_ASYNC_TYPE_KEY_NAME, "DarwinLog");
431 
432             // Create an array entry in the dictionary to hold all
433             // the events going in this packet.
434             JSONGenerator::ArraySP events_array(new JSONGenerator::Array());
435             async_dictionary.AddItem(OS_LOG_EVENTS_KEY_NAME, events_array);
436 
437             // We bundle up to DARWIN_LOG_MAX_EVENTS_PER_PACKET events in
438             // a single packet.
439             const auto inner_loop_bound =
440                 std::min(base_entry + DARWIN_LOG_MAX_EVENTS_PER_PACKET,
441                          entry_count);
442             for (DarwinLogEventVector::size_type i = base_entry;
443                  i < inner_loop_bound; ++i)
444             {
445                 DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): adding "
446                                  "entry index %lu to the JSON packet",
447                                  __FUNCTION__, i);
448                 events_array->AddItem(events[i]);
449             }
450 
451             // Send off the packet.
452             DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): sending JSON "
453                              "packet, %lu entries remain", __FUNCTION__,
454                              entry_count - inner_loop_bound);
455             SendAsyncJSONPacket(async_dictionary);
456         }
457 
458         DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): outer loop exit",
459                          __FUNCTION__);
460 
461     } while (entry_count > 0);
462 
463     DNBLogThreadedIf(LOG_DARWIN_LOG, "RNBRemote::%s(): exit",
464                      __PRETTY_FUNCTION__);
465 }
466 
467 rnb_err_t
468 RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer)
469 {
470     std::ostringstream packet_sstrm;
471     // Append the header cstr if there was one
472     if (header && header[0])
473         packet_sstrm << header;
474     nub_size_t i;
475     const uint8_t *ubuf8 = (const uint8_t *)buf;
476     for (i=0; i<buf_len; i++)
477     {
478         packet_sstrm << RAWHEX8(ubuf8[i]);
479     }
480     // Append the footer cstr if there was one
481     if (footer && footer[0])
482         packet_sstrm << footer;
483 
484     return SendPacket(packet_sstrm.str());
485 }
486 
487 rnb_err_t
488 RNBRemote::SendSTDOUTPacket (char *buf, nub_size_t buf_size)
489 {
490     if (buf_size == 0)
491         return rnb_success;
492     return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
493 }
494 
495 rnb_err_t
496 RNBRemote::SendSTDERRPacket (char *buf, nub_size_t buf_size)
497 {
498     if (buf_size == 0)
499         return rnb_success;
500     return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
501 }
502 
503 // This makes use of asynchronous bit 'A' in the gdb remote protocol.
504 rnb_err_t
505 RNBRemote::SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size)
506 {
507     if (buf_size == 0)
508         return rnb_success;
509 
510     std::string packet("A");
511     packet.append(buf, buf_size);
512     return SendPacket(packet);
513 }
514 
515 rnb_err_t
516 RNBRemote::SendAsyncJSONPacket(const JSONGenerator::Dictionary &dictionary)
517 {
518     std::ostringstream stream;
519     // We're choosing something that is easy to spot if we somehow get one
520     // of these coming out at the wrong time (i.e. when the remote side
521     // is not waiting for a process control completion response).
522     stream << "JSON-async:";
523     dictionary.Dump(stream);
524     const std::string payload = binary_encode_string(stream.str());
525     return SendPacket(payload);
526 }
527 
528 // Given a std::string packet contents to send, possibly encode/compress it.
529 // If compression is enabled, the returned std::string will be in one of two
530 // forms:
531 //
532 //    N<original packet contents uncompressed>
533 //    C<size of original decompressed packet>:<packet compressed with the requested compression scheme>
534 //
535 // If compression is not requested, the original packet contents are returned
536 
537 std::string
538 RNBRemote::CompressString (const std::string &orig)
539 {
540     std::string compressed;
541     compression_types compression_type = GetCompressionType();
542     if (compression_type != compression_types::none)
543     {
544         bool compress_this_packet = false;
545 
546         if (orig.size() > m_compression_minsize)
547         {
548             compress_this_packet = true;
549         }
550 
551         if (compress_this_packet)
552         {
553             const size_t encoded_data_buf_size = orig.size() + 128;
554             std::vector<uint8_t> encoded_data (encoded_data_buf_size);
555             size_t compressed_size = 0;
556 
557 #if defined (HAVE_LIBCOMPRESSION)
558             if (compression_decode_buffer && compression_type == compression_types::lz4)
559             {
560                 compressed_size = compression_encode_buffer (encoded_data.data(),
561                                                              encoded_data_buf_size,
562                                                              (uint8_t*) orig.c_str(),
563                                                              orig.size(),
564                                                              nullptr,
565                                                              COMPRESSION_LZ4_RAW);
566             }
567             if (compression_decode_buffer && compression_type == compression_types::zlib_deflate)
568             {
569                 compressed_size = compression_encode_buffer (encoded_data.data(),
570                                                              encoded_data_buf_size,
571                                                              (uint8_t*) orig.c_str(),
572                                                              orig.size(),
573                                                              nullptr,
574                                                              COMPRESSION_ZLIB);
575             }
576             if (compression_decode_buffer && compression_type == compression_types::lzma)
577             {
578                 compressed_size = compression_encode_buffer (encoded_data.data(),
579                                                              encoded_data_buf_size,
580                                                              (uint8_t*) orig.c_str(),
581                                                              orig.size(),
582                                                              nullptr,
583                                                              COMPRESSION_LZMA);
584             }
585             if (compression_decode_buffer && compression_type == compression_types::lzfse)
586             {
587                 compressed_size = compression_encode_buffer (encoded_data.data(),
588                                                              encoded_data_buf_size,
589                                                              (uint8_t*) orig.c_str(),
590                                                              orig.size(),
591                                                              nullptr,
592                                                              COMPRESSION_LZFSE);
593             }
594 #endif
595 
596 #if defined (HAVE_LIBZ)
597             if (compressed_size == 0 && compression_type == compression_types::zlib_deflate)
598             {
599                 z_stream stream;
600                 memset (&stream, 0, sizeof (z_stream));
601                 stream.next_in = (Bytef *) orig.c_str();
602                 stream.avail_in = (uInt) orig.size();
603                 stream.next_out = (Bytef *) encoded_data.data();
604                 stream.avail_out = (uInt) encoded_data_buf_size;
605                 stream.zalloc = Z_NULL;
606                 stream.zfree = Z_NULL;
607                 stream.opaque = Z_NULL;
608                 deflateInit2 (&stream, 5, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
609                 int compress_status = deflate (&stream, Z_FINISH);
610                 deflateEnd (&stream);
611                 if (compress_status == Z_STREAM_END && stream.total_out > 0)
612                 {
613                     compressed_size = stream.total_out;
614                 }
615             }
616 #endif
617 
618             if (compressed_size > 0)
619             {
620                 compressed.clear ();
621                 compressed.reserve (compressed_size);
622                 compressed = "C";
623                 char numbuf[16];
624                 snprintf (numbuf, sizeof (numbuf), "%zu:", orig.size());
625                 numbuf[sizeof (numbuf) - 1] = '\0';
626                 compressed.append (numbuf);
627 
628                 for (size_t i = 0; i < compressed_size; i++)
629                 {
630                     uint8_t byte = encoded_data[i];
631                     if (byte == '#' || byte == '$' || byte == '}' || byte == '*' || byte == '\0')
632                     {
633                         compressed.push_back (0x7d);
634                         compressed.push_back (byte ^ 0x20);
635                     }
636                     else
637                     {
638                         compressed.push_back (byte);
639                     }
640                 }
641             }
642             else
643             {
644                 compressed = "N" + orig;
645             }
646         }
647         else
648         {
649             compressed = "N" + orig;
650         }
651     }
652     else
653     {
654         compressed = orig;
655     }
656 
657     return compressed;
658 }
659 
660 rnb_err_t
661 RNBRemote::SendPacket (const std::string &s)
662 {
663     DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, s.c_str());
664 
665     std::string s_compressed = CompressString (s);
666 
667     std::string sendpacket = "$" + s_compressed + "#";
668     int cksum = 0;
669     char hexbuf[5];
670 
671     if (m_noack_mode)
672     {
673         sendpacket += "00";
674     }
675     else
676     {
677         for (size_t i = 0; i != s_compressed.size(); ++i)
678             cksum += s_compressed[i];
679         snprintf (hexbuf, sizeof hexbuf, "%02x", cksum & 0xff);
680         sendpacket += hexbuf;
681     }
682 
683     rnb_err_t err = m_comm.Write (sendpacket.c_str(), sendpacket.size());
684     if (err != rnb_success)
685         return err;
686 
687     if (m_noack_mode)
688         return rnb_success;
689 
690     std::string reply;
691     RNBRemote::Packet packet;
692     err = GetPacket (reply, packet, true);
693 
694     if (err != rnb_success)
695     {
696         DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s (%s) got error trying to get reply...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, sendpacket.c_str());
697         return err;
698     }
699 
700     DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) got reply: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, sendpacket.c_str(), reply.c_str());
701 
702     if (packet.type == ack)
703         return rnb_success;
704 
705     // Should we try to resend the packet at this layer?
706     //  if (packet.command == nack)
707     return rnb_err;
708 }
709 
710 /* Get a packet via gdb remote protocol.
711  Strip off the prefix/suffix, verify the checksum to make sure
712  a valid packet was received, send an ACK if they match.  */
713 
714 rnb_err_t
715 RNBRemote::GetPacketPayload (std::string &return_packet)
716 {
717     //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
718 
719     PThreadMutex::Locker locker(m_mutex);
720     if (m_rx_packets.empty())
721     {
722         // Only reset the remote command available event if we have no more packets
723         m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available );
724         //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
725         return rnb_err;
726     }
727 
728     //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, m_rx_packets.size());
729     return_packet.swap(m_rx_packets.front());
730     m_rx_packets.pop_front();
731     locker.Reset(); // Release our lock on the mutex
732 
733     if (m_rx_packets.empty())
734     {
735         // Reset the remote command available event if we have no more packets
736         m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available );
737     }
738 
739     //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
740 
741     switch (return_packet[0])
742     {
743         case '+':
744         case '-':
745         case '\x03':
746             break;
747 
748         case '$':
749         {
750             long packet_checksum = 0;
751             if (!m_noack_mode)
752             {
753                 for (size_t i = return_packet.size() - 2; i < return_packet.size(); ++i)
754                 {
755                     char checksum_char = tolower (return_packet[i]);
756                     if (!isxdigit (checksum_char))
757                     {
758                         m_comm.Write ("-", 1);
759                         DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s error: packet with invalid checksum characters: %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
760                         return rnb_err;
761                     }
762                 }
763                 packet_checksum = strtol (&return_packet[return_packet.size() - 2], NULL, 16);
764             }
765 
766             return_packet.erase(0,1);           // Strip the leading '$'
767             return_packet.erase(return_packet.size() - 3);// Strip the #XX checksum
768 
769             if (!m_noack_mode)
770             {
771                 // Compute the checksum
772                 int computed_checksum = 0;
773                 for (std::string::iterator it = return_packet.begin ();
774                      it != return_packet.end ();
775                      ++it)
776                 {
777                     computed_checksum += *it;
778                 }
779 
780                 if (packet_checksum == (computed_checksum & 0xff))
781                 {
782                     //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
783                     m_comm.Write ("+", 1);
784                 }
785                 else
786                 {
787                     DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: packet checksum mismatch  (0x%2.2lx != 0x%2.2x))",
788                                       (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
789                                       __FUNCTION__,
790                                       return_packet.c_str(),
791                                       packet_checksum,
792                                       computed_checksum);
793                     m_comm.Write ("-", 1);
794                     return rnb_err;
795                 }
796             }
797         }
798         break;
799 
800         default:
801             DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s tossing unexpected packet???? %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
802             if (!m_noack_mode)
803                 m_comm.Write ("-", 1);
804             return rnb_err;
805     }
806 
807     return rnb_success;
808 }
809 
810 rnb_err_t
811 RNBRemote::HandlePacket_UNIMPLEMENTED (const char* p)
812 {
813     DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p ? p : "NULL");
814     return SendPacket ("");
815 }
816 
817 rnb_err_t
818 RNBRemote::HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description)
819 {
820     DNBLogThreadedIf (LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, line, __FUNCTION__, p);
821     return SendPacket ("E03");
822 }
823 
824 rnb_err_t
825 RNBRemote::GetPacket (std::string &packet_payload, RNBRemote::Packet& packet_info, bool wait)
826 {
827     std::string payload;
828     rnb_err_t err = GetPacketPayload (payload);
829     if (err != rnb_success)
830     {
831         PThreadEvent& events = m_ctx.Events();
832         nub_event_t set_events = events.GetEventBits();
833         // TODO: add timeout version of GetPacket?? We would then need to pass
834         // that timeout value along to DNBProcessTimedWaitForEvent.
835         if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0))
836             return err;
837 
838         const nub_event_t events_to_wait_for = RNBContext::event_read_packet_available | RNBContext::event_read_thread_exiting;
839 
840         while ((set_events = events.WaitForSetEvents(events_to_wait_for)) != 0)
841         {
842             if (set_events & RNBContext::event_read_packet_available)
843             {
844                 // Try the queue again now that we got an event
845                 err = GetPacketPayload (payload);
846                 if (err == rnb_success)
847                     break;
848             }
849 
850             if (set_events & RNBContext::event_read_thread_exiting)
851                 err = rnb_not_connected;
852 
853             if (err == rnb_not_connected)
854                 return err;
855 
856         } while (err == rnb_err);
857 
858         if (set_events == 0)
859             err = rnb_not_connected;
860     }
861 
862     if (err == rnb_success)
863     {
864         Packet::iterator it;
865         for (it = m_packets.begin (); it != m_packets.end (); ++it)
866         {
867             if (payload.compare (0, it->abbrev.size(), it->abbrev) == 0)
868                 break;
869         }
870 
871         // A packet we don't have an entry for. This can happen when we
872         // get a packet that we don't know about or support. We just reply
873         // accordingly and go on.
874         if (it == m_packets.end ())
875         {
876             DNBLogThreadedIf (LOG_RNB_PACKETS, "unimplemented packet: '%s'", payload.c_str());
877             HandlePacket_UNIMPLEMENTED(payload.c_str());
878             return rnb_err;
879         }
880         else
881         {
882             packet_info = *it;
883             packet_payload = payload;
884         }
885     }
886     return err;
887 }
888 
889 rnb_err_t
890 RNBRemote::HandleAsyncPacket(PacketEnum *type)
891 {
892     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
893     static DNBTimer g_packetTimer(true);
894     rnb_err_t err = rnb_err;
895     std::string packet_data;
896     RNBRemote::Packet packet_info;
897     err = GetPacket (packet_data, packet_info, false);
898 
899     if (err == rnb_success)
900     {
901         if (!packet_data.empty() && isprint(packet_data[0]))
902             DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (\"%s\");", packet_data.c_str());
903         else
904             DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (%s);", packet_info.printable_name.c_str());
905 
906         HandlePacketCallback packet_callback = packet_info.async;
907         if (packet_callback != NULL)
908         {
909             if (type != NULL)
910                 *type = packet_info.type;
911             return (this->*packet_callback)(packet_data.c_str());
912         }
913     }
914 
915     return err;
916 }
917 
918 rnb_err_t
919 RNBRemote::HandleReceivedPacket(PacketEnum *type)
920 {
921     static DNBTimer g_packetTimer(true);
922 
923     //  DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
924     rnb_err_t err = rnb_err;
925     std::string packet_data;
926     RNBRemote::Packet packet_info;
927     err = GetPacket (packet_data, packet_info, false);
928 
929     if (err == rnb_success)
930     {
931         DNBLogThreadedIf (LOG_RNB_REMOTE, "HandleReceivedPacket (\"%s\");", packet_data.c_str());
932         HandlePacketCallback packet_callback = packet_info.normal;
933         if (packet_callback != NULL)
934         {
935             if (type != NULL)
936                 *type = packet_info.type;
937             return (this->*packet_callback)(packet_data.c_str());
938         }
939         else
940         {
941             // Do not fall through to end of this function, if we have valid
942             // packet_info and it has a NULL callback, then we need to respect
943             // that it may not want any response or anything to be done.
944             return err;
945         }
946     }
947     return rnb_err;
948 }
949 
950 void
951 RNBRemote::CommDataReceived(const std::string& new_data)
952 {
953     //  DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
954     {
955         // Put the packet data into the buffer in a thread safe fashion
956         PThreadMutex::Locker locker(m_mutex);
957 
958         std::string data;
959         // See if we have any left over data from a previous call to this
960         // function?
961         if (!m_rx_partial_data.empty())
962         {
963             // We do, so lets start with that data
964             data.swap(m_rx_partial_data);
965         }
966         // Append the new incoming data
967         data += new_data;
968 
969         // Parse up the packets into gdb remote packets
970         size_t idx = 0;
971         const size_t data_size = data.size();
972 
973         while (idx < data_size)
974         {
975             // end_idx must be one past the last valid packet byte. Start
976             // it off with an invalid value that is the same as the current
977             // index.
978             size_t end_idx = idx;
979 
980             switch (data[idx])
981             {
982                 case '+':       // Look for ack
983                 case '-':       // Look for cancel
984                 case '\x03':    // ^C to halt target
985                     end_idx = idx + 1;  // The command is one byte long...
986                     break;
987 
988                 case '$':
989                     // Look for a standard gdb packet?
990                     end_idx = data.find('#',  idx + 1);
991                     if (end_idx == std::string::npos || end_idx + 3 > data_size)
992                     {
993                         end_idx = std::string::npos;
994                     }
995                     else
996                     {
997                         // Add two for the checksum bytes and 1 to point to the
998                         // byte just past the end of this packet
999                         end_idx += 3;
1000                     }
1001                     break;
1002 
1003                 default:
1004                     break;
1005             }
1006 
1007             if (end_idx == std::string::npos)
1008             {
1009                 // Not all data may be here for the packet yet, save it for
1010                 // next time through this function.
1011                 m_rx_partial_data += data.substr(idx);
1012                 //DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s saving data for later[%u, npos): '%s'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx, m_rx_partial_data.c_str());
1013                 idx = end_idx;
1014             }
1015             else
1016                 if (idx < end_idx)
1017                 {
1018                     m_packets_recvd++;
1019                     // Hack to get rid of initial '+' ACK???
1020                     if (m_packets_recvd == 1 && (end_idx == idx + 1) && data[idx] == '+')
1021                     {
1022                         //DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s throwing first ACK away....[%u, npos): '+'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx);
1023                     }
1024                     else
1025                     {
1026                         // We have a valid packet...
1027                         m_rx_packets.push_back(data.substr(idx, end_idx - idx));
1028                         DNBLogThreadedIf (LOG_RNB_PACKETS, "getpkt: %s", m_rx_packets.back().c_str());
1029                     }
1030                     idx = end_idx;
1031                 }
1032                 else
1033                 {
1034                     DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s tossing junk byte at %c",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, data[idx]);
1035                     idx = idx + 1;
1036                 }
1037         }
1038     }
1039 
1040     if (!m_rx_packets.empty())
1041     {
1042         // Let the main thread know we have received a packet
1043 
1044         //DNBLogThreadedIf (LOG_RNB_EVENTS, "%8d RNBRemote::%s   called events.SetEvent(RNBContext::event_read_packet_available)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
1045         PThreadEvent& events = m_ctx.Events();
1046         events.SetEvents (RNBContext::event_read_packet_available);
1047     }
1048 }
1049 
1050 rnb_err_t
1051 RNBRemote::GetCommData ()
1052 {
1053     //  DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
1054     std::string comm_data;
1055     rnb_err_t err = m_comm.Read (comm_data);
1056     if (err == rnb_success)
1057     {
1058         if (!comm_data.empty())
1059             CommDataReceived (comm_data);
1060     }
1061     return err;
1062 }
1063 
1064 void
1065 RNBRemote::StartReadRemoteDataThread()
1066 {
1067     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
1068     PThreadEvent& events = m_ctx.Events();
1069     if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 0)
1070     {
1071         events.ResetEvents (RNBContext::event_read_thread_exiting);
1072         int err = ::pthread_create (&m_rx_pthread, NULL, ThreadFunctionReadRemoteData, this);
1073         if (err == 0)
1074         {
1075             // Our thread was successfully kicked off, wait for it to
1076             // set the started event so we can safely continue
1077             events.WaitForSetEvents (RNBContext::event_read_thread_running);
1078         }
1079         else
1080         {
1081             events.ResetEvents (RNBContext::event_read_thread_running);
1082             events.SetEvents (RNBContext::event_read_thread_exiting);
1083         }
1084     }
1085 }
1086 
1087 void
1088 RNBRemote::StopReadRemoteDataThread()
1089 {
1090     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
1091     PThreadEvent& events = m_ctx.Events();
1092     if ((events.GetEventBits() & RNBContext::event_read_thread_running) == RNBContext::event_read_thread_running)
1093     {
1094         m_comm.Disconnect(true);
1095         struct timespec timeout_abstime;
1096         DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
1097 
1098         // Wait for 2 seconds for the remote data thread to exit
1099         if (events.WaitForSetEvents(RNBContext::event_read_thread_exiting, &timeout_abstime) == 0)
1100         {
1101             // Kill the remote data thread???
1102         }
1103     }
1104 }
1105 
1106 
1107 void*
1108 RNBRemote::ThreadFunctionReadRemoteData(void *arg)
1109 {
1110     // Keep a shared pointer reference so this doesn't go away on us before the thread is killed.
1111     DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread starting...", __FUNCTION__, arg);
1112     RNBRemoteSP remoteSP(g_remoteSP);
1113     if (remoteSP.get() != NULL)
1114     {
1115 
1116 #if defined (__APPLE__)
1117         pthread_setname_np ("read gdb-remote packets thread");
1118 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
1119         struct sched_param thread_param;
1120         int thread_sched_policy;
1121         if (pthread_getschedparam(pthread_self(), &thread_sched_policy, &thread_param) == 0)
1122         {
1123             thread_param.sched_priority = 47;
1124             pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
1125         }
1126 #endif
1127 #endif
1128 
1129         RNBRemote* remote = remoteSP.get();
1130         PThreadEvent& events = remote->Context().Events();
1131         events.SetEvents (RNBContext::event_read_thread_running);
1132         // START: main receive remote command thread loop
1133         bool done = false;
1134         while (!done)
1135         {
1136             rnb_err_t err = remote->GetCommData();
1137 
1138             switch (err)
1139             {
1140                 case rnb_success:
1141                     break;
1142 
1143                 case rnb_err:
1144                     DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err);
1145                     done = true;
1146                     break;
1147 
1148                 case rnb_not_connected:
1149                     DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned not connected...");
1150                     done = true;
1151                     break;
1152             }
1153         }
1154         // START: main receive remote command thread loop
1155         events.ResetEvents (RNBContext::event_read_thread_running);
1156         events.SetEvents (RNBContext::event_read_thread_exiting);
1157     }
1158     DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", __FUNCTION__, arg);
1159     return NULL;
1160 }
1161 
1162 
1163 // If we fail to get back a valid CPU type for the remote process,
1164 // make a best guess for the CPU type based on the currently running
1165 // debugserver binary -- the debugger may not handle the case of an
1166 // un-specified process CPU type correctly.
1167 
1168 static cpu_type_t
1169 best_guess_cpu_type ()
1170 {
1171 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
1172     if (sizeof (char *) == 8)
1173     {
1174         return CPU_TYPE_ARM64;
1175     }
1176     else
1177     {
1178         return CPU_TYPE_ARM;
1179     }
1180 #elif defined (__i386__) || defined (__x86_64__)
1181     if (sizeof (char*) == 8)
1182     {
1183         return CPU_TYPE_X86_64;
1184     }
1185     else
1186     {
1187         return CPU_TYPE_I386;
1188     }
1189 #endif
1190     return 0;
1191 }
1192 
1193 
1194 /* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes
1195  (8-bit bytes).
1196  This encoding uses 0x7d ('}') as an escape character for
1197  0x7d ('}'), 0x23 ('#'), 0x24 ('$'), 0x2a ('*').
1198  LEN is the number of bytes to be processed.  If a character is escaped,
1199  it is 2 characters for LEN.  A LEN of -1 means decode-until-nul-byte
1200  (end of string).  */
1201 
1202 std::vector<uint8_t>
1203 decode_binary_data (const char *str, size_t len)
1204 {
1205     std::vector<uint8_t> bytes;
1206     if (len == 0)
1207     {
1208         return bytes;
1209     }
1210     if (len == (size_t)-1)
1211         len = strlen (str);
1212 
1213     while (len--)
1214     {
1215         unsigned char c = *str++;
1216         if (c == 0x7d && len > 0)
1217         {
1218             len--;
1219             c = *str++ ^ 0x20;
1220         }
1221         bytes.push_back (c);
1222     }
1223     return bytes;
1224 }
1225 
1226 // Quote any meta characters in a std::string as per the binary
1227 // packet convention in the gdb-remote protocol.
1228 
1229 static std::string
1230 binary_encode_string (const std::string &s)
1231 {
1232     std::string output;
1233     const size_t s_size = s.size();
1234     const char *s_chars = s.c_str();
1235 
1236     for (size_t i = 0; i < s_size; i++)
1237     {
1238         unsigned char ch = *(s_chars + i);
1239         if (ch == '#' || ch == '$' || ch == '}' || ch == '*')
1240         {
1241             output.push_back ('}');         // 0x7d
1242             output.push_back (ch ^ 0x20);
1243         }
1244         else
1245         {
1246             output.push_back (ch);
1247         }
1248     }
1249     return output;
1250 }
1251 
1252 // If the value side of a key-value pair in JSON is a string,
1253 // and that string has a " character in it, the " character must
1254 // be escaped.
1255 
1256 std::string
1257 json_string_quote_metachars (const std::string &s)
1258 {
1259     if (s.find('"') == std::string::npos)
1260         return s;
1261 
1262     std::string output;
1263     const size_t s_size = s.size();
1264     const char *s_chars = s.c_str();
1265     for (size_t i = 0; i < s_size; i++)
1266     {
1267         unsigned char ch = *(s_chars + i);
1268         if (ch == '"')
1269         {
1270             output.push_back ('\\');
1271         }
1272         output.push_back (ch);
1273     }
1274     return output;
1275 }
1276 
1277 typedef struct register_map_entry
1278 {
1279     uint32_t        debugserver_regnum; // debugserver register number
1280     uint32_t        offset;     // Offset in bytes into the register context data with no padding between register values
1281     DNBRegisterInfo nub_info;   // debugnub register info
1282     std::vector<uint32_t> value_regnums;
1283     std::vector<uint32_t> invalidate_regnums;
1284 } register_map_entry_t;
1285 
1286 
1287 
1288 // If the notion of registers differs from what is handed out by the
1289 // architecture, then flavors can be defined here.
1290 
1291 static std::vector<register_map_entry_t> g_dynamic_register_map;
1292 static register_map_entry_t *g_reg_entries = NULL;
1293 static size_t g_num_reg_entries = 0;
1294 
1295 void
1296 RNBRemote::Initialize()
1297 {
1298     DNBInitialize();
1299 }
1300 
1301 
1302 bool
1303 RNBRemote::InitializeRegisters (bool force)
1304 {
1305     pid_t pid = m_ctx.ProcessID();
1306     if (pid == INVALID_NUB_PROCESS)
1307         return false;
1308 
1309     DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface", __FUNCTION__);
1310     // Discover the registers by querying the DNB interface and letting it
1311     // state the registers that it would like to export. This allows the
1312     // registers to be discovered using multiple qRegisterInfo calls to get
1313     // all register information after the architecture for the process is
1314     // determined.
1315     if (force)
1316     {
1317         g_dynamic_register_map.clear();
1318         g_reg_entries = NULL;
1319         g_num_reg_entries = 0;
1320     }
1321 
1322     if (g_dynamic_register_map.empty())
1323     {
1324         nub_size_t num_reg_sets = 0;
1325         const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
1326 
1327         assert (num_reg_sets > 0 && reg_sets != NULL);
1328 
1329         uint32_t regnum = 0;
1330         uint32_t reg_data_offset = 0;
1331         typedef std::map<std::string, uint32_t> NameToRegNum;
1332         NameToRegNum name_to_regnum;
1333         for (nub_size_t set = 0; set < num_reg_sets; ++set)
1334         {
1335             if (reg_sets[set].registers == NULL)
1336                 continue;
1337 
1338             for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
1339             {
1340                 register_map_entry_t reg_entry = {
1341                     regnum++,                           // register number starts at zero and goes up with no gaps
1342                     reg_data_offset,                    // Offset into register context data, no gaps between registers
1343                     reg_sets[set].registers[reg],       // DNBRegisterInfo
1344                     {},
1345                     {},
1346                 };
1347 
1348                 name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum;
1349 
1350                 if (reg_entry.nub_info.value_regs == NULL)
1351                 {
1352                     reg_data_offset += reg_entry.nub_info.size;
1353                 }
1354 
1355                 g_dynamic_register_map.push_back (reg_entry);
1356             }
1357         }
1358 
1359         // Now we must find any registers whose values are in other registers and fix up
1360         // the offsets since we removed all gaps...
1361         for (auto &reg_entry: g_dynamic_register_map)
1362         {
1363             if (reg_entry.nub_info.value_regs)
1364             {
1365                 uint32_t new_offset = UINT32_MAX;
1366                 for (size_t i=0; reg_entry.nub_info.value_regs[i] != NULL; ++i)
1367                 {
1368                     const char *name = reg_entry.nub_info.value_regs[i];
1369                     auto pos = name_to_regnum.find(name);
1370                     if (pos != name_to_regnum.end())
1371                     {
1372                         regnum = pos->second;
1373                         reg_entry.value_regnums.push_back(regnum);
1374                         if (regnum < g_dynamic_register_map.size())
1375                         {
1376                             // The offset for value_regs registers is the offset within the register with the lowest offset
1377                             const uint32_t reg_offset = g_dynamic_register_map[regnum].offset + reg_entry.nub_info.offset;
1378                             if (new_offset > reg_offset)
1379                                 new_offset = reg_offset;
1380                         }
1381                     }
1382                 }
1383 
1384                 if (new_offset != UINT32_MAX)
1385                 {
1386                     reg_entry.offset = new_offset;
1387                 }
1388                 else
1389                 {
1390                     DNBLogThreaded("no offset was calculated entry for register %s", reg_entry.nub_info.name);
1391                     reg_entry.offset = UINT32_MAX;
1392                 }
1393             }
1394 
1395             if (reg_entry.nub_info.update_regs)
1396             {
1397                 for (size_t i=0; reg_entry.nub_info.update_regs[i] != NULL; ++i)
1398                 {
1399                     const char *name = reg_entry.nub_info.update_regs[i];
1400                     auto pos = name_to_regnum.find(name);
1401                     if (pos != name_to_regnum.end())
1402                     {
1403                         regnum = pos->second;
1404                         reg_entry.invalidate_regnums.push_back(regnum);
1405                     }
1406                 }
1407             }
1408         }
1409 
1410 
1411 //        for (auto &reg_entry: g_dynamic_register_map)
1412 //        {
1413 //            DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s",
1414 //                           reg_entry.offset,
1415 //                           reg_entry.nub_info.size,
1416 //                           reg_entry.nub_info.value_regs != NULL,
1417 //                           reg_entry.nub_info.name);
1418 //        }
1419 
1420         g_reg_entries = g_dynamic_register_map.data();
1421         g_num_reg_entries = g_dynamic_register_map.size();
1422     }
1423     return true;
1424 }
1425 
1426 /* The inferior has stopped executing; send a packet
1427  to gdb to let it know.  */
1428 
1429 void
1430 RNBRemote::NotifyThatProcessStopped (void)
1431 {
1432     RNBRemote::HandlePacket_last_signal (NULL);
1433     return;
1434 }
1435 
1436 
1437 /* 'A arglen,argnum,arg,...'
1438  Update the inferior context CTX with the program name and arg
1439  list.
1440  The documentation for this packet is underwhelming but my best reading
1441  of this is that it is a series of (len, position #, arg)'s, one for
1442  each argument with "arg" hex encoded (two 0-9a-f chars?).
1443  Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either
1444  is sufficient to get around the "," position separator escape issue.
1445 
1446  e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is
1447 
1448  6,0,676462,4,1,2d71,10,2,612e6f7574
1449 
1450  Note that "argnum" and "arglen" are numbers in base 10.  Again, that's
1451  not documented either way but I'm assuming it's so.  */
1452 
1453 rnb_err_t
1454 RNBRemote::HandlePacket_A (const char *p)
1455 {
1456     if (p == NULL || *p == '\0')
1457     {
1458         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt");
1459     }
1460     p++;
1461     if (*p == '\0' || !isdigit (*p))
1462     {
1463         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt");
1464     }
1465 
1466     /* I promise I don't modify it anywhere in this function.  strtoul()'s
1467      2nd arg has to be non-const which makes it problematic to step
1468      through the string easily.  */
1469     char *buf = const_cast<char *>(p);
1470 
1471     RNBContext& ctx = Context();
1472 
1473     while (*buf != '\0')
1474     {
1475         unsigned long arglen, argnum;
1476         std::string arg;
1477         char *c;
1478 
1479         errno = 0;
1480         arglen = strtoul (buf, &c, 10);
1481         if (errno != 0 && arglen == 0)
1482         {
1483             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt");
1484         }
1485         if (*c != ',')
1486         {
1487             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
1488         }
1489         buf = c + 1;
1490 
1491         errno = 0;
1492         argnum = strtoul (buf, &c, 10);
1493         if (errno != 0 && argnum == 0)
1494         {
1495             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt");
1496         }
1497         if (*c != ',')
1498         {
1499             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
1500         }
1501         buf = c + 1;
1502 
1503         c = buf;
1504         buf = buf + arglen;
1505         while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0')
1506         {
1507             char smallbuf[3];
1508             smallbuf[0] = *c;
1509             smallbuf[1] = *(c + 1);
1510             smallbuf[2] = '\0';
1511 
1512             errno = 0;
1513             int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
1514             if (errno != 0 && ch == 0)
1515             {
1516                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt");
1517             }
1518 
1519             arg.push_back(ch);
1520             c += 2;
1521         }
1522 
1523         ctx.PushArgument (arg.c_str());
1524         if (*buf == ',')
1525             buf++;
1526     }
1527     SendPacket ("OK");
1528 
1529     return rnb_success;
1530 }
1531 
1532 /* 'H c t'
1533  Set the thread for subsequent actions; 'c' for step/continue ops,
1534  'g' for other ops.  -1 means all threads, 0 means any thread.  */
1535 
1536 rnb_err_t
1537 RNBRemote::HandlePacket_H (const char *p)
1538 {
1539     p++;  // skip 'H'
1540     if (*p != 'c' && *p != 'g')
1541     {
1542         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet");
1543     }
1544 
1545     if (!m_ctx.HasValidProcessID())
1546     {
1547         // We allow gdb to connect to a server that hasn't started running
1548         // the target yet.  gdb still wants to ask questions about it and
1549         // freaks out if it gets an error.  So just return OK here.
1550     }
1551 
1552     errno = 0;
1553     nub_thread_t tid = strtoul (p + 1, NULL, 16);
1554     if (errno != 0 && tid == 0)
1555     {
1556         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet");
1557     }
1558     if (*p == 'c')
1559         SetContinueThread (tid);
1560     if (*p == 'g')
1561         SetCurrentThread (tid);
1562 
1563     return SendPacket ("OK");
1564 }
1565 
1566 
1567 rnb_err_t
1568 RNBRemote::HandlePacket_qLaunchSuccess (const char *p)
1569 {
1570     if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0)
1571         return SendPacket("OK");
1572     std::ostringstream ret_str;
1573     std::string status_str;
1574     ret_str << "E" << m_ctx.LaunchStatusAsString(status_str);
1575 
1576     return SendPacket (ret_str.str());
1577 }
1578 
1579 rnb_err_t
1580 RNBRemote::HandlePacket_qShlibInfoAddr (const char *p)
1581 {
1582     if (m_ctx.HasValidProcessID())
1583     {
1584         nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID());
1585         if (shlib_info_addr != INVALID_NUB_ADDRESS)
1586         {
1587             std::ostringstream ostrm;
1588             ostrm << RAW_HEXBASE << shlib_info_addr;
1589             return SendPacket (ostrm.str ());
1590         }
1591     }
1592     return SendPacket ("E44");
1593 }
1594 
1595 rnb_err_t
1596 RNBRemote::HandlePacket_qStepPacketSupported (const char *p)
1597 {
1598     // Normally the "s" packet is mandatory, yet in gdb when using ARM, they
1599     // get around the need for this packet by implementing software single
1600     // stepping from gdb. Current versions of debugserver do support the "s"
1601     // packet, yet some older versions do not. We need a way to tell if this
1602     // packet is supported so we can disable software single stepping in gdb
1603     // for remote targets (so the "s" packet will get used).
1604     return SendPacket("OK");
1605 }
1606 
1607 rnb_err_t
1608 RNBRemote::HandlePacket_qSyncThreadStateSupported (const char *p)
1609 {
1610     // We support attachOrWait meaning attach if the process exists, otherwise wait to attach.
1611     return SendPacket("OK");
1612 }
1613 
1614 rnb_err_t
1615 RNBRemote::HandlePacket_qVAttachOrWaitSupported (const char *p)
1616 {
1617     // We support attachOrWait meaning attach if the process exists, otherwise wait to attach.
1618     return SendPacket("OK");
1619 }
1620 
1621 rnb_err_t
1622 RNBRemote::HandlePacket_qThreadStopInfo (const char *p)
1623 {
1624     p += strlen ("qThreadStopInfo");
1625     nub_thread_t tid = strtoul(p, 0, 16);
1626     return SendStopReplyPacketForThread (tid);
1627 }
1628 
1629 rnb_err_t
1630 RNBRemote::HandlePacket_qThreadInfo (const char *p)
1631 {
1632     // We allow gdb to connect to a server that hasn't started running
1633     // the target yet.  gdb still wants to ask questions about it and
1634     // freaks out if it gets an error.  So just return OK here.
1635     nub_process_t pid = m_ctx.ProcessID();
1636     if (pid == INVALID_NUB_PROCESS)
1637         return SendPacket ("OK");
1638 
1639     // Only "qfThreadInfo" and "qsThreadInfo" get into this function so
1640     // we only need to check the second byte to tell which is which
1641     if (p[1] == 'f')
1642     {
1643         nub_size_t numthreads = DNBProcessGetNumThreads (pid);
1644         std::ostringstream ostrm;
1645         ostrm << "m";
1646         bool first = true;
1647         for (nub_size_t i = 0; i < numthreads; ++i)
1648         {
1649             if (first)
1650                 first = false;
1651             else
1652                 ostrm << ",";
1653             nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
1654             ostrm << std::hex << th;
1655         }
1656         return SendPacket (ostrm.str ());
1657     }
1658     else
1659     {
1660         return SendPacket ("l");
1661     }
1662 }
1663 
1664 rnb_err_t
1665 RNBRemote::HandlePacket_qThreadExtraInfo (const char *p)
1666 {
1667     // We allow gdb to connect to a server that hasn't started running
1668     // the target yet.  gdb still wants to ask questions about it and
1669     // freaks out if it gets an error.  So just return OK here.
1670     nub_process_t pid = m_ctx.ProcessID();
1671     if (pid == INVALID_NUB_PROCESS)
1672         return SendPacket ("OK");
1673 
1674     /* This is supposed to return a string like 'Runnable' or
1675      'Blocked on Mutex'.
1676      The returned string is formatted like the "A" packet - a
1677      sequence of letters encoded in as 2-hex-chars-per-letter.  */
1678     p += strlen ("qThreadExtraInfo");
1679     if (*p++ != ',')
1680         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet");
1681     errno = 0;
1682     nub_thread_t tid = strtoul (p, NULL, 16);
1683     if (errno != 0 && tid == 0)
1684     {
1685         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet");
1686     }
1687 
1688     const char * threadInfo = DNBThreadGetInfo(pid, tid);
1689     if (threadInfo != NULL && threadInfo[0])
1690     {
1691         return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL);
1692     }
1693     else
1694     {
1695         // "OK" == 4f6b
1696         // Return "OK" as a ASCII hex byte stream if things go wrong
1697         return SendPacket ("4f6b");
1698     }
1699 
1700     return SendPacket ("");
1701 }
1702 
1703 
1704 const char *k_space_delimiters = " \t";
1705 static void
1706 skip_spaces (std::string &line)
1707 {
1708     if (!line.empty())
1709     {
1710         size_t space_pos = line.find_first_not_of (k_space_delimiters);
1711         if (space_pos > 0)
1712             line.erase(0, space_pos);
1713     }
1714 }
1715 
1716 static std::string
1717 get_identifier (std::string &line)
1718 {
1719     std::string word;
1720     skip_spaces (line);
1721     const size_t line_size = line.size();
1722     size_t end_pos;
1723     for (end_pos = 0; end_pos < line_size; ++end_pos)
1724     {
1725         if (end_pos == 0)
1726         {
1727             if (isalpha(line[end_pos]) || line[end_pos] == '_')
1728                 continue;
1729         }
1730         else if (isalnum(line[end_pos]) || line[end_pos] == '_')
1731             continue;
1732         break;
1733     }
1734     word.assign (line, 0, end_pos);
1735     line.erase(0, end_pos);
1736     return word;
1737 }
1738 
1739 static std::string
1740 get_operator (std::string &line)
1741 {
1742     std::string op;
1743     skip_spaces (line);
1744     if (!line.empty())
1745     {
1746         if (line[0] == '=')
1747         {
1748             op = '=';
1749             line.erase(0,1);
1750         }
1751     }
1752     return op;
1753 }
1754 
1755 static std::string
1756 get_value (std::string &line)
1757 {
1758     std::string value;
1759     skip_spaces (line);
1760     if (!line.empty())
1761     {
1762         value.swap(line);
1763     }
1764     return value;
1765 }
1766 
1767 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
1768 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
1769 
1770 rnb_err_t
1771 RNBRemote::HandlePacket_qRcmd (const char *p)
1772 {
1773     const char *c = p + strlen("qRcmd,");
1774     std::string line;
1775     while (c[0] && c[1])
1776     {
1777         char smallbuf[3] = { c[0], c[1], '\0' };
1778         errno = 0;
1779         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
1780         if (errno != 0 && ch == 0)
1781             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet");
1782         line.push_back(ch);
1783         c += 2;
1784     }
1785     if (*c == '\0')
1786     {
1787         std::string command = get_identifier(line);
1788         if (command.compare("set") == 0)
1789         {
1790             std::string variable = get_identifier (line);
1791             std::string op = get_operator (line);
1792             std::string value = get_value (line);
1793             if (variable.compare("logfile") == 0)
1794             {
1795                 FILE *log_file = fopen(value.c_str(), "w");
1796                 if (log_file)
1797                 {
1798                     DNBLogSetLogCallback(FileLogCallback, log_file);
1799                     return SendPacket ("OK");
1800                 }
1801                 return SendPacket ("E71");
1802             }
1803             else if (variable.compare("logmask") == 0)
1804             {
1805                 char *end;
1806                 errno = 0;
1807                 uint32_t logmask = static_cast<uint32_t>(strtoul (value.c_str(), &end, 0));
1808                 if (errno == 0 && end && *end == '\0')
1809                 {
1810                     DNBLogSetLogMask (logmask);
1811                     if (!DNBLogGetLogCallback())
1812                         DNBLogSetLogCallback(ASLLogCallback, NULL);
1813                     return SendPacket ("OK");
1814                 }
1815                 errno = 0;
1816                 logmask = static_cast<uint32_t>(strtoul (value.c_str(), &end, 16));
1817                 if (errno == 0 && end && *end == '\0')
1818                 {
1819                     DNBLogSetLogMask (logmask);
1820                     return SendPacket ("OK");
1821                 }
1822                 return SendPacket ("E72");
1823             }
1824             return SendPacket ("E70");
1825         }
1826         return SendPacket ("E69");
1827     }
1828     return SendPacket ("E73");
1829 }
1830 
1831 rnb_err_t
1832 RNBRemote::HandlePacket_qC (const char *p)
1833 {
1834     nub_thread_t tid;
1835     std::ostringstream rep;
1836     // If we haven't run the process yet, we tell the debugger the
1837     // pid is 0.  That way it can know to tell use to run later on.
1838     if (!m_ctx.HasValidProcessID())
1839         tid = 0;
1840     else
1841     {
1842         // Grab the current thread.
1843         tid = DNBProcessGetCurrentThread (m_ctx.ProcessID());
1844         // Make sure we set the current thread so g and p packets return
1845         // the data the gdb will expect.
1846         SetCurrentThread (tid);
1847     }
1848     rep << "QC" << std::hex << tid;
1849     return SendPacket (rep.str());
1850 }
1851 
1852 rnb_err_t
1853 RNBRemote::HandlePacket_qEcho (const char *p)
1854 {
1855     // Just send the exact same packet back that we received to
1856     // synchronize the response packets after a previous packet
1857     // timed out. This allows the debugger to get back on track
1858     // with responses after a packet timeout.
1859     return SendPacket (p);
1860 }
1861 
1862 rnb_err_t
1863 RNBRemote::HandlePacket_qGetPid (const char *p)
1864 {
1865     nub_process_t pid;
1866     std::ostringstream rep;
1867     // If we haven't run the process yet, we tell the debugger the
1868     // pid is 0.  That way it can know to tell use to run later on.
1869     if (m_ctx.HasValidProcessID())
1870         pid = m_ctx.ProcessID();
1871     else
1872         pid = 0;
1873     rep << std::hex << pid;
1874     return SendPacket (rep.str());
1875 }
1876 
1877 rnb_err_t
1878 RNBRemote::HandlePacket_qRegisterInfo (const char *p)
1879 {
1880     if (g_num_reg_entries == 0)
1881         InitializeRegisters ();
1882 
1883     p += strlen ("qRegisterInfo");
1884 
1885     nub_size_t num_reg_sets = 0;
1886     const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets);
1887     uint32_t reg_num = static_cast<uint32_t>(strtoul(p, 0, 16));
1888 
1889     if (reg_num < g_num_reg_entries)
1890     {
1891         const register_map_entry_t *reg_entry = &g_reg_entries[reg_num];
1892         std::ostringstream ostrm;
1893         if (reg_entry->nub_info.name)
1894             ostrm << "name:" << reg_entry->nub_info.name << ';';
1895         if (reg_entry->nub_info.alt)
1896             ostrm << "alt-name:" << reg_entry->nub_info.alt << ';';
1897 
1898         ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';';
1899         ostrm << "offset:" << std::dec << reg_entry->offset << ';';
1900 
1901         switch (reg_entry->nub_info.type)
1902         {
1903             case Uint:      ostrm << "encoding:uint;"; break;
1904             case Sint:      ostrm << "encoding:sint;"; break;
1905             case IEEE754:   ostrm << "encoding:ieee754;"; break;
1906             case Vector:    ostrm << "encoding:vector;"; break;
1907         }
1908 
1909         switch (reg_entry->nub_info.format)
1910         {
1911             case Binary:            ostrm << "format:binary;"; break;
1912             case Decimal:           ostrm << "format:decimal;"; break;
1913             case Hex:               ostrm << "format:hex;"; break;
1914             case Float:             ostrm << "format:float;"; break;
1915             case VectorOfSInt8:     ostrm << "format:vector-sint8;"; break;
1916             case VectorOfUInt8:     ostrm << "format:vector-uint8;"; break;
1917             case VectorOfSInt16:    ostrm << "format:vector-sint16;"; break;
1918             case VectorOfUInt16:    ostrm << "format:vector-uint16;"; break;
1919             case VectorOfSInt32:    ostrm << "format:vector-sint32;"; break;
1920             case VectorOfUInt32:    ostrm << "format:vector-uint32;"; break;
1921             case VectorOfFloat32:   ostrm << "format:vector-float32;"; break;
1922             case VectorOfUInt128:   ostrm << "format:vector-uint128;"; break;
1923         };
1924 
1925         if (reg_set_info && reg_entry->nub_info.set < num_reg_sets)
1926             ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';';
1927 
1928         if (reg_entry->nub_info.reg_ehframe != INVALID_NUB_REGNUM)
1929             ostrm << "ehframe:" << std::dec << reg_entry->nub_info.reg_ehframe << ';';
1930 
1931         if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM)
1932             ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';';
1933 
1934         switch (reg_entry->nub_info.reg_generic)
1935         {
1936             case GENERIC_REGNUM_FP:     ostrm << "generic:fp;"; break;
1937             case GENERIC_REGNUM_PC:     ostrm << "generic:pc;"; break;
1938             case GENERIC_REGNUM_SP:     ostrm << "generic:sp;"; break;
1939             case GENERIC_REGNUM_RA:     ostrm << "generic:ra;"; break;
1940             case GENERIC_REGNUM_FLAGS:  ostrm << "generic:flags;"; break;
1941             case GENERIC_REGNUM_ARG1:   ostrm << "generic:arg1;"; break;
1942             case GENERIC_REGNUM_ARG2:   ostrm << "generic:arg2;"; break;
1943             case GENERIC_REGNUM_ARG3:   ostrm << "generic:arg3;"; break;
1944             case GENERIC_REGNUM_ARG4:   ostrm << "generic:arg4;"; break;
1945             case GENERIC_REGNUM_ARG5:   ostrm << "generic:arg5;"; break;
1946             case GENERIC_REGNUM_ARG6:   ostrm << "generic:arg6;"; break;
1947             case GENERIC_REGNUM_ARG7:   ostrm << "generic:arg7;"; break;
1948             case GENERIC_REGNUM_ARG8:   ostrm << "generic:arg8;"; break;
1949             default: break;
1950         }
1951 
1952         if (!reg_entry->value_regnums.empty())
1953         {
1954             ostrm << "container-regs:";
1955             for (size_t i=0, n=reg_entry->value_regnums.size(); i < n; ++i)
1956             {
1957                 if (i > 0)
1958                     ostrm << ',';
1959                 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i];
1960             }
1961             ostrm << ';';
1962         }
1963 
1964         if (!reg_entry->invalidate_regnums.empty())
1965         {
1966             ostrm << "invalidate-regs:";
1967             for (size_t i=0, n=reg_entry->invalidate_regnums.size(); i < n; ++i)
1968             {
1969                 if (i > 0)
1970                     ostrm << ',';
1971                 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i];
1972             }
1973             ostrm << ';';
1974         }
1975 
1976         return SendPacket (ostrm.str ());
1977     }
1978     return SendPacket ("E45");
1979 }
1980 
1981 
1982 /* This expects a packet formatted like
1983 
1984  QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
1985 
1986  with the "QSetLogging:" already removed from the start.  Maybe in the
1987  future this packet will include other keyvalue pairs like
1988 
1989  QSetLogging:bitmask=LOG_ALL;mode=asl;
1990  */
1991 
1992 rnb_err_t
1993 set_logging (const char *p)
1994 {
1995     int bitmask = 0;
1996     while (p && *p != '\0')
1997     {
1998         if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0)
1999         {
2000             p += sizeof ("bitmask=") - 1;
2001             while (p && *p != '\0' && *p != ';')
2002             {
2003                 if (*p == '|')
2004                     p++;
2005 
2006 // to regenerate the LOG_ entries (not including the LOG_RNB entries)
2007 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'`
2008 // do
2009 //   echo "                else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)"
2010 //   echo "                {"
2011 //   echo "                    p += sizeof (\"$logname\") - 1;"
2012 //   echo "                    bitmask |= $logname;"
2013 //   echo "                }"
2014 // done
2015                 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
2016                 {
2017                     p += sizeof ("LOG_VERBOSE") - 1;
2018                     bitmask |= LOG_VERBOSE;
2019                 }
2020                 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0)
2021                 {
2022                     p += sizeof ("LOG_PROCESS") - 1;
2023                     bitmask |= LOG_PROCESS;
2024                 }
2025                 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0)
2026                 {
2027                     p += sizeof ("LOG_THREAD") - 1;
2028                     bitmask |= LOG_THREAD;
2029                 }
2030                 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0)
2031                 {
2032                     p += sizeof ("LOG_EXCEPTIONS") - 1;
2033                     bitmask |= LOG_EXCEPTIONS;
2034                 }
2035                 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0)
2036                 {
2037                     p += sizeof ("LOG_SHLIB") - 1;
2038                     bitmask |= LOG_SHLIB;
2039                 }
2040                 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0)
2041                 {
2042                     p += sizeof ("LOG_MEMORY") - 1;
2043                     bitmask |= LOG_MEMORY;
2044                 }
2045                 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0)
2046                 {
2047                     p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1;
2048                     bitmask |= LOG_MEMORY_DATA_SHORT;
2049                 }
2050                 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0)
2051                 {
2052                     p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
2053                     bitmask |= LOG_MEMORY_DATA_LONG;
2054                 }
2055                 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0)
2056                 {
2057                     p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1;
2058                     bitmask |= LOG_MEMORY_PROTECTIONS;
2059                 }
2060                 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
2061                 {
2062                     p += sizeof ("LOG_BREAKPOINTS") - 1;
2063                     bitmask |= LOG_BREAKPOINTS;
2064                 }
2065                 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
2066                 {
2067                     p += sizeof ("LOG_EVENTS") - 1;
2068                     bitmask |= LOG_EVENTS;
2069                 }
2070                 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0)
2071                 {
2072                     p += sizeof ("LOG_WATCHPOINTS") - 1;
2073                     bitmask |= LOG_WATCHPOINTS;
2074                 }
2075                 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0)
2076                 {
2077                     p += sizeof ("LOG_STEP") - 1;
2078                     bitmask |= LOG_STEP;
2079                 }
2080                 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0)
2081                 {
2082                     p += sizeof ("LOG_TASK") - 1;
2083                     bitmask |= LOG_TASK;
2084                 }
2085                 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
2086                 {
2087                     p += sizeof ("LOG_ALL") - 1;
2088                     bitmask |= LOG_ALL;
2089                 }
2090                 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
2091                 {
2092                     p += sizeof ("LOG_DEFAULT") - 1;
2093                     bitmask |= LOG_DEFAULT;
2094                 }
2095 // end of auto-generated entries
2096 
2097                 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
2098                 {
2099                     p += sizeof ("LOG_NONE") - 1;
2100                     bitmask = 0;
2101                 }
2102                 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0)
2103                 {
2104                     p += sizeof ("LOG_RNB_MINIMAL") - 1;
2105                     bitmask |= LOG_RNB_MINIMAL;
2106                 }
2107                 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0)
2108                 {
2109                     p += sizeof ("LOG_RNB_MEDIUM") - 1;
2110                     bitmask |= LOG_RNB_MEDIUM;
2111                 }
2112                 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0)
2113                 {
2114                     p += sizeof ("LOG_RNB_MAX") - 1;
2115                     bitmask |= LOG_RNB_MAX;
2116                 }
2117                 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0)
2118                 {
2119                     p += sizeof ("LOG_RNB_COMM") - 1;
2120                     bitmask |= LOG_RNB_COMM;
2121                 }
2122                 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0)
2123                 {
2124                     p += sizeof ("LOG_RNB_REMOTE") - 1;
2125                     bitmask |= LOG_RNB_REMOTE;
2126                 }
2127                 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0)
2128                 {
2129                     p += sizeof ("LOG_RNB_EVENTS") - 1;
2130                     bitmask |= LOG_RNB_EVENTS;
2131                 }
2132                 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0)
2133                 {
2134                     p += sizeof ("LOG_RNB_PROC") - 1;
2135                     bitmask |= LOG_RNB_PROC;
2136                 }
2137                 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0)
2138                 {
2139                     p += sizeof ("LOG_RNB_PACKETS") - 1;
2140                     bitmask |= LOG_RNB_PACKETS;
2141                 }
2142                 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0)
2143                 {
2144                     p += sizeof ("LOG_RNB_ALL") - 1;
2145                     bitmask |= LOG_RNB_ALL;
2146                 }
2147                 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0)
2148                 {
2149                     p += sizeof ("LOG_RNB_DEFAULT") - 1;
2150                     bitmask |= LOG_RNB_DEFAULT;
2151                 }
2152                 else if (strncmp (p, "LOG_DARWIN_LOG", sizeof ("LOG_DARWIN_LOG") - 1) == 0)
2153                 {
2154                     p += sizeof ("LOG_DARWIN_LOG") - 1;
2155                     bitmask |= LOG_DARWIN_LOG;
2156                 }
2157                 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0)
2158                 {
2159                     p += sizeof ("LOG_RNB_NONE") - 1;
2160                     bitmask = 0;
2161                 }
2162                 else
2163                 {
2164                     /* Unrecognized logging bit; ignore it.  */
2165                     const char *c = strchr (p, '|');
2166                     if (c)
2167                     {
2168                         p = c;
2169                     }
2170                     else
2171                     {
2172                         c = strchr (p, ';');
2173                         if (c)
2174                         {
2175                             p = c;
2176                         }
2177                         else
2178                         {
2179                             // Improperly terminated word; just go to end of str
2180                             p = strchr (p, '\0');
2181                         }
2182                     }
2183                 }
2184             }
2185             // Did we get a properly formatted logging bitmask?
2186             if (p && *p == ';')
2187             {
2188                 // Enable DNB logging.
2189                 // Use the existing log callback if one was already configured.
2190                 if (!DNBLogGetLogCallback())
2191                 {
2192                     // Use the os_log()-based logger if available; otherwise,
2193                     // fallback to ASL.
2194                     auto log_callback = OsLogger::GetLogFunction();
2195                     if (log_callback)
2196                         DNBLogSetLogCallback(log_callback, nullptr);
2197                     else
2198                         DNBLogSetLogCallback(ASLLogCallback, nullptr);
2199                 }
2200 
2201                 // Update logging to use the configured log channel bitmask.
2202                 DNBLogSetLogMask (bitmask);
2203                 p++;
2204             }
2205         }
2206         // We're not going to support logging to a file for now.  All logging
2207         // goes through ASL or the previously arranged log callback.
2208 #if 0
2209         else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
2210         {
2211             p += sizeof ("mode=") - 1;
2212             if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
2213             {
2214                 DNBLogToASL ();
2215                 p += sizeof ("asl;") - 1;
2216             }
2217             else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
2218             {
2219                 DNBLogToFile ();
2220                 p += sizeof ("file;") - 1;
2221             }
2222             else
2223             {
2224                 // Ignore unknown argument
2225                 const char *c = strchr (p, ';');
2226                 if (c)
2227                     p = c + 1;
2228                 else
2229                     p = strchr (p, '\0');
2230             }
2231         }
2232         else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
2233         {
2234             p += sizeof ("filename=") - 1;
2235             const char *c = strchr (p, ';');
2236             if (c == NULL)
2237             {
2238                 c = strchr (p, '\0');
2239                 continue;
2240             }
2241             char *fn = (char *) alloca (c - p + 1);
2242             strncpy (fn, p, c - p);
2243             fn[c - p] = '\0';
2244 
2245             // A file name of "asl" is special and is another way to indicate
2246             // that logging should be done via ASL, not by file.
2247             if (strcmp (fn, "asl") == 0)
2248             {
2249                 DNBLogToASL ();
2250             }
2251             else
2252             {
2253                 FILE *f = fopen (fn, "w");
2254                 if (f)
2255                 {
2256                     DNBLogSetLogFile (f);
2257                     DNBEnableLogging (f, DNBLogGetLogMask ());
2258                     DNBLogToFile ();
2259                 }
2260             }
2261             p = c + 1;
2262         }
2263 #endif /* #if 0 to enforce ASL logging only.  */
2264         else
2265         {
2266             // Ignore unknown argument
2267             const char *c = strchr (p, ';');
2268             if (c)
2269                 p = c + 1;
2270             else
2271                 p = strchr (p, '\0');
2272         }
2273     }
2274 
2275     return rnb_success;
2276 }
2277 
2278 rnb_err_t
2279 RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
2280 {
2281     m_thread_suffix_supported = true;
2282     return SendPacket ("OK");
2283 }
2284 
2285 rnb_err_t
2286 RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
2287 {
2288     // Send the OK packet first so the correct checksum is appended...
2289     rnb_err_t result = SendPacket ("OK");
2290     m_noack_mode = true;
2291     return result;
2292 }
2293 
2294 
2295 rnb_err_t
2296 RNBRemote::HandlePacket_QSetLogging (const char *p)
2297 {
2298     p += sizeof ("QSetLogging:") - 1;
2299     rnb_err_t result = set_logging (p);
2300     if (result == rnb_success)
2301         return SendPacket ("OK");
2302     else
2303         return SendPacket ("E35");
2304 }
2305 
2306 rnb_err_t
2307 RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
2308 {
2309     extern int g_disable_aslr;
2310     p += sizeof ("QSetDisableASLR:") - 1;
2311     switch (*p)
2312     {
2313     case '0': g_disable_aslr = 0; break;
2314     case '1': g_disable_aslr = 1; break;
2315     default:
2316         return SendPacket ("E56");
2317     }
2318     return SendPacket ("OK");
2319 }
2320 
2321 rnb_err_t
2322 RNBRemote::HandlePacket_QSetSTDIO (const char *p)
2323 {
2324     // Only set stdin/out/err if we don't already have a process
2325     if (!m_ctx.HasValidProcessID())
2326     {
2327         bool success = false;
2328         // Check the seventh character since the packet will be one of:
2329         // QSetSTDIN
2330         // QSetSTDOUT
2331         // QSetSTDERR
2332         StringExtractor packet(p);
2333         packet.SetFilePos (7);
2334         char ch = packet.GetChar();
2335         while (packet.GetChar() != ':')
2336             /* Do nothing. */;
2337 
2338         switch (ch)
2339         {
2340             case 'I': // STDIN
2341                 packet.GetHexByteString (m_ctx.GetSTDIN());
2342                 success = !m_ctx.GetSTDIN().empty();
2343                 break;
2344 
2345             case 'O': // STDOUT
2346                 packet.GetHexByteString (m_ctx.GetSTDOUT());
2347                 success = !m_ctx.GetSTDOUT().empty();
2348                 break;
2349 
2350             case 'E': // STDERR
2351                 packet.GetHexByteString (m_ctx.GetSTDERR());
2352                 success = !m_ctx.GetSTDERR().empty();
2353                 break;
2354 
2355             default:
2356                 break;
2357         }
2358         if (success)
2359             return SendPacket ("OK");
2360         return SendPacket ("E57");
2361     }
2362     return SendPacket ("E58");
2363 }
2364 
2365 rnb_err_t
2366 RNBRemote::HandlePacket_QSetWorkingDir (const char *p)
2367 {
2368     // Only set the working directory if we don't already have a process
2369     if (!m_ctx.HasValidProcessID())
2370     {
2371         StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);
2372         if (packet.GetHexByteString (m_ctx.GetWorkingDir()))
2373         {
2374             struct stat working_dir_stat;
2375             if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1)
2376             {
2377                 m_ctx.GetWorkingDir().clear();
2378                 return SendPacket ("E61");    // Working directory doesn't exist...
2379             }
2380             else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR)
2381             {
2382                 return SendPacket ("OK");
2383             }
2384             else
2385             {
2386                 m_ctx.GetWorkingDir().clear();
2387                 return SendPacket ("E62");    // Working directory isn't a directory...
2388             }
2389         }
2390         return SendPacket ("E59");  // Invalid path
2391     }
2392     return SendPacket ("E60"); // Already had a process, too late to set working dir
2393 }
2394 
2395 rnb_err_t
2396 RNBRemote::HandlePacket_QSyncThreadState (const char *p)
2397 {
2398     if (!m_ctx.HasValidProcessID())
2399     {
2400         // We allow gdb to connect to a server that hasn't started running
2401         // the target yet.  gdb still wants to ask questions about it and
2402         // freaks out if it gets an error.  So just return OK here.
2403         return SendPacket ("OK");
2404     }
2405 
2406     errno = 0;
2407     p += strlen("QSyncThreadState:");
2408     nub_thread_t tid = strtoul (p, NULL, 16);
2409     if (errno != 0 && tid == 0)
2410     {
2411         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet");
2412     }
2413     if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid))
2414         return SendPacket("OK");
2415     else
2416         return SendPacket ("E61");
2417 }
2418 
2419 rnb_err_t
2420 RNBRemote::HandlePacket_QSetDetachOnError (const char *p)
2421 {
2422     p += sizeof ("QSetDetachOnError:") - 1;
2423     bool should_detach = true;
2424     switch (*p)
2425     {
2426         case '0': should_detach = false; break;
2427         case '1': should_detach = true; break;
2428         default:
2429           return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid value for QSetDetachOnError - should be 0 or 1");
2430           break;
2431     }
2432 
2433     m_ctx.SetDetachOnError(should_detach);
2434     return SendPacket ("OK");
2435 }
2436 
2437 rnb_err_t
2438 RNBRemote::HandlePacket_qStructuredDataPlugins(const char *p)
2439 {
2440     // We'll return a JSON array of supported packet types.
2441     // The type is significant.  For each of the supported
2442     // packet types that have been enabled, there will be a
2443     // 'J' async packet sent to the client with payload data.
2444     // This payload data will be a JSON dictionary, and the
2445     // top level dictionary will contain a string field with
2446     // its value set to the relevant packet type from this list.
2447     JSONGenerator::Array supported_json_packets;
2448 
2449     // Check for DarwinLog (libtrace os_log/activity support).
2450     if (DarwinLogCollector::IsSupported())
2451         supported_json_packets.AddItem(JSONGenerator::StringSP(
2452             new JSONGenerator::String("DarwinLog")));
2453 
2454     // Send back the array.
2455     std::ostringstream stream;
2456     supported_json_packets.Dump(stream);
2457     return SendPacket(stream.str());
2458 }
2459 
2460 rnb_err_t
2461 RNBRemote::HandlePacket_QConfigureDarwinLog(const char *p)
2462 {
2463     if (!DarwinLogCollector::IsSupported())
2464     {
2465         // We should never have been given this request.
2466         return SendPacket ("E89");
2467     }
2468 
2469     // Ensure we have a process.  We expect a separate configure request for
2470     // each process launched/attached.
2471     const nub_process_t pid = m_ctx.ProcessID();
2472     if (pid == INVALID_NUB_PROCESS)
2473         return SendPacket ("E94");
2474 
2475     // Get the configuration dictionary.
2476     p += strlen("QConfigureDarwinLog:");
2477 
2478     // The configuration dictionary is binary encoded.
2479     std::vector<uint8_t> unescaped_config_data = decode_binary_data(p, -1);
2480     std::string unescaped_config_string((const char*)&unescaped_config_data[0],
2481                                         unescaped_config_data.size());
2482     DNBLogThreadedIf(LOG_DARWIN_LOG, "DarwinLog: received config data: \"%s\"",
2483                      unescaped_config_string.c_str());
2484     auto configuration_sp =
2485         JSONParser(unescaped_config_string.c_str()).ParseJSONValue();
2486     if (!configuration_sp)
2487     {
2488         // Malformed request - we require configuration data
2489         // indicating whether we're enabling or disabling.
2490         return SendPacket("E90");
2491     }
2492 
2493     if (!JSONObject::classof(configuration_sp.get()))
2494     {
2495         // Configuration data is not of the right type.
2496         return SendPacket("E91");
2497     }
2498     JSONObject &config_dict = *static_cast<JSONObject*>(configuration_sp.get());
2499 
2500     // Check if we're enabling or disabling.
2501     auto enabled_sp = config_dict.GetObject("enabled");
2502     if (!enabled_sp)
2503     {
2504         // Missing required "enabled" field.
2505         return SendPacket("E92");
2506     }
2507     if (!JSONTrue::classof(enabled_sp.get()) &&
2508         !JSONFalse::classof(enabled_sp.get()))
2509     {
2510         // Should be a boolean type, but wasn't.
2511         return SendPacket("E93");
2512     }
2513     const bool enabling = JSONTrue::classof(enabled_sp.get());
2514 
2515     // TODO - handle other configuration parameters here.
2516 
2517     // Shut down any active activity stream for the process.
2518     DarwinLogCollector::CancelStreamForProcess(pid);
2519 
2520     if (enabling)
2521     {
2522         // Look up the procecess.
2523         if (!DarwinLogCollector::StartCollectingForProcess(pid, config_dict))
2524             return SendPacket("E95");
2525     }
2526 
2527     return SendPacket("OK");
2528 }
2529 
2530 rnb_err_t
2531 RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p)
2532 {
2533     // If this packet is received, it allows us to send an extra key/value
2534     // pair in the stop reply packets where we will list all of the thread IDs
2535     // separated by commas:
2536     //
2537     //  "threads:10a,10b,10c;"
2538     //
2539     // This will get included in the stop reply packet as something like:
2540     //
2541     //  "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;"
2542     //
2543     // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and
2544     // speed things up a bit.
2545     //
2546     // Send the OK packet first so the correct checksum is appended...
2547     rnb_err_t result = SendPacket ("OK");
2548     m_list_threads_in_stop_reply = true;
2549 
2550     return result;
2551 }
2552 
2553 
2554 rnb_err_t
2555 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
2556 {
2557     /* The number of characters in a packet payload that gdb is
2558      prepared to accept.  The packet-start char, packet-end char,
2559      2 checksum chars and terminating null character are not included
2560      in this size.  */
2561     p += sizeof ("QSetMaxPayloadSize:") - 1;
2562     errno = 0;
2563     uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16));
2564     if (errno != 0 && size == 0)
2565     {
2566         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
2567     }
2568     m_max_payload_size = size;
2569     return SendPacket ("OK");
2570 }
2571 
2572 rnb_err_t
2573 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
2574 {
2575     /* This tells us the largest packet that gdb can handle.
2576      i.e. the size of gdb's packet-reading buffer.
2577      QSetMaxPayloadSize is preferred because it is less ambiguous.  */
2578     p += sizeof ("QSetMaxPacketSize:") - 1;
2579     errno = 0;
2580     uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16));
2581     if (errno != 0 && size == 0)
2582     {
2583         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
2584     }
2585     m_max_payload_size = size - 5;
2586     return SendPacket ("OK");
2587 }
2588 
2589 
2590 
2591 
2592 rnb_err_t
2593 RNBRemote::HandlePacket_QEnvironment (const char *p)
2594 {
2595     /* This sets the environment for the target program.  The packet is of the form:
2596 
2597      QEnvironment:VARIABLE=VALUE
2598 
2599      */
2600 
2601     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
2602                       (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2603 
2604     p += sizeof ("QEnvironment:") - 1;
2605     RNBContext& ctx = Context();
2606 
2607     ctx.PushEnvironment (p);
2608     return SendPacket ("OK");
2609 }
2610 
2611 rnb_err_t
2612 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p)
2613 {
2614     /* This sets the environment for the target program.  The packet is of the form:
2615 
2616         QEnvironmentHexEncoded:VARIABLE=VALUE
2617 
2618         The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with special
2619         meaning in the remote protocol won't break it.
2620     */
2621 
2622     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"",
2623         (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2624 
2625     p += sizeof ("QEnvironmentHexEncoded:") - 1;
2626 
2627     std::string arg;
2628     const char *c;
2629     c = p;
2630     while (*c != '\0')
2631       {
2632         if (*(c + 1) == '\0')
2633         {
2634             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2635         }
2636         char smallbuf[3];
2637         smallbuf[0] = *c;
2638         smallbuf[1] = *(c + 1);
2639         smallbuf[2] = '\0';
2640         errno = 0;
2641         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
2642         if (errno != 0 && ch == 0)
2643           {
2644             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2645           }
2646         arg.push_back(ch);
2647         c += 2;
2648       }
2649 
2650     RNBContext& ctx = Context();
2651     if (arg.length() > 0)
2652       ctx.PushEnvironment (arg.c_str());
2653 
2654     return SendPacket ("OK");
2655 }
2656 
2657 
2658 rnb_err_t
2659 RNBRemote::HandlePacket_QLaunchArch (const char *p)
2660 {
2661     p += sizeof ("QLaunchArch:") - 1;
2662     if (DNBSetArchitecture(p))
2663         return SendPacket ("OK");
2664     return SendPacket ("E63");
2665 }
2666 
2667 rnb_err_t
2668 RNBRemote::HandlePacket_QSetProcessEvent (const char *p)
2669 {
2670     p += sizeof ("QSetProcessEvent:") - 1;
2671     // If the process is running, then send the event to the process, otherwise
2672     // store it in the context.
2673     if (Context().HasValidProcessID())
2674     {
2675         if (DNBProcessSendEvent (Context().ProcessID(), p))
2676             return SendPacket("OK");
2677         else
2678             return SendPacket ("E80");
2679     }
2680     else
2681     {
2682         Context().PushProcessEvent(p);
2683     }
2684     return SendPacket ("OK");
2685 }
2686 
2687 void
2688 append_hex_value (std::ostream& ostrm, const void *buf, size_t buf_size, bool swap)
2689 {
2690     int i;
2691     const uint8_t *p = (const uint8_t *)buf;
2692     if (swap)
2693     {
2694         for (i = static_cast<int>(buf_size)-1; i >= 0; i--)
2695             ostrm << RAWHEX8(p[i]);
2696     }
2697     else
2698     {
2699         for (size_t i = 0; i < buf_size; i++)
2700             ostrm << RAWHEX8(p[i]);
2701     }
2702 }
2703 
2704 void
2705 append_hexified_string (std::ostream& ostrm, const std::string &string)
2706 {
2707     size_t string_size = string.size();
2708     const char *string_buf = string.c_str();
2709     for (size_t i = 0; i < string_size; i++)
2710     {
2711             ostrm << RAWHEX8(*(string_buf + i));
2712     }
2713 }
2714 
2715 
2716 
2717 void
2718 register_value_in_hex_fixed_width (std::ostream& ostrm,
2719                                    nub_process_t pid,
2720                                    nub_thread_t tid,
2721                                    const register_map_entry_t* reg,
2722                                    const DNBRegisterValue *reg_value_ptr)
2723 {
2724     if (reg != NULL)
2725     {
2726         DNBRegisterValue reg_value;
2727         if (reg_value_ptr == NULL)
2728         {
2729             if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &reg_value))
2730                 reg_value_ptr = &reg_value;
2731         }
2732 
2733         if (reg_value_ptr)
2734         {
2735             append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false);
2736         }
2737         else
2738         {
2739             // If we fail to read a register value, check if it has a default
2740             // fail value. If it does, return this instead in case some of
2741             // the registers are not available on the current system.
2742             if (reg->nub_info.size > 0)
2743             {
2744                 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0');
2745                 append_hex_value (ostrm, zeros.data(), zeros.size(), false);
2746             }
2747         }
2748     }
2749 }
2750 
2751 
2752 void
2753 debugserver_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
2754                                                 nub_process_t pid,
2755                                                 nub_thread_t tid,
2756                                                 const register_map_entry_t* reg,
2757                                                 const DNBRegisterValue *reg_value_ptr)
2758 {
2759     // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
2760     // gdb register number, and VVVVVVVV is the correct number of hex bytes
2761     // as ASCII for the register value.
2762     if (reg != NULL)
2763     {
2764         ostrm << RAWHEX8(reg->debugserver_regnum) << ':';
2765         register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr);
2766         ostrm << ';';
2767     }
2768 }
2769 
2770 
2771 void
2772 RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid,
2773                                                      nub_addr_t dispatch_qaddr,
2774                                                      nub_addr_t &dispatch_queue_t,
2775                                                      std::string &queue_name,
2776                                                      uint64_t &queue_width,
2777                                                      uint64_t &queue_serialnum) const
2778 {
2779     queue_name.clear();
2780     queue_width = 0;
2781     queue_serialnum = 0;
2782 
2783     if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && dispatch_qaddr != 0)
2784     {
2785         dispatch_queue_t = DNBProcessMemoryReadPointer (pid, dispatch_qaddr);
2786         if (dispatch_queue_t)
2787         {
2788             queue_width = DNBProcessMemoryReadInteger (pid, dispatch_queue_t + dqo_width, dqo_width_size, 0);
2789             queue_serialnum = DNBProcessMemoryReadInteger (pid, dispatch_queue_t + dqo_serialnum, dqo_serialnum_size, 0);
2790 
2791             if (dqo_version >= 4)
2792             {
2793                 // libdispatch versions 4+, pointer to dispatch name is in the
2794                 // queue structure.
2795                 nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label;
2796                 nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address);
2797                 if (label_addr)
2798                     queue_name = DNBProcessMemoryReadCString(pid, label_addr);
2799             }
2800             else
2801             {
2802                 // libdispatch versions 1-3, dispatch name is a fixed width char array
2803                 // in the queue structure.
2804                 queue_name = DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size);
2805             }
2806         }
2807     }
2808 }
2809 
2810 struct StackMemory
2811 {
2812     uint8_t bytes[2*sizeof(nub_addr_t)];
2813     nub_size_t length;
2814 };
2815 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap;
2816 
2817 
2818 static void
2819 ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap, uint32_t backtrace_limit = 256)
2820 {
2821     DNBRegisterValue reg_value;
2822     if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, &reg_value))
2823     {
2824         uint32_t frame_count = 0;
2825         uint64_t fp = 0;
2826         if (reg_value.info.size == 4)
2827             fp = reg_value.value.uint32;
2828         else
2829             fp = reg_value.value.uint64;
2830         while (fp != 0)
2831         {
2832             // Make sure we never recurse more than 256 times so we don't recurse too far or
2833             // store up too much memory in the expedited cache
2834             if (++frame_count > backtrace_limit)
2835                 break;
2836 
2837             const nub_size_t read_size = reg_value.info.size*2;
2838             StackMemory stack_memory;
2839             stack_memory.length = read_size;
2840             if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size)
2841                 break;
2842             // Make sure we don't try to put the same stack memory in more than once
2843             if (stack_mmap.find(fp) != stack_mmap.end())
2844                 break;
2845             // Put the entry into the cache
2846             stack_mmap[fp] = stack_memory;
2847             // Dereference the frame pointer to get to the previous frame pointer
2848             if (reg_value.info.size == 4)
2849                 fp = ((uint32_t *)stack_memory.bytes)[0];
2850             else
2851                 fp = ((uint64_t *)stack_memory.bytes)[0];
2852         }
2853     }
2854 }
2855 
2856 rnb_err_t
2857 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
2858 {
2859     const nub_process_t pid = m_ctx.ProcessID();
2860     if (pid == INVALID_NUB_PROCESS)
2861         return SendPacket("E50");
2862 
2863     struct DNBThreadStopInfo tid_stop_info;
2864 
2865     /* Fill the remaining space in this packet with as many registers
2866      as we can stuff in there.  */
2867 
2868     if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
2869     {
2870         const bool did_exec = tid_stop_info.reason == eStopTypeExec;
2871         if (did_exec)
2872         {
2873             RNBRemote::InitializeRegisters(true);
2874 
2875             // Reset any symbols that need resetting when we exec
2876             m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS;
2877             m_dispatch_queue_offsets.Clear();
2878         }
2879 
2880         std::ostringstream ostrm;
2881         // Output the T packet with the thread
2882         ostrm << 'T';
2883         int signum = tid_stop_info.details.signal.signo;
2884         DNBLogThreadedIf (LOG_RNB_PROC, "%8d %s got signal signo = %u, exc_type = %u", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, signum, tid_stop_info.details.exception.type);
2885 
2886         // Translate any mach exceptions to gdb versions, unless they are
2887         // common exceptions like a breakpoint or a soft signal.
2888         switch (tid_stop_info.details.exception.type)
2889         {
2890             default:                    signum = 0; break;
2891             case EXC_BREAKPOINT:        signum = SIGTRAP; break;
2892             case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2893             case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2894             case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2895             case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2896             case EXC_SOFTWARE:
2897                 if (tid_stop_info.details.exception.data_count == 2 &&
2898                     tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2899                     signum = static_cast<int>(tid_stop_info.details.exception.data[1]);
2900                 else
2901                     signum = TARGET_EXC_SOFTWARE;
2902                 break;
2903         }
2904 
2905         ostrm << RAWHEX8(signum & 0xff);
2906 
2907         ostrm << std::hex << "thread:" << tid << ';';
2908 
2909         const char *thread_name = DNBThreadGetName (pid, tid);
2910         if (thread_name && thread_name[0])
2911         {
2912             size_t thread_name_len = strlen(thread_name);
2913 
2914 
2915             if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2916                 ostrm << std::hex << "name:" << thread_name << ';';
2917             else
2918             {
2919                 // the thread name contains special chars, send as hex bytes
2920                 ostrm << std::hex << "hexname:";
2921                 uint8_t *u_thread_name = (uint8_t *)thread_name;
2922                 for (size_t i = 0; i < thread_name_len; i++)
2923                     ostrm << RAWHEX8(u_thread_name[i]);
2924                 ostrm << ';';
2925             }
2926         }
2927 
2928         // If a 'QListThreadsInStopReply' was sent to enable this feature, we
2929         // will send all thread IDs back in the "threads" key whose value is
2930         // a list of hex thread IDs separated by commas:
2931         //  "threads:10a,10b,10c;"
2932         // This will save the debugger from having to send a pair of qfThreadInfo
2933         // and qsThreadInfo packets, but it also might take a lot of room in the
2934         // stop reply packet, so it must be enabled only on systems where there
2935         // are no limits on packet lengths.
2936         if (m_list_threads_in_stop_reply)
2937         {
2938             const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
2939             if (numthreads > 0)
2940             {
2941                 std::vector<uint64_t> pc_values;
2942                 ostrm << std::hex << "threads:";
2943                 for (nub_size_t i = 0; i < numthreads; ++i)
2944                 {
2945                     nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
2946                     if (i > 0)
2947                         ostrm << ',';
2948                     ostrm << std::hex << th;
2949                     DNBRegisterValue pc_regval;
2950                     if (DNBThreadGetRegisterValueByID (pid, th, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_regval))
2951                     {
2952                         uint64_t pc = INVALID_NUB_ADDRESS;
2953                         if (pc_regval.value.uint64 != INVALID_NUB_ADDRESS)
2954                         {
2955                             if (pc_regval.info.size == 4)
2956                             {
2957                                 pc = pc_regval.value.uint32;
2958                             }
2959                             else if (pc_regval.info.size == 8)
2960                             {
2961                                 pc = pc_regval.value.uint64;
2962                             }
2963                             if (pc != INVALID_NUB_ADDRESS)
2964                             {
2965                                 pc_values.push_back (pc);
2966                             }
2967                         }
2968                     }
2969                 }
2970                 ostrm << ';';
2971 
2972                 // If we failed to get any of the thread pc values, the size of our vector will not
2973                 // be the same as the # of threads.  Don't provide any expedited thread pc values in
2974                 // that case.  This should not happen.
2975                 if (pc_values.size() == numthreads)
2976                 {
2977                     ostrm << std::hex << "thread-pcs:";
2978                     for (nub_size_t i = 0; i < numthreads; ++i)
2979                     {
2980                         if (i > 0)
2981                             ostrm << ',';
2982                         ostrm << std::hex << pc_values[i];
2983                     }
2984                     ostrm << ';';
2985                 }
2986             }
2987 
2988             // Include JSON info that describes the stop reason for any threads
2989             // that actually have stop reasons. We use the new "jstopinfo" key
2990             // whose values is hex ascii JSON that contains the thread IDs
2991             // thread stop info only for threads that have stop reasons. Only send
2992             // this if we have more than one thread otherwise this packet has all
2993             // the info it needs.
2994             if (numthreads > 1)
2995             {
2996                 const bool threads_with_valid_stop_info_only = true;
2997                 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only);
2998                 if (threads_info_sp)
2999                 {
3000                     ostrm << std::hex << "jstopinfo:";
3001                     std::ostringstream json_strm;
3002                     threads_info_sp->Dump (json_strm);
3003                     append_hexified_string (ostrm, json_strm.str());
3004                     ostrm << ';';
3005                 }
3006             }
3007         }
3008 
3009         if (g_num_reg_entries == 0)
3010             InitializeRegisters ();
3011 
3012         if (g_reg_entries != NULL)
3013         {
3014             DNBRegisterValue reg_value;
3015             for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
3016             {
3017                 // Expedite all registers in the first register set that aren't
3018                 // contained in other registers
3019                 if (g_reg_entries[reg].nub_info.set == 1 &&
3020                     g_reg_entries[reg].nub_info.value_regs == NULL)
3021                 {
3022                     if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
3023                         continue;
3024 
3025                     debugserver_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], &reg_value);
3026                 }
3027             }
3028         }
3029 
3030         if (did_exec)
3031         {
3032             ostrm << "reason:exec;";
3033         }
3034         else if (tid_stop_info.details.exception.type)
3035         {
3036             ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';';
3037             ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';';
3038             for (nub_size_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
3039                 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';';
3040         }
3041 
3042         // Add expedited stack memory so stack backtracing doesn't need to read anything from the
3043         // frame pointer chain.
3044         StackMemoryMap stack_mmap;
3045         ReadStackMemory (pid, tid, stack_mmap, 2);
3046         if (!stack_mmap.empty())
3047         {
3048             for (const auto &stack_memory : stack_mmap)
3049             {
3050                 ostrm << "memory:" << HEXBASE << stack_memory.first << '=';
3051                 append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false);
3052                 ostrm << ';';
3053             }
3054         }
3055 
3056         return SendPacket (ostrm.str ());
3057     }
3058     return SendPacket("E51");
3059 }
3060 
3061 /* '?'
3062  The stop reply packet - tell gdb what the status of the inferior is.
3063  Often called the questionmark_packet.  */
3064 
3065 rnb_err_t
3066 RNBRemote::HandlePacket_last_signal (const char *unused)
3067 {
3068     if (!m_ctx.HasValidProcessID())
3069     {
3070         // Inferior is not yet specified/running
3071         return SendPacket ("E02");
3072     }
3073 
3074     nub_process_t pid = m_ctx.ProcessID();
3075     nub_state_t pid_state = DNBProcessGetState (pid);
3076 
3077     switch (pid_state)
3078     {
3079         case eStateAttaching:
3080         case eStateLaunching:
3081         case eStateRunning:
3082         case eStateStepping:
3083         case eStateDetached:
3084             return rnb_success;  // Ignore
3085 
3086         case eStateSuspended:
3087         case eStateStopped:
3088         case eStateCrashed:
3089             {
3090                 nub_thread_t tid = DNBProcessGetCurrentThread (pid);
3091                 // Make sure we set the current thread so g and p packets return
3092                 // the data the gdb will expect.
3093                 SetCurrentThread (tid);
3094 
3095                 SendStopReplyPacketForThread (tid);
3096             }
3097             break;
3098 
3099         case eStateInvalid:
3100         case eStateUnloaded:
3101         case eStateExited:
3102             {
3103                 char pid_exited_packet[16] = "";
3104                 int pid_status = 0;
3105                 // Process exited with exit status
3106                 if (!DNBProcessGetExitStatus(pid, &pid_status))
3107                     pid_status = 0;
3108 
3109                 if (pid_status)
3110                 {
3111                     if (WIFEXITED (pid_status))
3112                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
3113                     else if (WIFSIGNALED (pid_status))
3114                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
3115                     else if (WIFSTOPPED (pid_status))
3116                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
3117                 }
3118 
3119                 // If we have an empty exit packet, lets fill one in to be safe.
3120                 if (!pid_exited_packet[0])
3121                 {
3122                     strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
3123                     pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
3124                 }
3125 
3126                 const char *exit_info = DNBProcessGetExitInfo (pid);
3127                 if (exit_info != NULL && *exit_info != '\0')
3128                 {
3129                     std::ostringstream exit_packet;
3130                     exit_packet << pid_exited_packet;
3131                     exit_packet << ';';
3132                     exit_packet << RAW_HEXBASE << "description";
3133                     exit_packet << ':';
3134                     for (size_t i = 0; exit_info[i] != '\0'; i++)
3135                         exit_packet << RAWHEX8(exit_info[i]);
3136                     exit_packet << ';';
3137                     return SendPacket (exit_packet.str());
3138                 }
3139                 else
3140                     return SendPacket (pid_exited_packet);
3141             }
3142             break;
3143     }
3144     return rnb_success;
3145 }
3146 
3147 rnb_err_t
3148 RNBRemote::HandlePacket_M (const char *p)
3149 {
3150     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3151     {
3152         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
3153     }
3154 
3155     char *c;
3156     p++;
3157     errno = 0;
3158     nub_addr_t addr = strtoull (p, &c, 16);
3159     if (errno != 0 && addr == 0)
3160     {
3161         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
3162     }
3163     if (*c != ',')
3164     {
3165         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
3166     }
3167 
3168     /* Advance 'p' to the length part of the packet.  */
3169     p += (c - p) + 1;
3170 
3171     errno = 0;
3172     unsigned long length = strtoul (p, &c, 16);
3173     if (errno != 0 && length == 0)
3174     {
3175         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
3176     }
3177     if (length == 0)
3178     {
3179         return SendPacket ("OK");
3180     }
3181 
3182     if (*c != ':')
3183     {
3184         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
3185     }
3186     /* Advance 'p' to the data part of the packet.  */
3187     p += (c - p) + 1;
3188 
3189     size_t datalen = strlen (p);
3190     if (datalen & 0x1)
3191     {
3192         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
3193     }
3194     if (datalen == 0)
3195     {
3196         return SendPacket ("OK");
3197     }
3198 
3199     uint8_t *buf = (uint8_t *) alloca (datalen / 2);
3200     uint8_t *i = buf;
3201 
3202     while (*p != '\0' && *(p + 1) != '\0')
3203     {
3204         char hexbuf[3];
3205         hexbuf[0] = *p;
3206         hexbuf[1] = *(p + 1);
3207         hexbuf[2] = '\0';
3208         errno = 0;
3209         uint8_t byte = strtoul (hexbuf, NULL, 16);
3210         if (errno != 0 && byte == 0)
3211         {
3212             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
3213         }
3214         *i++ = byte;
3215         p += 2;
3216     }
3217 
3218     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
3219     if (wrote != length)
3220         return SendPacket ("E09");
3221     else
3222         return SendPacket ("OK");
3223 }
3224 
3225 
3226 rnb_err_t
3227 RNBRemote::HandlePacket_m (const char *p)
3228 {
3229     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3230     {
3231         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
3232     }
3233 
3234     char *c;
3235     p++;
3236     errno = 0;
3237     nub_addr_t addr = strtoull (p, &c, 16);
3238     if (errno != 0 && addr == 0)
3239     {
3240         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
3241     }
3242     if (*c != ',')
3243     {
3244         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
3245     }
3246 
3247     /* Advance 'p' to the length part of the packet.  */
3248     p += (c - p) + 1;
3249 
3250     errno = 0;
3251     auto length = strtoul (p, NULL, 16);
3252     if (errno != 0 && length == 0)
3253     {
3254         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
3255     }
3256     if (length == 0)
3257     {
3258         return SendPacket ("");
3259     }
3260 
3261     std::string buf(length, '\0');
3262     if (buf.empty())
3263     {
3264         return SendPacket ("E78");
3265     }
3266     nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
3267     if (bytes_read == 0)
3268     {
3269         return SendPacket ("E08");
3270     }
3271 
3272     // "The reply may contain fewer bytes than requested if the server was able
3273     //  to read only part of the region of memory."
3274     length = bytes_read;
3275 
3276     std::ostringstream ostrm;
3277     for (unsigned long i = 0; i < length; i++)
3278         ostrm << RAWHEX8(buf[i]);
3279     return SendPacket (ostrm.str ());
3280 }
3281 
3282 // Read memory, sent it up as binary data.
3283 // Usage:  xADDR,LEN
3284 // ADDR and LEN are both base 16.
3285 
3286 // Responds with 'OK' for zero-length request
3287 // or
3288 //
3289 // DATA
3290 //
3291 // where DATA is the binary data payload.
3292 
3293 rnb_err_t
3294 RNBRemote::HandlePacket_x (const char *p)
3295 {
3296     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3297     {
3298         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
3299     }
3300 
3301     char *c;
3302     p++;
3303     errno = 0;
3304     nub_addr_t addr = strtoull (p, &c, 16);
3305     if (errno != 0)
3306     {
3307         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
3308     }
3309     if (*c != ',')
3310     {
3311         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
3312     }
3313 
3314     /* Advance 'p' to the number of bytes to be read.  */
3315     p += (c - p) + 1;
3316 
3317     errno = 0;
3318     auto length = strtoul (p, NULL, 16);
3319     if (errno != 0)
3320     {
3321         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet");
3322     }
3323 
3324     // zero length read means this is a test of whether that packet is implemented or not.
3325     if (length == 0)
3326     {
3327         return SendPacket ("OK");
3328     }
3329 
3330     std::vector<uint8_t> buf (length);
3331 
3332     if (buf.capacity() != length)
3333     {
3334         return SendPacket ("E79");
3335     }
3336     nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
3337     if (bytes_read == 0)
3338     {
3339         return SendPacket ("E80");
3340     }
3341 
3342     std::vector<uint8_t> buf_quoted;
3343     buf_quoted.reserve (bytes_read + 30);
3344     for (nub_size_t i = 0; i < bytes_read; i++)
3345     {
3346         if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*')
3347         {
3348             buf_quoted.push_back(0x7d);
3349             buf_quoted.push_back(buf[i] ^ 0x20);
3350         }
3351         else
3352         {
3353             buf_quoted.push_back(buf[i]);
3354         }
3355     }
3356     length = buf_quoted.size();
3357 
3358     std::ostringstream ostrm;
3359     for (unsigned long i = 0; i < length; i++)
3360         ostrm << buf_quoted[i];
3361 
3362     return SendPacket (ostrm.str ());
3363 }
3364 
3365 rnb_err_t
3366 RNBRemote::HandlePacket_X (const char *p)
3367 {
3368     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3369     {
3370         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
3371     }
3372 
3373     char *c;
3374     p++;
3375     errno = 0;
3376     nub_addr_t addr = strtoull (p, &c, 16);
3377     if (errno != 0 && addr == 0)
3378     {
3379         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
3380     }
3381     if (*c != ',')
3382     {
3383         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
3384     }
3385 
3386     /* Advance 'p' to the length part of the packet.  NB this is the length of the packet
3387        including any escaped chars.  The data payload may be a little bit smaller after
3388        decoding.  */
3389     p += (c - p) + 1;
3390 
3391     errno = 0;
3392     auto length = strtoul (p, NULL, 16);
3393     if (errno != 0 && length == 0)
3394     {
3395         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet");
3396     }
3397 
3398     // I think gdb sends a zero length write request to test whether this
3399     // packet is accepted.
3400     if (length == 0)
3401     {
3402         return SendPacket ("OK");
3403     }
3404 
3405     std::vector<uint8_t> data = decode_binary_data (c, -1);
3406     std::vector<uint8_t>::const_iterator it;
3407     uint8_t *buf = (uint8_t *) alloca (data.size ());
3408     uint8_t *i = buf;
3409     for (it = data.begin (); it != data.end (); ++it)
3410     {
3411         *i++ = *it;
3412     }
3413 
3414     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
3415     if (wrote != data.size ())
3416         return SendPacket ("E08");
3417     return SendPacket ("OK");
3418 }
3419 
3420 /* 'g' -- read registers
3421  Get the contents of the registers for the current thread,
3422  send them to gdb.
3423  Should the setting of the Hg packet determine which thread's registers
3424  are returned?  */
3425 
3426 rnb_err_t
3427 RNBRemote::HandlePacket_g (const char *p)
3428 {
3429     std::ostringstream ostrm;
3430     if (!m_ctx.HasValidProcessID())
3431     {
3432         return SendPacket ("E11");
3433     }
3434 
3435     if (g_num_reg_entries == 0)
3436         InitializeRegisters ();
3437 
3438     nub_process_t pid = m_ctx.ProcessID ();
3439     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
3440     if (tid == INVALID_NUB_THREAD)
3441         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3442 
3443     // Get the register context size first by calling with NULL buffer
3444     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
3445     if (reg_ctx_size)
3446     {
3447         // Now allocate enough space for the entire register context
3448         std::vector<uint8_t> reg_ctx;
3449         reg_ctx.resize(reg_ctx_size);
3450         // Now read the register context
3451         reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
3452         if (reg_ctx_size)
3453         {
3454             append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
3455             return SendPacket (ostrm.str ());
3456         }
3457     }
3458     return SendPacket ("E74");
3459 }
3460 
3461 /* 'G XXX...' -- write registers
3462  How is the thread for these specified, beyond "the current thread"?
3463  Does gdb actually use the Hg packet to set this?  */
3464 
3465 rnb_err_t
3466 RNBRemote::HandlePacket_G (const char *p)
3467 {
3468     if (!m_ctx.HasValidProcessID())
3469     {
3470         return SendPacket ("E11");
3471     }
3472 
3473     if (g_num_reg_entries == 0)
3474         InitializeRegisters ();
3475 
3476     StringExtractor packet(p);
3477     packet.SetFilePos(1); // Skip the 'G'
3478 
3479     nub_process_t pid = m_ctx.ProcessID();
3480     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3481     if (tid == INVALID_NUB_THREAD)
3482         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3483 
3484     // Get the register context size first by calling with NULL buffer
3485     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
3486     if (reg_ctx_size)
3487     {
3488         // Now allocate enough space for the entire register context
3489         std::vector<uint8_t> reg_ctx;
3490         reg_ctx.resize(reg_ctx_size);
3491 
3492         const nub_size_t bytes_extracted = packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc);
3493         if (bytes_extracted == reg_ctx.size())
3494         {
3495             // Now write the register context
3496             reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
3497             if (reg_ctx_size == reg_ctx.size())
3498                 return SendPacket ("OK");
3499             else
3500                 return SendPacket ("E55");
3501         }
3502         else
3503         {
3504             DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size);
3505             return SendPacket ("E64");
3506         }
3507     }
3508     return SendPacket ("E65");
3509 }
3510 
3511 static bool
3512 RNBRemoteShouldCancelCallback (void *not_used)
3513 {
3514     RNBRemoteSP remoteSP(g_remoteSP);
3515     if (remoteSP.get() != NULL)
3516     {
3517         RNBRemote* remote = remoteSP.get();
3518         if (remote->Comm().IsConnected())
3519             return false;
3520         else
3521             return true;
3522     }
3523     return true;
3524 }
3525 
3526 
3527 // FORMAT: _MXXXXXX,PPP
3528 //      XXXXXX: big endian hex chars
3529 //      PPP: permissions can be any combo of r w x chars
3530 //
3531 // RESPONSE: XXXXXX
3532 //      XXXXXX: hex address of the newly allocated memory
3533 //      EXX: error code
3534 //
3535 // EXAMPLES:
3536 //      _M123000,rw
3537 //      _M123000,rwx
3538 //      _M123000,xw
3539 
3540 rnb_err_t
3541 RNBRemote::HandlePacket_AllocateMemory (const char *p)
3542 {
3543     StringExtractor packet (p);
3544     packet.SetFilePos(2); // Skip the "_M"
3545 
3546     nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
3547     if (size != 0)
3548     {
3549         if (packet.GetChar() == ',')
3550         {
3551             uint32_t permissions = 0;
3552             char ch;
3553             bool success = true;
3554             while (success && (ch = packet.GetChar()) != '\0')
3555             {
3556                 switch (ch)
3557                 {
3558                 case 'r':   permissions |= eMemoryPermissionsReadable; break;
3559                 case 'w':   permissions |= eMemoryPermissionsWritable; break;
3560                 case 'x':   permissions |= eMemoryPermissionsExecutable; break;
3561                 default:    success = false; break;
3562                 }
3563             }
3564 
3565             if (success)
3566             {
3567                 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
3568                 if (addr != INVALID_NUB_ADDRESS)
3569                 {
3570                     std::ostringstream ostrm;
3571                     ostrm << RAW_HEXBASE << addr;
3572                     return SendPacket (ostrm.str ());
3573                 }
3574             }
3575         }
3576     }
3577     return SendPacket ("E53");
3578 }
3579 
3580 // FORMAT: _mXXXXXX
3581 //      XXXXXX: address that was previously allocated
3582 //
3583 // RESPONSE: XXXXXX
3584 //      OK: address was deallocated
3585 //      EXX: error code
3586 //
3587 // EXAMPLES:
3588 //      _m123000
3589 
3590 rnb_err_t
3591 RNBRemote::HandlePacket_DeallocateMemory (const char *p)
3592 {
3593     StringExtractor packet (p);
3594     packet.SetFilePos(2); // Skip the "_m"
3595     nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
3596 
3597     if (addr != INVALID_NUB_ADDRESS)
3598     {
3599         if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
3600             return SendPacket ("OK");
3601     }
3602     return SendPacket ("E54");
3603 }
3604 
3605 
3606 // FORMAT: QSaveRegisterState;thread:TTTT;  (when thread suffix is supported)
3607 // FORMAT: QSaveRegisterState               (when thread suffix is NOT supported)
3608 //      TTTT: thread ID in hex
3609 //
3610 // RESPONSE:
3611 //      SAVEID: Where SAVEID is a decimal number that represents the save ID
3612 //              that can be passed back into a "QRestoreRegisterState" packet
3613 //      EXX: error code
3614 //
3615 // EXAMPLES:
3616 //      QSaveRegisterState;thread:1E34;     (when thread suffix is supported)
3617 //      QSaveRegisterState                  (when thread suffix is NOT supported)
3618 
3619 rnb_err_t
3620 RNBRemote::HandlePacket_SaveRegisterState (const char *p)
3621 {
3622     nub_process_t pid = m_ctx.ProcessID ();
3623     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3624     if (tid == INVALID_NUB_THREAD)
3625     {
3626         if (m_thread_suffix_supported)
3627             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
3628         else
3629             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
3630     }
3631 
3632     // Get the register context size first by calling with NULL buffer
3633     const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid);
3634     if (save_id != 0)
3635     {
3636         char response[64];
3637         snprintf (response, sizeof(response), "%u", save_id);
3638         return SendPacket (response);
3639     }
3640     else
3641     {
3642         return SendPacket ("E75");
3643     }
3644 }
3645 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT;  (when thread suffix is supported)
3646 // FORMAT: QRestoreRegisterState:SAVEID               (when thread suffix is NOT supported)
3647 //      TTTT: thread ID in hex
3648 //      SAVEID: a decimal number that represents the save ID that was
3649 //              returned from a call to "QSaveRegisterState"
3650 //
3651 // RESPONSE:
3652 //      OK: successfully restored registers for the specified thread
3653 //      EXX: error code
3654 //
3655 // EXAMPLES:
3656 //      QRestoreRegisterState:1;thread:1E34;     (when thread suffix is supported)
3657 //      QRestoreRegisterState:1                  (when thread suffix is NOT supported)
3658 
3659 rnb_err_t
3660 RNBRemote::HandlePacket_RestoreRegisterState (const char *p)
3661 {
3662     nub_process_t pid = m_ctx.ProcessID ();
3663     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3664     if (tid == INVALID_NUB_THREAD)
3665     {
3666         if (m_thread_suffix_supported)
3667             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
3668         else
3669             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
3670     }
3671 
3672     StringExtractor packet (p);
3673     packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:"
3674     const uint32_t save_id = packet.GetU32(0);
3675 
3676     if (save_id != 0)
3677     {
3678         // Get the register context size first by calling with NULL buffer
3679         if (DNBThreadRestoreRegisterState(pid, tid, save_id))
3680             return SendPacket ("OK");
3681         else
3682             return SendPacket ("E77");
3683     }
3684     return SendPacket ("E76");
3685 }
3686 
3687 static bool
3688 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name)
3689 {
3690     bool return_val = true;
3691     while (*p != '\0')
3692     {
3693         char smallbuf[3];
3694         smallbuf[0] = *p;
3695         smallbuf[1] = *(p + 1);
3696         smallbuf[2] = '\0';
3697 
3698         errno = 0;
3699         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
3700         if (errno != 0 && ch == 0)
3701         {
3702             return_val = false;
3703             break;
3704         }
3705 
3706         attach_name.push_back(ch);
3707         p += 2;
3708     }
3709     return return_val;
3710 }
3711 
3712 rnb_err_t
3713 RNBRemote::HandlePacket_qSupported (const char *p)
3714 {
3715     uint32_t max_packet_size = 128 * 1024;  // 128KBytes is a reasonable max packet size--debugger can always use less
3716     char buf[256];
3717     snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", max_packet_size);
3718 
3719     // By default, don't enable compression.  It's only worth doing when we are working
3720     // with a low speed communication channel.
3721     bool enable_compression = false;
3722     (void)enable_compression;
3723 
3724     // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth.
3725 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
3726     enable_compression = true;
3727 #endif
3728 
3729 #if defined (HAVE_LIBCOMPRESSION)
3730     // libcompression is weak linked so test if compression_decode_buffer() is available
3731     if (enable_compression && compression_decode_buffer != NULL)
3732     {
3733         strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize=");
3734         char numbuf[16];
3735         snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize);
3736         numbuf[sizeof (numbuf) - 1] = '\0';
3737         strcat (buf, numbuf);
3738     }
3739 #elif defined (HAVE_LIBZ)
3740     if (enable_compression)
3741     {
3742         strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize=");
3743         char numbuf[16];
3744         snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize);
3745         numbuf[sizeof (numbuf) - 1] = '\0';
3746         strcat (buf, numbuf);
3747     }
3748 #endif
3749 
3750     return SendPacket (buf);
3751 }
3752 
3753 /*
3754  vAttach;pid
3755 
3756  Attach to a new process with the specified process ID. pid is a hexadecimal integer
3757  identifying the process. If the stub is currently controlling a process, it is
3758  killed. The attached process is stopped.This packet is only available in extended
3759  mode (see extended mode).
3760 
3761  Reply:
3762  "ENN"                      for an error
3763  "Any Stop Reply Packet"     for success
3764  */
3765 
3766 rnb_err_t
3767 RNBRemote::HandlePacket_v (const char *p)
3768 {
3769     if (strcmp (p, "vCont;c") == 0)
3770     {
3771         // Simple continue
3772         return RNBRemote::HandlePacket_c("c");
3773     }
3774     else if (strcmp (p, "vCont;s") == 0)
3775     {
3776         // Simple step
3777         return RNBRemote::HandlePacket_s("s");
3778     }
3779     else if (strstr (p, "vCont") == p)
3780     {
3781         DNBThreadResumeActions thread_actions;
3782         char *c = (char *)(p += strlen("vCont"));
3783         char *c_end = c + strlen(c);
3784         if (*c == '?')
3785             return SendPacket ("vCont;c;C;s;S");
3786 
3787         while (c < c_end && *c == ';')
3788         {
3789             ++c;    // Skip the semi-colon
3790             DNBThreadResumeAction thread_action;
3791             thread_action.tid = INVALID_NUB_THREAD;
3792             thread_action.state = eStateInvalid;
3793             thread_action.signal = 0;
3794             thread_action.addr = INVALID_NUB_ADDRESS;
3795 
3796             char action = *c++;
3797 
3798             switch (action)
3799             {
3800                 case 'C':
3801                     errno = 0;
3802                     thread_action.signal = static_cast<int>(strtoul (c, &c, 16));
3803                     if (errno != 0)
3804                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
3805                     // Fall through to next case...
3806 
3807                 case 'c':
3808                     // Continue
3809                     thread_action.state = eStateRunning;
3810                     break;
3811 
3812                 case 'S':
3813                     errno = 0;
3814                     thread_action.signal = static_cast<int>(strtoul (c, &c, 16));
3815                     if (errno != 0)
3816                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
3817                     // Fall through to next case...
3818 
3819                 case 's':
3820                     // Step
3821                     thread_action.state = eStateStepping;
3822                     break;
3823 
3824                 default:
3825                     HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
3826                     break;
3827             }
3828             if (*c == ':')
3829             {
3830                 errno = 0;
3831                 thread_action.tid = strtoul (++c, &c, 16);
3832                 if (errno != 0)
3833                     return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
3834             }
3835 
3836             thread_actions.Append (thread_action);
3837         }
3838 
3839         // If a default action for all other threads wasn't mentioned
3840         // then we should stop the threads
3841         thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3842         DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
3843         return rnb_success;
3844     }
3845     else if (strstr (p, "vAttach") == p)
3846     {
3847         nub_process_t attach_pid = INVALID_NUB_PROCESS;        // attach_pid will be set to 0 if the attach fails
3848         nub_process_t pid_attaching_to = INVALID_NUB_PROCESS;  // pid_attaching_to is the original pid specified
3849         char err_str[1024]={'\0'};
3850         std::string attach_name;
3851 
3852         if (strstr (p, "vAttachWait;") == p)
3853         {
3854             p += strlen("vAttachWait;");
3855             if (!GetProcessNameFrom_vAttach(p, attach_name))
3856             {
3857                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
3858             }
3859             const bool ignore_existing = true;
3860             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
3861 
3862         }
3863         else if (strstr (p, "vAttachOrWait;") == p)
3864         {
3865             p += strlen("vAttachOrWait;");
3866             if (!GetProcessNameFrom_vAttach(p, attach_name))
3867             {
3868                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt");
3869             }
3870             const bool ignore_existing = false;
3871             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
3872         }
3873         else if (strstr (p, "vAttachName;") == p)
3874         {
3875             p += strlen("vAttachName;");
3876             if (!GetProcessNameFrom_vAttach(p, attach_name))
3877             {
3878                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
3879             }
3880 
3881             attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
3882 
3883         }
3884         else if (strstr (p, "vAttach;") == p)
3885         {
3886             p += strlen("vAttach;");
3887             char *end = NULL;
3888             pid_attaching_to = static_cast<int>(strtoul (p, &end, 16));    // PID will be in hex, so use base 16 to decode
3889             if (p != end && *end == '\0')
3890             {
3891                 // Wait at most 30 second for attach
3892                 struct timespec attach_timeout_abstime;
3893                 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
3894                 attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime, err_str, sizeof(err_str));
3895             }
3896         }
3897         else
3898         {
3899             return HandlePacket_UNIMPLEMENTED(p);
3900         }
3901 
3902 
3903         if (attach_pid != INVALID_NUB_PROCESS)
3904         {
3905             if (m_ctx.ProcessID() != attach_pid)
3906                 m_ctx.SetProcessID(attach_pid);
3907             // Send a stop reply packet to indicate we successfully attached!
3908             NotifyThatProcessStopped ();
3909             return rnb_success;
3910         }
3911         else
3912         {
3913             m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
3914             if (err_str[0])
3915                 m_ctx.LaunchStatus().SetErrorString(err_str);
3916             else
3917                 m_ctx.LaunchStatus().SetErrorString("attach failed");
3918 
3919 #if defined (__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000)
3920             if (pid_attaching_to == INVALID_NUB_PROCESS && !attach_name.empty())
3921             {
3922                 pid_attaching_to = DNBProcessGetPIDByName (attach_name.c_str());
3923             }
3924             if (pid_attaching_to != INVALID_NUB_PROCESS && strcmp (err_str, "No such process") != 0)
3925             {
3926                 // csr_check(CSR_ALLOW_TASK_FOR_PID) will be nonzero if System Integrity Protection is in effect.
3927                 if (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0)
3928                 {
3929                     bool attach_failed_due_to_sip = false;
3930 
3931                     if (rootless_allows_task_for_pid (pid_attaching_to) == 0)
3932                     {
3933                         attach_failed_due_to_sip = true;
3934                     }
3935 
3936                     if (attach_failed_due_to_sip == false)
3937                     {
3938                         int csops_flags = 0;
3939                         int retval = ::csops (pid_attaching_to, CS_OPS_STATUS, &csops_flags, sizeof (csops_flags));
3940                         if (retval != -1 && (csops_flags & CS_RESTRICT))
3941                         {
3942                             attach_failed_due_to_sip = true;
3943                         }
3944                     }
3945                     if (attach_failed_due_to_sip)
3946                     {
3947                         SendPacket ("E87");  // E87 is the magic value which says that we are not allowed to attach
3948                         DNBLogError ("Attach failed because process does not allow attaching: \"%s\".", err_str);
3949                         return rnb_err;
3950                     }
3951                 }
3952             }
3953 
3954 #endif
3955 
3956             SendPacket ("E01");  // E01 is our magic error value for attach failed.
3957             DNBLogError ("Attach failed: \"%s\".", err_str);
3958             return rnb_err;
3959         }
3960     }
3961 
3962     // All other failures come through here
3963     return HandlePacket_UNIMPLEMENTED(p);
3964 }
3965 
3966 /* 'T XX' -- status of thread
3967  Check if the specified thread is alive.
3968  The thread number is in hex?  */
3969 
3970 rnb_err_t
3971 RNBRemote::HandlePacket_T (const char *p)
3972 {
3973     p++;
3974     if (p == NULL || *p == '\0')
3975     {
3976         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
3977     }
3978     if (!m_ctx.HasValidProcessID())
3979     {
3980         return SendPacket ("E15");
3981     }
3982     errno = 0;
3983     nub_thread_t tid = strtoul (p, NULL, 16);
3984     if (errno != 0 && tid == 0)
3985     {
3986         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
3987     }
3988 
3989     nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
3990     if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
3991     {
3992         return SendPacket ("E16");
3993     }
3994 
3995     return SendPacket ("OK");
3996 }
3997 
3998 
3999 rnb_err_t
4000 RNBRemote::HandlePacket_z (const char *p)
4001 {
4002     if (p == NULL || *p == '\0')
4003         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
4004 
4005     if (!m_ctx.HasValidProcessID())
4006         return SendPacket ("E15");
4007 
4008     char packet_cmd = *p++;
4009     char break_type = *p++;
4010 
4011     if (*p++ != ',')
4012         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
4013 
4014     char *c = NULL;
4015     nub_process_t pid = m_ctx.ProcessID();
4016     errno = 0;
4017     nub_addr_t addr = strtoull (p, &c, 16);
4018     if (errno != 0 && addr == 0)
4019         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
4020     p = c;
4021     if (*p++ != ',')
4022         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
4023 
4024     errno = 0;
4025     auto byte_size = strtoul (p, &c, 16);
4026     if (errno != 0 && byte_size == 0)
4027         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
4028 
4029     if (packet_cmd == 'Z')
4030     {
4031         // set
4032         switch (break_type)
4033         {
4034             case '0':   // set software breakpoint
4035             case '1':   // set hardware breakpoint
4036                 {
4037                     // gdb can send multiple Z packets for the same address and
4038                     // these calls must be ref counted.
4039                     bool hardware = (break_type == '1');
4040 
4041                     if (DNBBreakpointSet (pid, addr, byte_size, hardware))
4042                     {
4043                         // We successfully created a breakpoint, now lets full out
4044                         // a ref count structure with the breakID and add it to our
4045                         // map.
4046                         return SendPacket ("OK");
4047                     }
4048                     else
4049                     {
4050                         // We failed to set the software breakpoint
4051                         return SendPacket ("E09");
4052                     }
4053                 }
4054                 break;
4055 
4056             case '2':   // set write watchpoint
4057             case '3':   // set read watchpoint
4058             case '4':   // set access watchpoint
4059                 {
4060                     bool hardware = true;
4061                     uint32_t watch_flags = 0;
4062                     if (break_type == '2')
4063                         watch_flags = WATCH_TYPE_WRITE;
4064                     else if (break_type == '3')
4065                         watch_flags = WATCH_TYPE_READ;
4066                     else
4067                         watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
4068 
4069                     if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware))
4070                     {
4071                         return SendPacket ("OK");
4072                     }
4073                     else
4074                     {
4075                         // We failed to set the watchpoint
4076                         return SendPacket ("E09");
4077                     }
4078                 }
4079                 break;
4080 
4081             default:
4082                 break;
4083         }
4084     }
4085     else if (packet_cmd == 'z')
4086     {
4087         // remove
4088         switch (break_type)
4089         {
4090             case '0':   // remove software breakpoint
4091             case '1':   // remove hardware breakpoint
4092                 if (DNBBreakpointClear (pid, addr))
4093                 {
4094                     return SendPacket ("OK");
4095                 }
4096                 else
4097                 {
4098                     return SendPacket ("E08");
4099                 }
4100                 break;
4101 
4102             case '2':   // remove write watchpoint
4103             case '3':   // remove read watchpoint
4104             case '4':   // remove access watchpoint
4105                 if (DNBWatchpointClear (pid, addr))
4106                 {
4107                     return SendPacket ("OK");
4108                 }
4109                 else
4110                 {
4111                     return SendPacket ("E08");
4112                 }
4113                 break;
4114 
4115             default:
4116                 break;
4117         }
4118     }
4119     return HandlePacket_UNIMPLEMENTED(p);
4120 }
4121 
4122 // Extract the thread number from the thread suffix that might be appended to
4123 // thread specific packets. This will only be enabled if m_thread_suffix_supported
4124 // is true.
4125 nub_thread_t
4126 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
4127 {
4128     if (m_thread_suffix_supported)
4129     {
4130         nub_thread_t tid = INVALID_NUB_THREAD;
4131         if (p)
4132         {
4133             const char *tid_cstr = strstr (p, "thread:");
4134             if (tid_cstr)
4135             {
4136                 tid_cstr += strlen ("thread:");
4137                 tid = strtoul(tid_cstr, NULL, 16);
4138             }
4139         }
4140         return tid;
4141     }
4142     return GetCurrentThread();
4143 
4144 }
4145 
4146 /* 'p XX'
4147  print the contents of register X */
4148 
4149 rnb_err_t
4150 RNBRemote::HandlePacket_p (const char *p)
4151 {
4152     if (g_num_reg_entries == 0)
4153         InitializeRegisters ();
4154 
4155     if (p == NULL || *p == '\0')
4156     {
4157         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
4158     }
4159     if (!m_ctx.HasValidProcessID())
4160     {
4161         return SendPacket ("E15");
4162     }
4163     nub_process_t pid = m_ctx.ProcessID();
4164     errno = 0;
4165     char *tid_cstr = NULL;
4166     uint32_t reg = static_cast<uint32_t>(strtoul (p + 1, &tid_cstr, 16));
4167     if (errno != 0 && reg == 0)
4168     {
4169         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
4170     }
4171 
4172     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
4173     if (tid == INVALID_NUB_THREAD)
4174         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
4175 
4176     const register_map_entry_t *reg_entry;
4177 
4178     if (reg < g_num_reg_entries)
4179         reg_entry = &g_reg_entries[reg];
4180     else
4181         reg_entry = NULL;
4182 
4183     std::ostringstream ostrm;
4184     if (reg_entry == NULL)
4185     {
4186         DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
4187         ostrm << "00000000";
4188     }
4189     else if (reg_entry->nub_info.reg == (uint32_t)-1)
4190     {
4191         if (reg_entry->nub_info.size > 0)
4192         {
4193             std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0');
4194             append_hex_value(ostrm, zeros.data(), zeros.size(), false);
4195         }
4196     }
4197     else
4198     {
4199         register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL);
4200     }
4201     return SendPacket (ostrm.str());
4202 }
4203 
4204 /* 'Pnn=rrrrr'
4205  Set register number n to value r.
4206  n and r are hex strings.  */
4207 
4208 rnb_err_t
4209 RNBRemote::HandlePacket_P (const char *p)
4210 {
4211     if (g_num_reg_entries == 0)
4212         InitializeRegisters ();
4213 
4214     if (p == NULL || *p == '\0')
4215     {
4216         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
4217     }
4218     if (!m_ctx.HasValidProcessID())
4219     {
4220         return SendPacket ("E28");
4221     }
4222 
4223     nub_process_t pid = m_ctx.ProcessID();
4224 
4225     StringExtractor packet (p);
4226 
4227     const char cmd_char = packet.GetChar();
4228     // Register ID is always in big endian
4229     const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
4230     const char equal_char = packet.GetChar();
4231 
4232     if (cmd_char != 'P')
4233         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
4234 
4235     if (reg == UINT32_MAX)
4236         return SendPacket ("E29");
4237 
4238     if (equal_char != '=')
4239         return SendPacket ("E30");
4240 
4241     const register_map_entry_t *reg_entry;
4242 
4243     if (reg >= g_num_reg_entries)
4244         return SendPacket("E47");
4245 
4246     reg_entry = &g_reg_entries[reg];
4247 
4248     if (reg_entry->nub_info.set == (uint32_t)-1 && reg_entry->nub_info.reg == (uint32_t)-1)
4249     {
4250         DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
4251         return SendPacket("E48");
4252     }
4253 
4254     DNBRegisterValue reg_value;
4255     reg_value.info = reg_entry->nub_info;
4256     packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc);
4257 
4258     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
4259     if (tid == INVALID_NUB_THREAD)
4260         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
4261 
4262     if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
4263     {
4264         return SendPacket ("E32");
4265     }
4266     return SendPacket ("OK");
4267 }
4268 
4269 /* 'c [addr]'
4270  Continue, optionally from a specified address. */
4271 
4272 rnb_err_t
4273 RNBRemote::HandlePacket_c (const char *p)
4274 {
4275     const nub_process_t pid = m_ctx.ProcessID();
4276 
4277     if (pid == INVALID_NUB_PROCESS)
4278         return SendPacket ("E23");
4279 
4280     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
4281 
4282     if (*(p + 1) != '\0')
4283     {
4284         action.tid = GetContinueThread();
4285         errno = 0;
4286         action.addr = strtoull (p + 1, NULL, 16);
4287         if (errno != 0 && action.addr == 0)
4288             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
4289     }
4290 
4291     DNBThreadResumeActions thread_actions;
4292     thread_actions.Append(action);
4293     thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
4294     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4295         return SendPacket ("E25");
4296     // Don't send an "OK" packet; response is the stopped/exited message.
4297     return rnb_success;
4298 }
4299 
4300 rnb_err_t
4301 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
4302 {
4303     /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code)
4304        for the memory region containing a given address and return that information.
4305 
4306        Users of this packet must be prepared for three results:
4307 
4308            Region information is returned
4309            Region information is unavailable for this address because the address is in unmapped memory
4310            Region lookup cannot be performed on this platform or process is not yet launched
4311            This packet isn't implemented
4312 
4313        Examples of use:
4314           qMemoryRegionInfo:3a55140
4315           start:3a50000,size:100000,permissions:rwx
4316 
4317           qMemoryRegionInfo:0
4318           error:address in unmapped region
4319 
4320           qMemoryRegionInfo:3a551140   (on a different platform)
4321           error:region lookup cannot be performed
4322 
4323           qMemoryRegionInfo
4324           OK                   // this packet is implemented by the remote nub
4325     */
4326 
4327     p += sizeof ("qMemoryRegionInfo") - 1;
4328     if (*p == '\0')
4329        return SendPacket ("OK");
4330     if (*p++ != ':')
4331        return SendPacket ("E67");
4332     if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
4333        p += 2;
4334 
4335     errno = 0;
4336     uint64_t address = strtoul (p, NULL, 16);
4337     if (errno != 0 && address == 0)
4338     {
4339         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
4340     }
4341 
4342     DNBRegionInfo region_info = { 0, 0, 0 };
4343     DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, &region_info);
4344     std::ostringstream ostrm;
4345 
4346         // start:3a50000,size:100000,permissions:rwx
4347     ostrm << "start:" << std::hex << region_info.addr << ';';
4348 
4349     if (region_info.size > 0)
4350         ostrm << "size:"  << std::hex << region_info.size << ';';
4351 
4352     if (region_info.permissions)
4353     {
4354         ostrm << "permissions:";
4355 
4356         if (region_info.permissions & eMemoryPermissionsReadable)
4357             ostrm << 'r';
4358         if (region_info.permissions & eMemoryPermissionsWritable)
4359             ostrm << 'w';
4360         if (region_info.permissions & eMemoryPermissionsExecutable)
4361             ostrm << 'x';
4362         ostrm << ';';
4363     }
4364     return SendPacket (ostrm.str());
4365 }
4366 
4367 // qGetProfileData;scan_type:0xYYYYYYY
4368 rnb_err_t
4369 RNBRemote::HandlePacket_GetProfileData (const char *p)
4370 {
4371     nub_process_t pid = m_ctx.ProcessID();
4372     if (pid == INVALID_NUB_PROCESS)
4373         return SendPacket ("OK");
4374 
4375     StringExtractor packet(p += sizeof ("qGetProfileData"));
4376     DNBProfileDataScanType scan_type = eProfileAll;
4377     std::string name;
4378     std::string value;
4379     while (packet.GetNameColonValue(name, value))
4380     {
4381         if (name.compare ("scan_type") == 0)
4382         {
4383             std::istringstream iss(value);
4384             uint32_t int_value = 0;
4385             if (iss >> std::hex >> int_value)
4386             {
4387                 scan_type = (DNBProfileDataScanType)int_value;
4388             }
4389         }
4390     }
4391 
4392     std::string data = DNBProcessGetProfileData(pid, scan_type);
4393     if (!data.empty())
4394     {
4395         return SendPacket (data.c_str());
4396     }
4397     else
4398     {
4399         return SendPacket ("OK");
4400     }
4401 }
4402 
4403 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY
4404 rnb_err_t
4405 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
4406 {
4407     nub_process_t pid = m_ctx.ProcessID();
4408     if (pid == INVALID_NUB_PROCESS)
4409         return SendPacket ("OK");
4410 
4411     StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));
4412     bool enable = false;
4413     uint64_t interval_usec = 0;
4414     DNBProfileDataScanType scan_type = eProfileAll;
4415     std::string name;
4416     std::string value;
4417     while (packet.GetNameColonValue(name, value))
4418     {
4419         if (name.compare ("enable") == 0)
4420         {
4421             enable  = strtoul(value.c_str(), NULL, 10) > 0;
4422         }
4423         else if (name.compare ("interval_usec") == 0)
4424         {
4425             interval_usec  = strtoul(value.c_str(), NULL, 10);
4426         }
4427         else if (name.compare ("scan_type") == 0)
4428         {
4429             std::istringstream iss(value);
4430             uint32_t int_value = 0;
4431             if (iss >> std::hex >> int_value)
4432             {
4433                 scan_type = (DNBProfileDataScanType)int_value;
4434             }
4435         }
4436     }
4437 
4438     if (interval_usec == 0)
4439     {
4440         enable = 0;
4441     }
4442 
4443     DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type);
4444     return SendPacket ("OK");
4445 }
4446 
4447 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO COMPRESS>;
4448 //
4449 // type: must be a type previously reported by the qXfer:features: SupportedCompressions list
4450 //
4451 // minsize: is optional; by default the qXfer:features: DefaultCompressionMinSize value is used
4452 // debugserver may have a better idea of what a good minimum packet size to compress is than lldb.
4453 
4454 rnb_err_t
4455 RNBRemote::HandlePacket_QEnableCompression (const char *p)
4456 {
4457     p += sizeof ("QEnableCompression:") - 1;
4458 
4459     size_t new_compression_minsize = m_compression_minsize;
4460     const char *new_compression_minsize_str = strstr (p, "minsize:");
4461     if (new_compression_minsize_str)
4462     {
4463         new_compression_minsize_str += strlen ("minsize:");
4464         errno = 0;
4465         new_compression_minsize = strtoul (new_compression_minsize_str, NULL, 10);
4466         if (errno != 0 || new_compression_minsize == ULONG_MAX)
4467         {
4468             new_compression_minsize = m_compression_minsize;
4469         }
4470     }
4471 
4472 #if defined (HAVE_LIBCOMPRESSION)
4473     if (compression_decode_buffer != NULL)
4474     {
4475         if (strstr (p, "type:zlib-deflate;") != nullptr)
4476         {
4477             EnableCompressionNextSendPacket (compression_types::zlib_deflate);
4478             m_compression_minsize = new_compression_minsize;
4479             return SendPacket ("OK");
4480         }
4481         else if (strstr (p, "type:lz4;") != nullptr)
4482         {
4483             EnableCompressionNextSendPacket (compression_types::lz4);
4484             m_compression_minsize = new_compression_minsize;
4485             return SendPacket ("OK");
4486         }
4487         else if (strstr (p, "type:lzma;") != nullptr)
4488         {
4489             EnableCompressionNextSendPacket (compression_types::lzma);
4490             m_compression_minsize = new_compression_minsize;
4491             return SendPacket ("OK");
4492         }
4493         else if (strstr (p, "type:lzfse;") != nullptr)
4494         {
4495             EnableCompressionNextSendPacket (compression_types::lzfse);
4496             m_compression_minsize = new_compression_minsize;
4497             return SendPacket ("OK");
4498         }
4499     }
4500 #endif
4501 
4502 #if defined (HAVE_LIBZ)
4503     if (strstr (p, "type:zlib-deflate;") != nullptr)
4504     {
4505         EnableCompressionNextSendPacket (compression_types::zlib_deflate);
4506         m_compression_minsize = new_compression_minsize;
4507         return SendPacket ("OK");
4508     }
4509 #endif
4510 
4511     return SendPacket ("E88");
4512 }
4513 
4514 rnb_err_t
4515 RNBRemote::HandlePacket_qSpeedTest (const char *p)
4516 {
4517     p += strlen ("qSpeedTest:response_size:");
4518     char *end = NULL;
4519     errno = 0;
4520     uint64_t response_size = ::strtoul (p, &end, 16);
4521     if (errno != 0)
4522         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Didn't find response_size value at right offset");
4523     else if (*end == ';')
4524     {
4525         static char g_data[4*1024*1024+16] = "data:";
4526         memset(g_data + 5, 'a', response_size);
4527         g_data[response_size + 5] = '\0';
4528         return SendPacket (g_data);
4529     }
4530     else
4531     {
4532         return SendPacket ("E79");
4533     }
4534 }
4535 
4536 rnb_err_t
4537 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p)
4538 {
4539     /* This packet simply returns the number of supported hardware watchpoints.
4540 
4541        Examples of use:
4542           qWatchpointSupportInfo:
4543           num:4
4544 
4545           qWatchpointSupportInfo
4546           OK                   // this packet is implemented by the remote nub
4547     */
4548 
4549     p += sizeof ("qWatchpointSupportInfo") - 1;
4550     if (*p == '\0')
4551        return SendPacket ("OK");
4552     if (*p++ != ':')
4553        return SendPacket ("E67");
4554 
4555     errno = 0;
4556     uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID());
4557     std::ostringstream ostrm;
4558 
4559     // size:4
4560     ostrm << "num:" << std::dec << num << ';';
4561     return SendPacket (ostrm.str());
4562 }
4563 
4564 /* 'C sig [;addr]'
4565  Resume with signal sig, optionally at address addr.  */
4566 
4567 rnb_err_t
4568 RNBRemote::HandlePacket_C (const char *p)
4569 {
4570     const nub_process_t pid = m_ctx.ProcessID();
4571 
4572     if (pid == INVALID_NUB_PROCESS)
4573         return SendPacket ("E36");
4574 
4575     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
4576     int process_signo = -1;
4577     if (*(p + 1) != '\0')
4578     {
4579         action.tid = GetContinueThread();
4580         char *end = NULL;
4581         errno = 0;
4582         process_signo = static_cast<int>(strtoul (p + 1, &end, 16));
4583         if (errno != 0)
4584             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
4585         else if (*end == ';')
4586         {
4587             errno = 0;
4588             action.addr = strtoull (end + 1, NULL, 16);
4589             if (errno != 0 && action.addr == 0)
4590                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
4591         }
4592     }
4593 
4594     DNBThreadResumeActions thread_actions;
4595     thread_actions.Append (action);
4596     thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
4597     if (!DNBProcessSignal(pid, process_signo))
4598         return SendPacket ("E52");
4599     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4600         return SendPacket ("E38");
4601     /* Don't send an "OK" packet; response is the stopped/exited message.  */
4602     return rnb_success;
4603 }
4604 
4605 //----------------------------------------------------------------------
4606 // 'D' packet
4607 // Detach from gdb.
4608 //----------------------------------------------------------------------
4609 rnb_err_t
4610 RNBRemote::HandlePacket_D (const char *p)
4611 {
4612     if (m_ctx.HasValidProcessID())
4613     {
4614         if (DNBProcessDetach(m_ctx.ProcessID()))
4615             SendPacket ("OK");
4616         else
4617             SendPacket ("E");
4618     }
4619     else
4620     {
4621         SendPacket ("E");
4622     }
4623     return rnb_success;
4624 }
4625 
4626 /* 'k'
4627  Kill the inferior process.  */
4628 
4629 rnb_err_t
4630 RNBRemote::HandlePacket_k (const char *p)
4631 {
4632     DNBLog ("Got a 'k' packet, killing the inferior process.");
4633     // No response to should be sent to the kill packet
4634     if (m_ctx.HasValidProcessID())
4635         DNBProcessKill (m_ctx.ProcessID());
4636     SendPacket ("X09");
4637     return rnb_success;
4638 }
4639 
4640 rnb_err_t
4641 RNBRemote::HandlePacket_stop_process (const char *p)
4642 {
4643 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt
4644 #if defined(TEST_EXIT_ON_INTERRUPT)
4645     rnb_err_t err = HandlePacket_k (p);
4646     m_comm.Disconnect(true);
4647     return err;
4648 #else
4649     if (!DNBProcessInterrupt(m_ctx.ProcessID()))
4650     {
4651         // If we failed to interrupt the process, then send a stop
4652         // reply packet as the process was probably already stopped
4653         DNBLogThreaded ("RNBRemote::HandlePacket_stop_process() sending extra stop reply because DNBProcessInterrupt returned false");
4654         HandlePacket_last_signal (NULL);
4655     }
4656     return rnb_success;
4657 #endif
4658 }
4659 
4660 /* 's'
4661  Step the inferior process.  */
4662 
4663 rnb_err_t
4664 RNBRemote::HandlePacket_s (const char *p)
4665 {
4666     const nub_process_t pid = m_ctx.ProcessID();
4667     if (pid == INVALID_NUB_PROCESS)
4668         return SendPacket ("E32");
4669 
4670     // Hardware supported stepping not supported on arm
4671     nub_thread_t tid = GetContinueThread ();
4672     if (tid == 0 || tid == (nub_thread_t)-1)
4673         tid = GetCurrentThread();
4674 
4675     if (tid == INVALID_NUB_THREAD)
4676         return SendPacket ("E33");
4677 
4678     DNBThreadResumeActions thread_actions;
4679     thread_actions.AppendAction(tid, eStateStepping);
4680 
4681     // Make all other threads stop when we are stepping
4682     thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
4683     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4684         return SendPacket ("E49");
4685     // Don't send an "OK" packet; response is the stopped/exited message.
4686     return rnb_success;
4687 }
4688 
4689 /* 'S sig [;addr]'
4690  Step with signal sig, optionally at address addr.  */
4691 
4692 rnb_err_t
4693 RNBRemote::HandlePacket_S (const char *p)
4694 {
4695     const nub_process_t pid = m_ctx.ProcessID();
4696     if (pid == INVALID_NUB_PROCESS)
4697         return SendPacket ("E36");
4698 
4699     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
4700 
4701     if (*(p + 1) != '\0')
4702     {
4703         char *end = NULL;
4704         errno = 0;
4705         action.signal = static_cast<int>(strtoul (p + 1, &end, 16));
4706         if (errno != 0)
4707             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
4708         else if (*end == ';')
4709         {
4710             errno = 0;
4711             action.addr = strtoull (end + 1, NULL, 16);
4712             if (errno != 0 && action.addr == 0)
4713             {
4714                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
4715             }
4716         }
4717     }
4718 
4719     action.tid = GetContinueThread ();
4720     if (action.tid == 0 || action.tid == (nub_thread_t)-1)
4721         return SendPacket ("E40");
4722 
4723     nub_state_t tstate = DNBThreadGetState (pid, action.tid);
4724     if (tstate == eStateInvalid || tstate == eStateExited)
4725         return SendPacket ("E37");
4726 
4727 
4728     DNBThreadResumeActions thread_actions;
4729     thread_actions.Append (action);
4730 
4731     // Make all other threads stop when we are stepping
4732     thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
4733     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4734         return SendPacket ("E39");
4735 
4736     // Don't send an "OK" packet; response is the stopped/exited message.
4737     return rnb_success;
4738 }
4739 
4740 static const char *
4741 GetArchName (const uint32_t cputype, const uint32_t cpusubtype)
4742 {
4743     switch (cputype)
4744     {
4745     case CPU_TYPE_ARM:
4746         switch (cpusubtype)
4747         {
4748         case 5:     return "armv4";
4749         case 6:     return "armv6";
4750         case 7:     return "armv5t";
4751         case 8:     return "xscale";
4752         case 9:     return "armv7";
4753         case 10:    return "armv7f";
4754         case 11:    return "armv7s";
4755         case 12:    return "armv7k";
4756         case 14:    return "armv6m";
4757         case 15:    return "armv7m";
4758         case 16:    return "armv7em";
4759         default:    return "arm";
4760         }
4761         break;
4762     case CPU_TYPE_ARM64:    return "arm64";
4763     case CPU_TYPE_I386:     return "i386";
4764     case CPU_TYPE_X86_64:
4765         switch (cpusubtype)
4766         {
4767         default:    return "x86_64";
4768         case 8:     return "x86_64h";
4769         }
4770         break;
4771     }
4772     return NULL;
4773 }
4774 
4775 static bool
4776 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64)
4777 {
4778     static uint32_t g_host_cputype = 0;
4779     static uint32_t g_host_cpusubtype = 0;
4780     static uint32_t g_is_64_bit_capable = 0;
4781     static bool g_promoted_to_64 = false;
4782 
4783     if (g_host_cputype == 0)
4784     {
4785         g_promoted_to_64 = false;
4786         size_t len = sizeof(uint32_t);
4787         if  (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0)
4788         {
4789             len = sizeof (uint32_t);
4790             if  (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0)
4791             {
4792                 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0))
4793                 {
4794                     g_promoted_to_64 = true;
4795                     g_host_cputype |= CPU_ARCH_ABI64;
4796                 }
4797             }
4798         }
4799 
4800         len = sizeof(uint32_t);
4801         if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0)
4802         {
4803             if (g_promoted_to_64 &&
4804                 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486)
4805                 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL;
4806         }
4807     }
4808 
4809     cputype = g_host_cputype;
4810     cpusubtype = g_host_cpusubtype;
4811     is_64_bit_capable = g_is_64_bit_capable;
4812     promoted_to_64 = g_promoted_to_64;
4813     return g_host_cputype != 0;
4814 }
4815 
4816 rnb_err_t
4817 RNBRemote::HandlePacket_qHostInfo (const char *p)
4818 {
4819     std::ostringstream strm;
4820 
4821     uint32_t cputype = 0;
4822     uint32_t cpusubtype = 0;
4823     uint32_t is_64_bit_capable = 0;
4824     bool promoted_to_64 = false;
4825     if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64))
4826     {
4827         strm << "cputype:" << std::dec << cputype << ';';
4828         strm << "cpusubtype:" << std::dec << cpusubtype << ';';
4829     }
4830 
4831     // The OS in the triple should be "ios" or "macosx" which doesn't match our
4832     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
4833     // this for now.
4834     if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
4835     {
4836 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
4837         strm << "ostype:tvos;";
4838 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
4839         strm << "ostype:watchos;";
4840 #else
4841         strm << "ostype:ios;";
4842 #endif
4843 
4844         // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
4845         strm << "watchpoint_exceptions_received:before;";
4846     }
4847     else
4848     {
4849         strm << "ostype:macosx;";
4850         strm << "watchpoint_exceptions_received:after;";
4851     }
4852 //    char ostype[64];
4853 //    len = sizeof(ostype);
4854 //    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
4855 //    {
4856 //        len = strlen(ostype);
4857 //        std::transform (ostype, ostype + len, ostype, tolower);
4858 //        strm << "ostype:" << std::dec << ostype << ';';
4859 //    }
4860 
4861     strm << "vendor:apple;";
4862 
4863     uint64_t major, minor, patch;
4864     if (DNBGetOSVersionNumbers (&major, &minor, &patch))
4865     {
4866         strm << "os_version:" << major << "." << minor;
4867         if (patch != UINT64_MAX)
4868             strm << "." << patch;
4869         strm << ";";
4870     }
4871 
4872 #if defined (__LITTLE_ENDIAN__)
4873     strm << "endian:little;";
4874 #elif defined (__BIG_ENDIAN__)
4875     strm << "endian:big;";
4876 #elif defined (__PDP_ENDIAN__)
4877     strm << "endian:pdp;";
4878 #endif
4879 
4880     if (promoted_to_64)
4881         strm << "ptrsize:8;";
4882     else
4883         strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
4884 
4885 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
4886     strm << "default_packet_timeout:10;";
4887 #endif
4888 
4889     return SendPacket (strm.str());
4890 }
4891 
4892 void
4893 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes)
4894 {
4895     if (indent)
4896         s << INDENT_WITH_SPACES(indent);
4897     s << '<' << name;
4898     if (!has_attributes)
4899         s << '>' << std::endl;
4900 }
4901 
4902 void
4903 XMLElementStartEndAttributes (std::ostringstream &s, bool empty)
4904 {
4905     if (empty)
4906         s << '/';
4907     s << '>' << std::endl;
4908 }
4909 
4910 void
4911 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name)
4912 {
4913     if (indent)
4914         s << INDENT_WITH_SPACES(indent);
4915     s << '<' << '/' << name << '>' << std::endl;
4916 }
4917 
4918 void
4919 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true)
4920 {
4921     if (value)
4922     {
4923         if (indent)
4924             s << INDENT_WITH_SPACES(indent);
4925         s << '<' << name << '>' << value;
4926         if (close)
4927             XMLElementEnd(s, 0, name);
4928     }
4929 }
4930 
4931 void
4932 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true)
4933 {
4934     if (indent)
4935         s << INDENT_WITH_SPACES(indent);
4936 
4937     s << '<' << name << '>' << DECIMAL << value;
4938     if (close)
4939         XMLElementEnd(s, 0, name);
4940 }
4941 
4942 void
4943 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL)
4944 {
4945     if (value)
4946     {
4947         if (default_value && strcmp(value, default_value) == 0)
4948             return; // No need to emit the attribute because it matches the default value
4949         s <<' ' << name << "=\"" << value << "\"";
4950     }
4951 }
4952 
4953 void
4954 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value)
4955 {
4956     s <<' ' << name << "=\"" << DECIMAL << value << "\"";
4957 }
4958 
4959 void
4960 GenerateTargetXMLRegister (std::ostringstream &s,
4961                            const uint32_t reg_num,
4962                            nub_size_t num_reg_sets,
4963                            const DNBRegisterSetInfo *reg_set_info,
4964                            const register_map_entry_t &reg)
4965 {
4966     const char *default_lldb_encoding = "uint";
4967     const char *lldb_encoding = default_lldb_encoding;
4968     const char *gdb_group = "general";
4969     const char *default_gdb_type = "int";
4970     const char *gdb_type = default_gdb_type;
4971     const char *default_lldb_format = "hex";
4972     const char *lldb_format = default_lldb_format;
4973     const char *lldb_set = NULL;
4974 
4975     switch (reg.nub_info.type)
4976     {
4977         case Uint:      lldb_encoding = "uint"; break;
4978         case Sint:      lldb_encoding = "sint"; break;
4979         case IEEE754:   lldb_encoding = "ieee754";  if (reg.nub_info.set > 0) gdb_group = "float"; break;
4980         case Vector:    lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break;
4981     }
4982 
4983     switch (reg.nub_info.format)
4984     {
4985         case Binary:            lldb_format = "binary"; break;
4986         case Decimal:           lldb_format = "decimal"; break;
4987         case Hex:               lldb_format = "hex"; break;
4988         case Float:             gdb_type = "float"; lldb_format = "float"; break;
4989         case VectorOfSInt8:     gdb_type = "float"; lldb_format = "vector-sint8"; break;
4990         case VectorOfUInt8:     gdb_type = "float"; lldb_format = "vector-uint8"; break;
4991         case VectorOfSInt16:    gdb_type = "float"; lldb_format = "vector-sint16"; break;
4992         case VectorOfUInt16:    gdb_type = "float"; lldb_format = "vector-uint16"; break;
4993         case VectorOfSInt32:    gdb_type = "float"; lldb_format = "vector-sint32"; break;
4994         case VectorOfUInt32:    gdb_type = "float"; lldb_format = "vector-uint32"; break;
4995         case VectorOfFloat32:   gdb_type = "float"; lldb_format = "vector-float32"; break;
4996         case VectorOfUInt128:   gdb_type = "float"; lldb_format = "vector-uint128"; break;
4997     };
4998     if (reg_set_info && reg.nub_info.set < num_reg_sets)
4999         lldb_set = reg_set_info[reg.nub_info.set].name;
5000 
5001     uint32_t indent = 2;
5002 
5003     XMLElementStart(s, indent, "reg", true);
5004     XMLAttributeString(s, "name", reg.nub_info.name);
5005     XMLAttributeUnsignedDecimal(s, "regnum", reg_num);
5006     XMLAttributeUnsignedDecimal(s, "offset", reg.offset);
5007     XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8);
5008     XMLAttributeString(s, "group", gdb_group);
5009     XMLAttributeString(s, "type", gdb_type, default_gdb_type);
5010     XMLAttributeString (s, "altname", reg.nub_info.alt);
5011     XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding);
5012     XMLAttributeString(s, "format", lldb_format, default_lldb_format);
5013     XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set);
5014     if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM)
5015         XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe);
5016     if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM)
5017         XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf);
5018 
5019     const char *lldb_generic = NULL;
5020     switch (reg.nub_info.reg_generic)
5021     {
5022         case GENERIC_REGNUM_FP:     lldb_generic = "fp"; break;
5023         case GENERIC_REGNUM_PC:     lldb_generic = "pc"; break;
5024         case GENERIC_REGNUM_SP:     lldb_generic = "sp"; break;
5025         case GENERIC_REGNUM_RA:     lldb_generic = "ra"; break;
5026         case GENERIC_REGNUM_FLAGS:  lldb_generic = "flags"; break;
5027         case GENERIC_REGNUM_ARG1:   lldb_generic = "arg1"; break;
5028         case GENERIC_REGNUM_ARG2:   lldb_generic = "arg2"; break;
5029         case GENERIC_REGNUM_ARG3:   lldb_generic = "arg3"; break;
5030         case GENERIC_REGNUM_ARG4:   lldb_generic = "arg4"; break;
5031         case GENERIC_REGNUM_ARG5:   lldb_generic = "arg5"; break;
5032         case GENERIC_REGNUM_ARG6:   lldb_generic = "arg6"; break;
5033         case GENERIC_REGNUM_ARG7:   lldb_generic = "arg7"; break;
5034         case GENERIC_REGNUM_ARG8:   lldb_generic = "arg8"; break;
5035         default: break;
5036     }
5037     XMLAttributeString(s, "generic", lldb_generic);
5038 
5039 
5040     bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty();
5041     if (!empty)
5042     {
5043         if (!reg.value_regnums.empty())
5044         {
5045             std::ostringstream regnums;
5046             bool first = true;
5047             regnums << DECIMAL;
5048             for (auto regnum : reg.value_regnums)
5049             {
5050                 if (!first)
5051                     regnums << ',';
5052                 regnums << regnum;
5053                 first = false;
5054             }
5055             XMLAttributeString(s, "value_regnums", regnums.str().c_str());
5056         }
5057 
5058         if (!reg.invalidate_regnums.empty())
5059         {
5060             std::ostringstream regnums;
5061             bool first = true;
5062             regnums << DECIMAL;
5063             for (auto regnum : reg.invalidate_regnums)
5064             {
5065                 if (!first)
5066                     regnums << ',';
5067                 regnums << regnum;
5068                 first = false;
5069             }
5070             XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str());
5071         }
5072     }
5073     XMLElementStartEndAttributes(s, true);
5074 }
5075 
5076 void
5077 GenerateTargetXMLRegisters (std::ostringstream &s)
5078 {
5079     nub_size_t num_reg_sets = 0;
5080     const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
5081 
5082 
5083     uint32_t cputype = DNBGetRegisterCPUType();
5084     if (cputype)
5085     {
5086         XMLElementStart(s, 0, "feature", true);
5087         std::ostringstream name_strm;
5088         name_strm << "com.apple.debugserver." << GetArchName (cputype, 0);
5089         XMLAttributeString(s, "name", name_strm.str().c_str());
5090         XMLElementStartEndAttributes(s, false);
5091         for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num)
5092 //        for (const auto &reg: g_dynamic_register_map)
5093         {
5094             GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]);
5095         }
5096         XMLElementEnd(s, 0, "feature");
5097 
5098         if (num_reg_sets > 0)
5099         {
5100             XMLElementStart(s, 0, "groups", false);
5101             for (uint32_t set=1; set<num_reg_sets; ++set)
5102             {
5103                 XMLElementStart(s, 2, "group", true);
5104                 XMLAttributeUnsignedDecimal(s, "id", set);
5105                 XMLAttributeString(s, "name", reg_sets[set].name);
5106                 XMLElementStartEndAttributes(s, true);
5107             }
5108             XMLElementEnd(s, 0, "groups");
5109         }
5110     }
5111 }
5112 
5113 static const char *g_target_xml_header = R"(<?xml version="1.0"?>
5114 <target version="1.0">)";
5115 
5116 static const char *g_target_xml_footer = "</target>";
5117 
5118 static std::string g_target_xml;
5119 
5120 void
5121 UpdateTargetXML ()
5122 {
5123     std::ostringstream s;
5124     s << g_target_xml_header << std::endl;
5125 
5126     // Set the architecture
5127     //s << "<architecture>" << arch "</architecture>" << std::endl;
5128 
5129     // Set the OSABI
5130     //s << "<osabi>abi-name</osabi>"
5131 
5132     GenerateTargetXMLRegisters(s);
5133 
5134     s << g_target_xml_footer << std::endl;
5135 
5136     // Save the XML output in case it gets retrieved in chunks
5137     g_target_xml = s.str();
5138 }
5139 
5140 rnb_err_t
5141 RNBRemote::HandlePacket_qXfer (const char *command)
5142 {
5143     const char *p = command;
5144     p += strlen ("qXfer:");
5145     const char *sep = strchr(p, ':');
5146     if (sep)
5147     {
5148         std::string object(p, sep - p);     // "auxv", "backtrace", "features", etc
5149         p = sep + 1;
5150         sep = strchr(p, ':');
5151         if (sep)
5152         {
5153             std::string rw(p, sep - p);    // "read" or "write"
5154             p = sep + 1;
5155             sep = strchr(p, ':');
5156             if (sep)
5157             {
5158                 std::string annex(p, sep - p);    // "read" or "write"
5159 
5160                 p = sep + 1;
5161                 sep = strchr(p, ',');
5162                 if (sep)
5163                 {
5164                     std::string offset_str(p, sep - p); // read the length as a string
5165                     p = sep + 1;
5166                     std::string length_str(p); // read the offset as a string
5167                     char *end = nullptr;
5168                     const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset
5169                     if (*end == '\0')
5170                     {
5171                         const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length
5172                         if (*end == '\0')
5173                         {
5174                             if (object == "features"  &&
5175                                 rw     == "read"      &&
5176                                 annex  == "target.xml")
5177                             {
5178                                 std::ostringstream xml_out;
5179 
5180                                 if (offset == 0)
5181                                 {
5182                                     InitializeRegisters (true);
5183 
5184                                     UpdateTargetXML();
5185                                     if (g_target_xml.empty())
5186                                         return SendPacket("E83");
5187 
5188                                     if (length > g_target_xml.size())
5189                                     {
5190                                         xml_out << 'l'; // No more data
5191                                         xml_out << binary_encode_string(g_target_xml);
5192                                     }
5193                                     else
5194                                     {
5195                                         xml_out << 'm'; // More data needs to be read with a subsequent call
5196                                         xml_out << binary_encode_string(std::string(g_target_xml, offset, length));
5197                                     }
5198                                 }
5199                                 else
5200                                 {
5201                                     // Retrieving target XML in chunks
5202                                     if (offset < g_target_xml.size())
5203                                     {
5204                                         std::string chunk(g_target_xml, offset, length);
5205                                         if (chunk.size() < length)
5206                                             xml_out << 'l'; // No more data
5207                                         else
5208                                             xml_out << 'm'; // More data needs to be read with a subsequent call
5209                                         xml_out << binary_encode_string(chunk.data());
5210                                     }
5211                                 }
5212                                 return SendPacket(xml_out.str());
5213                             }
5214                             // Well formed, put not supported
5215                             return HandlePacket_UNIMPLEMENTED (command);
5216                         }
5217                     }
5218                 }
5219             }
5220             else
5221             {
5222                 SendPacket ("E85");
5223             }
5224         }
5225         else
5226         {
5227             SendPacket ("E86");
5228         }
5229     }
5230     return SendPacket ("E82");
5231 }
5232 
5233 
5234 rnb_err_t
5235 RNBRemote::HandlePacket_qGDBServerVersion (const char *p)
5236 {
5237     std::ostringstream strm;
5238 
5239 #if defined(DEBUGSERVER_PROGRAM_NAME)
5240     strm << "name:" DEBUGSERVER_PROGRAM_NAME ";";
5241 #else
5242     strm << "name:debugserver;";
5243 #endif
5244     strm << "version:" << DEBUGSERVER_VERSION_NUM << ";";
5245 
5246     return SendPacket (strm.str());
5247 }
5248 
5249 // A helper function that retrieves a single integer value from
5250 // a one-level-deep JSON dictionary of key-value pairs.  e.g.
5251 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}]
5252 //
5253 uint64_t
5254 get_integer_value_for_key_name_from_json (const char *key, const char *json_string)
5255 {
5256     uint64_t retval = INVALID_NUB_ADDRESS;
5257     std::string key_with_quotes = "\"";
5258     key_with_quotes += key;
5259     key_with_quotes += "\"";
5260     const char *c = strstr (json_string, key_with_quotes.c_str());
5261     if (c)
5262     {
5263         c += key_with_quotes.size();
5264 
5265         while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5266             c++;
5267 
5268         if (*c == ':')
5269         {
5270             c++;
5271 
5272             while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5273                 c++;
5274 
5275             errno = 0;
5276             retval = strtoul (c, NULL, 10);
5277             if (errno != 0)
5278             {
5279                 retval = INVALID_NUB_ADDRESS;
5280             }
5281         }
5282     }
5283     return retval;
5284 
5285 }
5286 
5287 // A helper function that retrieves a boolean value from
5288 // a one-level-deep JSON dictionary of key-value pairs.  e.g.
5289 // jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}]
5290 
5291 // Returns true if it was able to find the key name, and sets the 'value'
5292 // argument to the value found.
5293 
5294 bool
5295 get_boolean_value_for_key_name_from_json (const char *key, const char *json_string, bool &value)
5296 {
5297     std::string key_with_quotes = "\"";
5298     key_with_quotes += key;
5299     key_with_quotes += "\"";
5300     const char *c = strstr (json_string, key_with_quotes.c_str());
5301     if (c)
5302     {
5303         c += key_with_quotes.size();
5304 
5305         while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5306             c++;
5307 
5308         if (*c == ':')
5309         {
5310             c++;
5311 
5312             while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5313                 c++;
5314 
5315             if (strncmp (c, "true", 4) == 0)
5316             {
5317                 value = true;
5318                 return true;
5319             } else if (strncmp (c, "false", 5) == 0)
5320             {
5321                 value = false;
5322                 return true;
5323             }
5324         }
5325     }
5326     return false;
5327 }
5328 
5329 // A helper function that reads an array of uint64_t's from
5330 // a one-level-deep JSON dictionary of key-value pairs.  e.g.
5331 // jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}]
5332 
5333 // Returns true if it was able to find the key name, false if it did not.
5334 // "ints" will have all integers found in the array appended to it.
5335 
5336 bool
5337 get_array_of_ints_value_for_key_name_from_json (const char *key, const char *json_string, std::vector<uint64_t> &ints)
5338 {
5339     std::string key_with_quotes = "\"";
5340     key_with_quotes += key;
5341     key_with_quotes += "\"";
5342     const char *c = strstr (json_string, key_with_quotes.c_str());
5343     if (c)
5344     {
5345         c += key_with_quotes.size();
5346 
5347         while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5348             c++;
5349 
5350         if (*c == ':')
5351         {
5352             c++;
5353 
5354             while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5355                 c++;
5356 
5357             if (*c == '[')
5358             {
5359                 c++;
5360                 while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5361                     c++;
5362                 while (1)
5363                 {
5364                     if (!isdigit (*c))
5365                     {
5366                         return true;
5367                     }
5368 
5369                     errno = 0;
5370                     char *endptr;
5371                     uint64_t value = strtoul (c, &endptr, 10);
5372                     if (errno == 0)
5373                     {
5374                         ints.push_back (value);
5375                     }
5376                     else
5377                     {
5378                         break;
5379                     }
5380                     if (endptr == c || endptr == nullptr || *endptr == '\0')
5381                     {
5382                         break;
5383                     }
5384                     c = endptr;
5385 
5386                     while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5387                         c++;
5388                     if (*c == ',')
5389                         c++;
5390                     while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5391                         c++;
5392                     if (*c == ']')
5393                     {
5394                         return true;
5395                     }
5396                 }
5397             }
5398         }
5399     }
5400     return false;
5401 }
5402 
5403 JSONGenerator::ObjectSP
5404 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only)
5405 {
5406     JSONGenerator::ArraySP threads_array_sp;
5407     if (m_ctx.HasValidProcessID())
5408     {
5409         threads_array_sp.reset(new JSONGenerator::Array());
5410 
5411         nub_process_t pid = m_ctx.ProcessID();
5412 
5413         nub_size_t numthreads = DNBProcessGetNumThreads (pid);
5414         for (nub_size_t i = 0; i < numthreads; ++i)
5415         {
5416             nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i);
5417 
5418             struct DNBThreadStopInfo tid_stop_info;
5419 
5420             const bool stop_info_valid = DNBThreadGetStopReason (pid, tid, &tid_stop_info);
5421 
5422             // If we are doing stop info only, then we only show threads that have a
5423             // valid stop reason
5424             if (threads_with_valid_stop_info_only)
5425             {
5426                 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid)
5427                     continue;
5428             }
5429 
5430             JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary());
5431             thread_dict_sp->AddIntegerItem("tid", tid);
5432 
5433             std::string reason_value("none");
5434 
5435             if (stop_info_valid)
5436             {
5437                 switch (tid_stop_info.reason)
5438                 {
5439                     case eStopTypeInvalid:
5440                         break;
5441 
5442                     case eStopTypeSignal:
5443                         if (tid_stop_info.details.signal.signo != 0)
5444                         {
5445                             thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo);
5446                             reason_value = "signal";
5447                         }
5448                         break;
5449 
5450                     case eStopTypeException:
5451                         if (tid_stop_info.details.exception.type != 0)
5452                         {
5453                             reason_value = "exception";
5454                             thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type);
5455                             JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array());
5456                             for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i)
5457                             {
5458                                 medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i])));
5459                             }
5460                             thread_dict_sp->AddItem("medata", medata_array_sp);
5461                         }
5462                         break;
5463 
5464                     case eStopTypeExec:
5465                         reason_value = "exec";
5466                         break;
5467                 }
5468             }
5469 
5470             thread_dict_sp->AddStringItem("reason", reason_value);
5471 
5472             if (threads_with_valid_stop_info_only == false)
5473             {
5474                 const char *thread_name = DNBThreadGetName (pid, tid);
5475                 if (thread_name && thread_name[0])
5476                     thread_dict_sp->AddStringItem("name", thread_name);
5477 
5478                 thread_identifier_info_data_t thread_ident_info;
5479                 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
5480                 {
5481                     if (thread_ident_info.dispatch_qaddr != 0)
5482                     {
5483                         thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr);
5484 
5485                         const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets();
5486                         if (dispatch_queue_offsets)
5487                         {
5488                             std::string queue_name;
5489                             uint64_t queue_width = 0;
5490                             uint64_t queue_serialnum = 0;
5491                             nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS;
5492                             dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, queue_name, queue_width, queue_serialnum);
5493                             if (dispatch_queue_t == 0 && queue_name.empty() && queue_serialnum == 0)
5494                             {
5495                                 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", false);
5496                             }
5497                             else
5498                             {
5499                                 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", true);
5500                             }
5501                             if (dispatch_queue_t != INVALID_NUB_ADDRESS && dispatch_queue_t != 0)
5502                                 thread_dict_sp->AddIntegerItem("dispatch_queue_t", dispatch_queue_t);
5503                             if (!queue_name.empty())
5504                                 thread_dict_sp->AddStringItem("qname", queue_name);
5505                             if (queue_width == 1)
5506                                 thread_dict_sp->AddStringItem("qkind", "serial");
5507                             else if (queue_width > 1)
5508                                 thread_dict_sp->AddStringItem("qkind", "concurrent");
5509                             if (queue_serialnum > 0)
5510                                 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum);
5511                         }
5512                     }
5513                 }
5514 
5515                 DNBRegisterValue reg_value;
5516 
5517                 if (g_reg_entries != NULL)
5518                 {
5519                     JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary());
5520 
5521                     for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
5522                     {
5523                         // Expedite all registers in the first register set that aren't
5524                         // contained in other registers
5525                         if (g_reg_entries[reg].nub_info.set == 1 &&
5526                             g_reg_entries[reg].nub_info.value_regs == NULL)
5527                         {
5528                             if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
5529                                 continue;
5530 
5531                             std::ostringstream reg_num;
5532                             reg_num << std::dec << g_reg_entries[reg].debugserver_regnum;
5533                             // Encode native byte ordered bytes as hex ascii
5534                             registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size);
5535                         }
5536                     }
5537                     thread_dict_sp->AddItem("registers", registers_dict_sp);
5538                 }
5539 
5540                 // Add expedited stack memory so stack backtracing doesn't need to read anything from the
5541                 // frame pointer chain.
5542                 StackMemoryMap stack_mmap;
5543                 ReadStackMemory (pid, tid, stack_mmap);
5544                 if (!stack_mmap.empty())
5545                 {
5546                     JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array());
5547 
5548                     for (const auto &stack_memory : stack_mmap)
5549                     {
5550                         JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary());
5551                         stack_memory_sp->AddIntegerItem("address", stack_memory.first);
5552                         stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length);
5553                         memory_array_sp->AddItem(stack_memory_sp);
5554                     }
5555                     thread_dict_sp->AddItem("memory", memory_array_sp);
5556                 }
5557             }
5558 
5559             threads_array_sp->AddItem(thread_dict_sp);
5560         }
5561     }
5562     return threads_array_sp;
5563 }
5564 
5565 rnb_err_t
5566 RNBRemote::HandlePacket_jThreadsInfo (const char *p)
5567 {
5568     JSONGenerator::ObjectSP threads_info_sp;
5569     std::ostringstream json;
5570     std::ostringstream reply_strm;
5571     // If we haven't run the process yet, return an error.
5572     if (m_ctx.HasValidProcessID())
5573     {
5574         const bool threads_with_valid_stop_info_only = false;
5575         JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only);
5576 
5577         if (threads_info_sp)
5578         {
5579             std::ostringstream strm;
5580             threads_info_sp->Dump (strm);
5581             std::string binary_packet = binary_encode_string (strm.str());
5582             if (!binary_packet.empty())
5583                 return SendPacket (binary_packet.c_str());
5584         }
5585     }
5586     return SendPacket ("E85");
5587 
5588 }
5589 
5590 rnb_err_t
5591 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
5592 {
5593     nub_process_t pid;
5594     std::ostringstream json;
5595     // If we haven't run the process yet, return an error.
5596     if (!m_ctx.HasValidProcessID())
5597     {
5598         return SendPacket ("E81");
5599     }
5600 
5601     pid = m_ctx.ProcessID();
5602 
5603     const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" };
5604     if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0)
5605     {
5606         p += strlen (thread_extended_info_str);
5607 
5608         uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p);
5609         uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p);
5610         uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p);
5611         uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p);
5612         uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p);
5613         // Commented out the two variables below as they are not being used
5614 //        uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p);
5615 //        uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p);
5616 
5617         if (tid != INVALID_NUB_ADDRESS)
5618         {
5619             nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid);
5620 
5621             uint64_t tsd_address = INVALID_NUB_ADDRESS;
5622             if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS
5623                 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS
5624                 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS)
5625             {
5626                 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
5627             }
5628 
5629             bool timed_out = false;
5630             Genealogy::ThreadActivitySP thread_activity_sp;
5631 
5632             // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base
5633             // and got an invalid value back, then we have a thread in early startup or shutdown and
5634             // it's possible that gathering the genealogy information for this thread go badly.
5635             // Ideally fetching this info for a thread in these odd states shouldn't matter - but
5636             // we've seen some problems with these new SPI and threads in edge-casey states.
5637 
5638             double genealogy_fetch_time = 0;
5639             if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS)
5640             {
5641                 DNBTimer timer(false);
5642                 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out);
5643                 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0;
5644             }
5645 
5646             std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen
5647 
5648             json << "{";
5649 
5650             bool need_to_print_comma = false;
5651 
5652             if (thread_activity_sp && timed_out == false)
5653             {
5654                 const Genealogy::Activity *activity = &thread_activity_sp->current_activity;
5655                 bool need_vouchers_comma_sep = false;
5656                 json << "\"activity_query_timed_out\":false,";
5657                 if (genealogy_fetch_time != 0)
5658                 {
5659                     //  If we append the floating point value with << we'll get it in scientific
5660                     //  notation.
5661                     char floating_point_ascii_buffer[64];
5662                     floating_point_ascii_buffer[0] = '\0';
5663                     snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time);
5664                     if (strlen (floating_point_ascii_buffer) > 0)
5665                     {
5666                         if (need_to_print_comma)
5667                             json << ",";
5668                         need_to_print_comma = true;
5669                         json << "\"activity_query_duration\":" << floating_point_ascii_buffer;
5670                     }
5671                 }
5672                 if (activity->activity_id != 0)
5673                 {
5674                     if (need_to_print_comma)
5675                         json << ",";
5676                     need_to_print_comma = true;
5677                     need_vouchers_comma_sep = true;
5678                     json << "\"activity\":{";
5679                     json <<    "\"start\":" << activity->activity_start << ",";
5680                     json <<    "\"id\":" << activity->activity_id << ",";
5681                     json <<    "\"parent_id\":" << activity->parent_id << ",";
5682                     json <<    "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\",";
5683                     json <<    "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\"";
5684                     json << "}";
5685                 }
5686                 if (thread_activity_sp->messages.size() > 0)
5687                 {
5688                     need_to_print_comma = true;
5689                     if (need_vouchers_comma_sep)
5690                         json << ",";
5691                     need_vouchers_comma_sep = true;
5692                     json << "\"trace_messages\":[";
5693                     bool printed_one_message = false;
5694                     for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter)
5695                     {
5696                         if (printed_one_message)
5697                             json << ",";
5698                         else
5699                             printed_one_message = true;
5700                         json << "{";
5701                         json <<   "\"timestamp\":" << iter->timestamp << ",";
5702                         json <<   "\"activity_id\":" << iter->activity_id << ",";
5703                         json <<   "\"trace_id\":" << iter->trace_id << ",";
5704                         json <<   "\"thread\":" << iter->thread << ",";
5705                         json <<   "\"type\":" << (int) iter->type << ",";
5706                         json <<   "\"process_info_index\":" << iter->process_info_index << ",";
5707                         process_info_indexes.insert (iter->process_info_index);
5708                         json <<   "\"message\":\"" << json_string_quote_metachars (iter->message) << "\"";
5709                         json << "}";
5710                     }
5711                     json << "]";
5712                 }
5713                 if (thread_activity_sp->breadcrumbs.size() == 1)
5714                 {
5715                     need_to_print_comma = true;
5716                     if (need_vouchers_comma_sep)
5717                         json << ",";
5718                     need_vouchers_comma_sep = true;
5719                     json << "\"breadcrumb\":{";
5720                     for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter)
5721                     {
5722                         json <<   "\"breadcrumb_id\":" << iter->breadcrumb_id << ",";
5723                         json <<   "\"activity_id\":" << iter->activity_id << ",";
5724                         json <<   "\"timestamp\":" << iter->timestamp << ",";
5725                         json <<   "\"name\":\"" << json_string_quote_metachars (iter->name) << "\"";
5726                     }
5727                     json << "}";
5728                 }
5729                 if (process_info_indexes.size() > 0)
5730                 {
5731                     need_to_print_comma = true;
5732                     if (need_vouchers_comma_sep)
5733                         json << ",";
5734                     need_vouchers_comma_sep = true;
5735                     bool printed_one_process_info = false;
5736                     for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter)
5737                     {
5738                         if (printed_one_process_info)
5739                             json << ",";
5740                         Genealogy::ProcessExecutableInfoSP image_info_sp;
5741                         uint32_t idx = *iter;
5742                         image_info_sp = DNBGetGenealogyImageInfo (pid, idx);
5743                         if (image_info_sp)
5744                         {
5745                             if (!printed_one_process_info)
5746                             {
5747                                 json << "\"process_infos\":[";
5748                                 printed_one_process_info = true;
5749                             }
5750 
5751                             json << "{";
5752                             char uuid_buf[37];
5753                             uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf);
5754                             json <<   "\"process_info_index\":" << idx << ",";
5755                             json <<  "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\",";
5756                             json <<  "\"image_uuid\":\"" << uuid_buf <<"\"";
5757                             json << "}";
5758                         }
5759                     }
5760                     if (printed_one_process_info)
5761                         json << "]";
5762                 }
5763             }
5764             else
5765             {
5766                 if (timed_out)
5767                 {
5768                     if (need_to_print_comma)
5769                         json << ",";
5770                     need_to_print_comma = true;
5771                     json << "\"activity_query_timed_out\":true";
5772                     if (genealogy_fetch_time != 0)
5773                     {
5774                         //  If we append the floating point value with << we'll get it in scientific
5775                         //  notation.
5776                         char floating_point_ascii_buffer[64];
5777                         floating_point_ascii_buffer[0] = '\0';
5778                         snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time);
5779                         if (strlen (floating_point_ascii_buffer) > 0)
5780                         {
5781                             json << ",";
5782                             json << "\"activity_query_duration\":" << floating_point_ascii_buffer;
5783                         }
5784                     }
5785                 }
5786             }
5787 
5788             if (tsd_address != INVALID_NUB_ADDRESS)
5789             {
5790                 if (need_to_print_comma)
5791                     json << ",";
5792                 need_to_print_comma = true;
5793                 json << "\"tsd_address\":" << tsd_address;
5794 
5795                 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX)
5796                 {
5797                     ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index);
5798                     if (requested_qos.IsValid())
5799                     {
5800                         if (need_to_print_comma)
5801                             json << ",";
5802                         need_to_print_comma = true;
5803                         json << "\"requested_qos\":{";
5804                         json <<    "\"enum_value\":" << requested_qos.enum_value << ",";
5805                         json <<    "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\",";
5806                         json <<    "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\"";
5807                         json << "}";
5808                     }
5809                 }
5810             }
5811 
5812             if (pthread_t_value != INVALID_NUB_ADDRESS)
5813             {
5814                 if (need_to_print_comma)
5815                     json << ",";
5816                 need_to_print_comma = true;
5817                 json << "\"pthread_t\":" << pthread_t_value;
5818             }
5819 
5820             nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid);
5821             if (dispatch_queue_t_value != INVALID_NUB_ADDRESS)
5822             {
5823                 if (need_to_print_comma)
5824                     json << ",";
5825                 need_to_print_comma = true;
5826                 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value;
5827             }
5828 
5829             json << "}";
5830             std::string json_quoted = binary_encode_string (json.str());
5831             return SendPacket (json_quoted);
5832         }
5833     }
5834     return SendPacket ("OK");
5835 }
5836 
5837 //  This packet may be called in one of three ways:
5838 //
5839 //  jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704}
5840 //      Look for an array of the old dyld_all_image_infos style of binary infos at the image_list_address.
5841 //      This an array of {void* load_addr, void* mod_date, void* pathname}
5842 //
5843 //  jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}
5844 //      Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get a list of all the
5845 //      libraries loaded
5846 //
5847 //  jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]}
5848 //      Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get the information
5849 //      about the libraries loaded at these addresses.
5850 //
5851 rnb_err_t
5852 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
5853 {
5854     nub_process_t pid;
5855     // If we haven't run the process yet, return an error.
5856     if (!m_ctx.HasValidProcessID())
5857     {
5858         return SendPacket ("E83");
5859     }
5860 
5861     pid = m_ctx.ProcessID();
5862 
5863     const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" };
5864     if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0)
5865     {
5866         p += strlen (get_loaded_dynamic_libraries_infos_str);
5867 
5868         JSONGenerator::ObjectSP json_sp;
5869 
5870         std::vector<uint64_t> macho_addresses;
5871         bool fetch_all_solibs = false;
5872         if (get_boolean_value_for_key_name_from_json ("fetch_all_solibs", p, fetch_all_solibs) && fetch_all_solibs)
5873         {
5874             json_sp = DNBGetAllLoadedLibrariesInfos (pid);
5875         }
5876         else if (get_array_of_ints_value_for_key_name_from_json ("solib_addresses", p, macho_addresses))
5877         {
5878             json_sp = DNBGetLibrariesInfoForAddresses (pid, macho_addresses);
5879         }
5880         else
5881         {
5882             nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
5883             nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
5884 
5885             if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
5886             {
5887                 json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
5888             }
5889         }
5890 
5891         if (json_sp.get())
5892         {
5893             std::ostringstream json_str;
5894             json_sp->Dump (json_str);
5895             if (json_str.str().size() > 0)
5896             {
5897                 std::string json_str_quoted = binary_encode_string (json_str.str());
5898                 return SendPacket (json_str_quoted.c_str());
5899             }
5900             else
5901             {
5902                 SendPacket ("E84");
5903             }
5904         }
5905     }
5906     return SendPacket ("OK");
5907 }
5908 
5909 // This packet does not currently take any arguments.  So the behavior is
5910 //    jGetSharedCacheInfo:{}
5911 //         send information about the inferior's shared cache
5912 //    jGetSharedCacheInfo:
5913 //         send "OK" to indicate that this packet is supported
5914 rnb_err_t
5915 RNBRemote::HandlePacket_jGetSharedCacheInfo (const char *p)
5916 {
5917     nub_process_t pid;
5918     // If we haven't run the process yet, return an error.
5919     if (!m_ctx.HasValidProcessID())
5920     {
5921         return SendPacket ("E85");
5922     }
5923 
5924     pid = m_ctx.ProcessID();
5925 
5926     const char get_shared_cache_info_str[] = { "jGetSharedCacheInfo:{" };
5927     if (strncmp (p, get_shared_cache_info_str, sizeof (get_shared_cache_info_str) - 1) == 0)
5928     {
5929         JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo (pid);
5930 
5931         if (json_sp.get())
5932         {
5933             std::ostringstream json_str;
5934             json_sp->Dump (json_str);
5935             if (json_str.str().size() > 0)
5936             {
5937                 std::string json_str_quoted = binary_encode_string (json_str.str());
5938                 return SendPacket (json_str_quoted.c_str());
5939             }
5940             else
5941             {
5942                 SendPacket ("E86");
5943             }
5944         }
5945     }
5946     return SendPacket ("OK");
5947 }
5948 
5949 static bool
5950 MachHeaderIsMainExecutable (nub_process_t pid, uint32_t addr_size, nub_addr_t mach_header_addr, mach_header &mh)
5951 {
5952     DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx)", pid, addr_size, mach_header_addr);
5953     const nub_size_t bytes_read = DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh);
5954     if (bytes_read == sizeof(mh))
5955     {
5956         DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx): mh = {\n  magic = 0x%8.8x\n  cpu = 0x%8.8x\n  sub = 0x%8.8x\n  filetype = %u\n  ncmds = %u\n  sizeofcmds = 0x%8.8x\n  flags = 0x%8.8x }", pid, addr_size, mach_header_addr, mh.magic, mh.cputype, mh.cpusubtype, mh.filetype, mh.ncmds, mh.sizeofcmds, mh.flags);
5957         if ((addr_size == 4 && mh.magic == MH_MAGIC) ||
5958             (addr_size == 8 && mh.magic == MH_MAGIC_64))
5959         {
5960             if (mh.filetype == MH_EXECUTE)
5961             {
5962                 DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx) -> this is the executable!!!", pid, addr_size, mach_header_addr);
5963                 return true;
5964             }
5965         }
5966     }
5967     return false;
5968 }
5969 
5970 static nub_addr_t
5971 GetMachHeaderForMainExecutable (const nub_process_t pid, const uint32_t addr_size, mach_header &mh)
5972 {
5973     struct AllImageInfos
5974     {
5975         uint32_t version;
5976         uint32_t dylib_info_count;
5977         uint64_t dylib_info_addr;
5978     };
5979 
5980     uint64_t mach_header_addr = 0;
5981 
5982     const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress (pid);
5983     uint8_t bytes[256];
5984     nub_size_t bytes_read = 0;
5985     DNBDataRef data (bytes, sizeof(bytes), false);
5986     DNBDataRef::offset_t offset = 0;
5987     data.SetPointerSize(addr_size);
5988 
5989     //----------------------------------------------------------------------
5990     // When we are sitting at __dyld_start, the kernel has placed the
5991     // address of the mach header of the main executable on the stack. If we
5992     // read the SP and dereference a pointer, we might find the mach header
5993     // for the executable. We also just make sure there is only 1 thread
5994     // since if we are at __dyld_start we shouldn't have multiple threads.
5995     //----------------------------------------------------------------------
5996     if (DNBProcessGetNumThreads(pid) == 1)
5997     {
5998         nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0);
5999         if (tid != INVALID_NUB_THREAD)
6000         {
6001             DNBRegisterValue sp_value;
6002             if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_SP, &sp_value))
6003             {
6004                 uint64_t sp = addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32;
6005                 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes);
6006                 if (bytes_read == addr_size)
6007                 {
6008                     offset = 0;
6009                     mach_header_addr = data.GetPointer(&offset);
6010                     if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
6011                         return mach_header_addr;
6012                 }
6013             }
6014         }
6015     }
6016 
6017     //----------------------------------------------------------------------
6018     // Check the dyld_all_image_info structure for a list of mach header
6019     // since it is a very easy thing to check
6020     //----------------------------------------------------------------------
6021     if (shlib_addr != INVALID_NUB_ADDRESS)
6022     {
6023         bytes_read = DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes);
6024         if (bytes_read > 0)
6025         {
6026             AllImageInfos aii;
6027             offset = 0;
6028             aii.version = data.Get32(&offset);
6029             aii.dylib_info_count = data.Get32(&offset);
6030             if (aii.dylib_info_count > 0)
6031             {
6032                 aii.dylib_info_addr = data.GetPointer(&offset);
6033                 if (aii.dylib_info_addr != 0)
6034                 {
6035                     const size_t image_info_byte_size = 3 * addr_size;
6036                     for (uint32_t i=0; i<aii.dylib_info_count; ++i)
6037                     {
6038                         bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + i * image_info_byte_size, image_info_byte_size, bytes);
6039                         if (bytes_read != image_info_byte_size)
6040                             break;
6041                         offset = 0;
6042                         mach_header_addr = data.GetPointer(&offset);
6043                         if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
6044                             return mach_header_addr;
6045                     }
6046                 }
6047             }
6048         }
6049     }
6050 
6051     //----------------------------------------------------------------------
6052     // We failed to find the executable's mach header from the all image
6053     // infos and by dereferencing the stack pointer. Now we fall back to
6054     // enumerating the memory regions and looking for regions that are
6055     // executable.
6056     //----------------------------------------------------------------------
6057     DNBRegionInfo region_info;
6058     mach_header_addr = 0;
6059     while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, &region_info))
6060     {
6061         if (region_info.size == 0)
6062             break;
6063 
6064         if (region_info.permissions & eMemoryPermissionsExecutable)
6065         {
6066             DNBLogThreadedIf (LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx) permissions = %c%c%c: checking region for executable mach header", region_info.addr, region_info.addr + region_info.size, (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-');
6067             if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
6068                 return mach_header_addr;
6069         }
6070         else
6071         {
6072             DNBLogThreadedIf (LOG_RNB_PROC, "[0x%16.16llx - 0x%16.16llx): permissions = %c%c%c: skipping region", region_info.addr, region_info.addr + region_info.size, (region_info.permissions & eMemoryPermissionsReadable) ? 'r' : '-', (region_info.permissions & eMemoryPermissionsWritable) ? 'w' : '-', (region_info.permissions & eMemoryPermissionsExecutable) ? 'x' : '-');
6073         }
6074         // Set the address to the next mapped region
6075         mach_header_addr = region_info.addr + region_info.size;
6076     }
6077     bzero (&mh, sizeof(mh));
6078     return INVALID_NUB_ADDRESS;
6079 }
6080 
6081 rnb_err_t
6082 RNBRemote::HandlePacket_qSymbol (const char *command)
6083 {
6084     const char *p = command;
6085     p += strlen ("qSymbol:");
6086     const char *sep = strchr(p, ':');
6087 
6088     std::string symbol_name;
6089     std::string symbol_value_str;
6090     // Extract the symbol value if there is one
6091     if (sep > p)
6092         symbol_value_str.assign(p, sep - p);
6093     p = sep + 1;
6094 
6095     if (*p)
6096     {
6097         // We have a symbol name
6098         symbol_name = decode_hex_ascii_string(p);
6099         if (!symbol_value_str.empty())
6100         {
6101             nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16);
6102             if (symbol_name == "dispatch_queue_offsets")
6103                 m_dispatch_queue_offsets_addr = symbol_value;
6104         }
6105         ++m_qSymbol_index;
6106     }
6107     else
6108     {
6109         // No symbol name, set our symbol index to zero so we can
6110         // read any symbols that we need
6111         m_qSymbol_index = 0;
6112     }
6113 
6114     symbol_name.clear();
6115 
6116     if (m_qSymbol_index == 0)
6117     {
6118         if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS)
6119             symbol_name = "dispatch_queue_offsets";
6120         else
6121             ++m_qSymbol_index;
6122     }
6123 
6124 //    // Lookup next symbol when we have one...
6125 //    if (m_qSymbol_index == 1)
6126 //    {
6127 //    }
6128 
6129 
6130     if (symbol_name.empty())
6131     {
6132         // Done with symbol lookups
6133         return SendPacket ("OK");
6134     }
6135     else
6136     {
6137         std::ostringstream reply;
6138         reply << "qSymbol:";
6139         for (size_t i = 0; i < symbol_name.size(); ++i)
6140             reply << RAWHEX8(symbol_name[i]);
6141         return SendPacket (reply.str().c_str());
6142     }
6143 }
6144 
6145 // Note that all numeric values returned by qProcessInfo are hex encoded,
6146 // including the pid and the cpu type.
6147 
6148 rnb_err_t
6149 RNBRemote::HandlePacket_qProcessInfo (const char *p)
6150 {
6151     nub_process_t pid;
6152     std::ostringstream rep;
6153 
6154     // If we haven't run the process yet, return an error.
6155     if (!m_ctx.HasValidProcessID())
6156         return SendPacket ("E68");
6157 
6158     pid = m_ctx.ProcessID();
6159 
6160     rep << "pid:" << std::hex << pid << ';';
6161 
6162     int procpid_mib[4];
6163     procpid_mib[0] = CTL_KERN;
6164     procpid_mib[1] = KERN_PROC;
6165     procpid_mib[2] = KERN_PROC_PID;
6166     procpid_mib[3] = pid;
6167     struct kinfo_proc proc_kinfo;
6168     size_t proc_kinfo_size = sizeof(struct kinfo_proc);
6169 
6170     if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
6171     {
6172         if (proc_kinfo_size > 0)
6173         {
6174             rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';';
6175             rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ';';
6176             rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ';';
6177             rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ';';
6178             if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
6179                 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';';
6180         }
6181     }
6182 
6183     cpu_type_t cputype = DNBProcessGetCPUType (pid);
6184     if (cputype == 0)
6185     {
6186         DNBLog ("Unable to get the process cpu_type, making a best guess.");
6187         cputype = best_guess_cpu_type();
6188     }
6189 
6190     uint32_t addr_size = 0;
6191     if (cputype != 0)
6192     {
6193         rep << "cputype:" << std::hex << cputype << ";";
6194         if (cputype & CPU_ARCH_ABI64)
6195             addr_size = 8;
6196         else
6197             addr_size = 4;
6198     }
6199 
6200     bool host_cpu_is_64bit = false;
6201     uint32_t is64bit_capable;
6202     size_t is64bit_capable_len = sizeof (is64bit_capable);
6203     if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0)
6204         host_cpu_is_64bit = is64bit_capable != 0;
6205 
6206     uint32_t cpusubtype;
6207     size_t cpusubtype_len = sizeof(cpusubtype);
6208     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
6209     {
6210         // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected
6211         // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the
6212         // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype
6213         // for i386...
6214         if (host_cpu_is_64bit)
6215         {
6216             if (cputype == CPU_TYPE_X86)
6217             {
6218                 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
6219             }
6220             else if (cputype == CPU_TYPE_ARM)
6221             {
6222                 // We can query a process' cputype but we cannot query a process' cpusubtype.
6223                 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we
6224                 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace)
6225                 // with a reasonable CPU_SUBTYPE_ARMV7 subtype.
6226                 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S
6227             }
6228         }
6229         rep << "cpusubtype:" << std::hex << cpusubtype << ';';
6230     }
6231 
6232     bool os_handled = false;
6233     if (addr_size > 0)
6234     {
6235         rep << "ptrsize:" << std::dec << addr_size << ';';
6236 
6237 #if (defined (__x86_64__) || defined (__i386__))
6238         // Try and get the OS type by looking at the load commands in the main
6239         // executable and looking for a LC_VERSION_MIN load command. This is the
6240         // most reliable way to determine the "ostype" value when on desktop.
6241 
6242         mach_header mh;
6243         nub_addr_t exe_mach_header_addr = GetMachHeaderForMainExecutable (pid, addr_size, mh);
6244         if (exe_mach_header_addr != INVALID_NUB_ADDRESS)
6245         {
6246             uint64_t load_command_addr = exe_mach_header_addr + ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header));
6247             load_command lc;
6248             for (uint32_t i=0; i<mh.ncmds && !os_handled; ++i)
6249             {
6250                 const nub_size_t bytes_read = DNBProcessMemoryRead (pid, load_command_addr, sizeof(lc), &lc);
6251                 uint32_t raw_cmd = lc.cmd & ~LC_REQ_DYLD;
6252                 if (bytes_read != sizeof(lc))
6253                     break;
6254                 switch (raw_cmd)
6255                 {
6256                 case LC_VERSION_MIN_IPHONEOS:
6257                     os_handled = true;
6258                     rep << "ostype:ios;";
6259                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_IPHONEOS -> 'ostype:ios;'");
6260                     break;
6261 
6262                 case LC_VERSION_MIN_MACOSX:
6263                     os_handled = true;
6264                     rep << "ostype:macosx;";
6265                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'");
6266                     break;
6267 
6268 #if defined (LC_VERSION_MIN_TVOS)
6269                 case LC_VERSION_MIN_TVOS:
6270                     os_handled = true;
6271                     rep << "ostype:tvos;";
6272                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_TVOS -> 'ostype:tvos;'");
6273                     break;
6274 #endif
6275 
6276 #if defined (LC_VERSION_MIN_WATCHOS)
6277                 case LC_VERSION_MIN_WATCHOS:
6278                     os_handled = true;
6279                     rep << "ostype:watchos;";
6280                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_WATCHOS -> 'ostype:watchos;'");
6281                     break;
6282 #endif
6283 
6284                 default:
6285                     break;
6286                 }
6287                 load_command_addr = load_command_addr + lc.cmdsize;
6288             }
6289         }
6290 #endif
6291     }
6292 
6293     // If we weren't able to find the OS in a LC_VERSION_MIN load command, try
6294     // to set it correctly by using the cpu type and other tricks
6295     if (!os_handled)
6296     {
6297         // The OS in the triple should be "ios" or "macosx" which doesn't match our
6298         // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
6299         // this for now.
6300         if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
6301         {
6302 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
6303             rep << "ostype:tvos;";
6304 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
6305             rep << "ostype:watchos;";
6306 #else
6307             rep << "ostype:ios;";
6308 #endif
6309         }
6310         else
6311         {
6312             bool is_ios_simulator = false;
6313             if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64)
6314             {
6315                 // Check for iOS simulator binaries by getting the process argument
6316                 // and environment and checking for SIMULATOR_UDID in the environment
6317                 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid };
6318 
6319                 uint8_t arg_data[8192];
6320                 size_t arg_data_size = sizeof(arg_data);
6321                 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
6322                 {
6323                     DNBDataRef data (arg_data, arg_data_size, false);
6324                     DNBDataRef::offset_t offset = 0;
6325                     uint32_t argc = data.Get32 (&offset);
6326                     const char *cstr;
6327 
6328                     cstr = data.GetCStr (&offset);
6329                     if (cstr)
6330                     {
6331                         // Skip NULLs
6332                         while (1)
6333                         {
6334                             const char *p = data.PeekCStr(offset);
6335                             if ((p == NULL) || (*p != '\0'))
6336                                 break;
6337                             ++offset;
6338                         }
6339                         // Now skip all arguments
6340                         for (uint32_t i = 0; i < argc; ++i)
6341                         {
6342                             data.GetCStr(&offset);
6343                         }
6344 
6345                         // Now iterate across all environment variables
6346                         while ((cstr = data.GetCStr(&offset)))
6347                         {
6348                             if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0)
6349                             {
6350                                 is_ios_simulator = true;
6351                                 break;
6352                             }
6353                             if (cstr[0] == '\0')
6354                                 break;
6355 
6356                         }
6357                     }
6358                 }
6359             }
6360             if (is_ios_simulator)
6361             {
6362 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
6363                 rep << "ostype:tvos;";
6364 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
6365                 rep << "ostype:watchos;";
6366 #else
6367                 rep << "ostype:ios;";
6368 #endif
6369             }
6370             else
6371             {
6372                 rep << "ostype:macosx;";
6373             }
6374         }
6375     }
6376 
6377     rep << "vendor:apple;";
6378 
6379 #if defined (__LITTLE_ENDIAN__)
6380     rep << "endian:little;";
6381 #elif defined (__BIG_ENDIAN__)
6382     rep << "endian:big;";
6383 #elif defined (__PDP_ENDIAN__)
6384     rep << "endian:pdp;";
6385 #endif
6386 
6387     if (addr_size == 0)
6388     {
6389 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
6390         nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
6391         kern_return_t kr;
6392         x86_thread_state_t gp_regs;
6393         mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
6394         kr = thread_get_state (static_cast<thread_act_t>(thread),
6395                                x86_THREAD_STATE,
6396                                (thread_state_t) &gp_regs,
6397                                &gp_count);
6398         if (kr == KERN_SUCCESS)
6399         {
6400             if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
6401                 rep << "ptrsize:8;";
6402             else
6403                 rep << "ptrsize:4;";
6404         }
6405 #elif defined (__arm__)
6406         rep << "ptrsize:4;";
6407 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE)
6408         nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
6409         kern_return_t kr;
6410         arm_unified_thread_state_t gp_regs;
6411         mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT;
6412         kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE,
6413                                (thread_state_t) &gp_regs, &gp_count);
6414         if (kr == KERN_SUCCESS)
6415         {
6416             if (gp_regs.ash.flavor == ARM_THREAD_STATE64)
6417                 rep << "ptrsize:8;";
6418             else
6419                 rep << "ptrsize:4;";
6420         }
6421 #endif
6422     }
6423 
6424     return SendPacket (rep.str());
6425 }
6426 
6427 const RNBRemote::DispatchQueueOffsets *
6428 RNBRemote::GetDispatchQueueOffsets()
6429 {
6430     if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID())
6431     {
6432         nub_process_t pid = m_ctx.ProcessID();
6433         nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets);
6434         if (bytes_read != sizeof(m_dispatch_queue_offsets))
6435             m_dispatch_queue_offsets.Clear();
6436     }
6437 
6438     if (m_dispatch_queue_offsets.IsValid())
6439         return &m_dispatch_queue_offsets;
6440     else
6441         return nullptr;
6442 }
6443 
6444 void
6445 RNBRemote::EnableCompressionNextSendPacket (compression_types type)
6446 {
6447     m_compression_mode = type;
6448     m_enable_compression_next_send_packet = true;
6449 }
6450 
6451 compression_types
6452 RNBRemote::GetCompressionType ()
6453 {
6454     // The first packet we send back to the debugger after a QEnableCompression request
6455     // should be uncompressed -- so we can indicate whether the compression was enabled
6456     // or not via OK / Enn returns.  After that, all packets sent will be using the
6457     // compression protocol.
6458 
6459     if (m_enable_compression_next_send_packet)
6460     {
6461         // One time, we send back "None" as our compression type
6462         m_enable_compression_next_send_packet = false;
6463         return compression_types::none;
6464     }
6465     return m_compression_mode;
6466 }
6467