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