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