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                 case rnb_err:
1030                     DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err);
1031                     done = true;
1032                     break;
1033 
1034                 case rnb_not_connected:
1035                     DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned not connected...");
1036                     done = true;
1037                     break;
1038             }
1039         }
1040         // START: main receive remote command thread loop
1041         events.ResetEvents (RNBContext::event_read_thread_running);
1042         events.SetEvents (RNBContext::event_read_thread_exiting);
1043     }
1044     DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", __FUNCTION__, arg);
1045     return NULL;
1046 }
1047 
1048 
1049 // If we fail to get back a valid CPU type for the remote process,
1050 // make a best guess for the CPU type based on the currently running
1051 // debugserver binary -- the debugger may not handle the case of an
1052 // un-specified process CPU type correctly.
1053 
1054 static cpu_type_t
1055 best_guess_cpu_type ()
1056 {
1057 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
1058     if (sizeof (char *) == 8)
1059     {
1060         return CPU_TYPE_ARM64;
1061     }
1062     else
1063     {
1064         return CPU_TYPE_ARM;
1065     }
1066 #elif defined (__i386__) || defined (__x86_64__)
1067     if (sizeof (char*) == 8)
1068     {
1069         return CPU_TYPE_X86_64;
1070     }
1071     else
1072     {
1073         return CPU_TYPE_I386;
1074     }
1075 #endif
1076     return 0;
1077 }
1078 
1079 
1080 /* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes
1081  (8-bit bytes).
1082  This encoding uses 0x7d ('}') as an escape character for
1083  0x7d ('}'), 0x23 ('#'), 0x24 ('$'), 0x2a ('*').
1084  LEN is the number of bytes to be processed.  If a character is escaped,
1085  it is 2 characters for LEN.  A LEN of -1 means decode-until-nul-byte
1086  (end of string).  */
1087 
1088 std::vector<uint8_t>
1089 decode_binary_data (const char *str, size_t len)
1090 {
1091     std::vector<uint8_t> bytes;
1092     if (len == 0)
1093     {
1094         return bytes;
1095     }
1096     if (len == (size_t)-1)
1097         len = strlen (str);
1098 
1099     while (len--)
1100     {
1101         unsigned char c = *str;
1102         if (c == 0x7d && len > 0)
1103         {
1104             len--;
1105             str++;
1106             c = *str ^ 0x20;
1107         }
1108         bytes.push_back (c);
1109     }
1110     return bytes;
1111 }
1112 
1113 // Quote any meta characters in a std::string as per the binary
1114 // packet convention in the gdb-remote protocol.
1115 
1116 std::string
1117 binary_encode_string (const std::string &s)
1118 {
1119     std::string output;
1120     const size_t s_size = s.size();
1121     const char *s_chars = s.c_str();
1122 
1123     for (size_t i = 0; i < s_size; i++)
1124     {
1125         unsigned char ch = *(s_chars + i);
1126         if (ch == '#' || ch == '$' || ch == '}' || ch == '*')
1127         {
1128             output.push_back ('}');         // 0x7d
1129             output.push_back (ch ^ 0x20);
1130         }
1131         else
1132         {
1133             output.push_back (ch);
1134         }
1135     }
1136     return output;
1137 }
1138 
1139 // If the value side of a key-value pair in JSON is a string,
1140 // and that string has a " character in it, the " character must
1141 // be escaped.
1142 
1143 std::string
1144 json_string_quote_metachars (const std::string &s)
1145 {
1146     if (s.find('"') == std::string::npos)
1147         return s;
1148 
1149     std::string output;
1150     const size_t s_size = s.size();
1151     const char *s_chars = s.c_str();
1152     for (size_t i = 0; i < s_size; i++)
1153     {
1154         unsigned char ch = *(s_chars + i);
1155         if (ch == '"')
1156         {
1157             output.push_back ('\\');
1158         }
1159         output.push_back (ch);
1160     }
1161     return output;
1162 }
1163 
1164 typedef struct register_map_entry
1165 {
1166     uint32_t        debugserver_regnum; // debugserver register number
1167     uint32_t        offset;     // Offset in bytes into the register context data with no padding between register values
1168     DNBRegisterInfo nub_info;   // debugnub register info
1169     std::vector<uint32_t> value_regnums;
1170     std::vector<uint32_t> invalidate_regnums;
1171 } register_map_entry_t;
1172 
1173 
1174 
1175 // If the notion of registers differs from what is handed out by the
1176 // architecture, then flavors can be defined here.
1177 
1178 static std::vector<register_map_entry_t> g_dynamic_register_map;
1179 static register_map_entry_t *g_reg_entries = NULL;
1180 static size_t g_num_reg_entries = 0;
1181 
1182 void
1183 RNBRemote::Initialize()
1184 {
1185     DNBInitialize();
1186 }
1187 
1188 
1189 bool
1190 RNBRemote::InitializeRegisters (bool force)
1191 {
1192     pid_t pid = m_ctx.ProcessID();
1193     if (pid == INVALID_NUB_PROCESS)
1194         return false;
1195 
1196     DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface", __FUNCTION__);
1197     // Discover the registers by querying the DNB interface and letting it
1198     // state the registers that it would like to export. This allows the
1199     // registers to be discovered using multiple qRegisterInfo calls to get
1200     // all register information after the architecture for the process is
1201     // determined.
1202     if (force)
1203     {
1204         g_dynamic_register_map.clear();
1205         g_reg_entries = NULL;
1206         g_num_reg_entries = 0;
1207     }
1208 
1209     if (g_dynamic_register_map.empty())
1210     {
1211         nub_size_t num_reg_sets = 0;
1212         const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
1213 
1214         assert (num_reg_sets > 0 && reg_sets != NULL);
1215 
1216         uint32_t regnum = 0;
1217         uint32_t reg_data_offset = 0;
1218         typedef std::map<std::string, uint32_t> NameToRegNum;
1219         NameToRegNum name_to_regnum;
1220         for (nub_size_t set = 0; set < num_reg_sets; ++set)
1221         {
1222             if (reg_sets[set].registers == NULL)
1223                 continue;
1224 
1225             for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
1226             {
1227                 register_map_entry_t reg_entry = {
1228                     regnum++,                           // register number starts at zero and goes up with no gaps
1229                     reg_data_offset,                    // Offset into register context data, no gaps between registers
1230                     reg_sets[set].registers[reg],       // DNBRegisterInfo
1231                     {},
1232                     {},
1233                 };
1234 
1235                 name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum;
1236 
1237                 if (reg_entry.nub_info.value_regs == NULL)
1238                 {
1239                     reg_data_offset += reg_entry.nub_info.size;
1240                 }
1241 
1242                 g_dynamic_register_map.push_back (reg_entry);
1243             }
1244         }
1245 
1246         // Now we must find any registers whose values are in other registers and fix up
1247         // the offsets since we removed all gaps...
1248         for (auto &reg_entry: g_dynamic_register_map)
1249         {
1250             if (reg_entry.nub_info.value_regs)
1251             {
1252                 uint32_t new_offset = UINT32_MAX;
1253                 for (size_t i=0; reg_entry.nub_info.value_regs[i] != NULL; ++i)
1254                 {
1255                     const char *name = reg_entry.nub_info.value_regs[i];
1256                     auto pos = name_to_regnum.find(name);
1257                     if (pos != name_to_regnum.end())
1258                     {
1259                         regnum = pos->second;
1260                         reg_entry.value_regnums.push_back(regnum);
1261                         if (regnum < g_dynamic_register_map.size())
1262                         {
1263                             // The offset for value_regs registers is the offset within the register with the lowest offset
1264                             const uint32_t reg_offset = g_dynamic_register_map[regnum].offset + reg_entry.nub_info.offset;
1265                             if (new_offset > reg_offset)
1266                                 new_offset = reg_offset;
1267                         }
1268                     }
1269                 }
1270 
1271                 if (new_offset != UINT32_MAX)
1272                 {
1273                     reg_entry.offset = new_offset;
1274                 }
1275                 else
1276                 {
1277                     DNBLogThreaded("no offset was calculated entry for register %s", reg_entry.nub_info.name);
1278                     reg_entry.offset = UINT32_MAX;
1279                 }
1280             }
1281 
1282             if (reg_entry.nub_info.update_regs)
1283             {
1284                 for (size_t i=0; reg_entry.nub_info.update_regs[i] != NULL; ++i)
1285                 {
1286                     const char *name = reg_entry.nub_info.update_regs[i];
1287                     auto pos = name_to_regnum.find(name);
1288                     if (pos != name_to_regnum.end())
1289                     {
1290                         regnum = pos->second;
1291                         reg_entry.invalidate_regnums.push_back(regnum);
1292                     }
1293                 }
1294             }
1295         }
1296 
1297 
1298 //        for (auto &reg_entry: g_dynamic_register_map)
1299 //        {
1300 //            DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s",
1301 //                           reg_entry.offset,
1302 //                           reg_entry.nub_info.size,
1303 //                           reg_entry.nub_info.value_regs != NULL,
1304 //                           reg_entry.nub_info.name);
1305 //        }
1306 
1307         g_reg_entries = g_dynamic_register_map.data();
1308         g_num_reg_entries = g_dynamic_register_map.size();
1309     }
1310     return true;
1311 }
1312 
1313 /* The inferior has stopped executing; send a packet
1314  to gdb to let it know.  */
1315 
1316 void
1317 RNBRemote::NotifyThatProcessStopped (void)
1318 {
1319     RNBRemote::HandlePacket_last_signal (NULL);
1320     return;
1321 }
1322 
1323 
1324 /* 'A arglen,argnum,arg,...'
1325  Update the inferior context CTX with the program name and arg
1326  list.
1327  The documentation for this packet is underwhelming but my best reading
1328  of this is that it is a series of (len, position #, arg)'s, one for
1329  each argument with "arg" hex encoded (two 0-9a-f chars?).
1330  Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either
1331  is sufficient to get around the "," position separator escape issue.
1332 
1333  e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is
1334 
1335  6,0,676462,4,1,2d71,10,2,612e6f7574
1336 
1337  Note that "argnum" and "arglen" are numbers in base 10.  Again, that's
1338  not documented either way but I'm assuming it's so.  */
1339 
1340 rnb_err_t
1341 RNBRemote::HandlePacket_A (const char *p)
1342 {
1343     if (p == NULL || *p == '\0')
1344     {
1345         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt");
1346     }
1347     p++;
1348     if (*p == '\0' || !isdigit (*p))
1349     {
1350         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt");
1351     }
1352 
1353     /* I promise I don't modify it anywhere in this function.  strtoul()'s
1354      2nd arg has to be non-const which makes it problematic to step
1355      through the string easily.  */
1356     char *buf = const_cast<char *>(p);
1357 
1358     RNBContext& ctx = Context();
1359 
1360     while (*buf != '\0')
1361     {
1362         unsigned long arglen, argnum;
1363         std::string arg;
1364         char *c;
1365 
1366         errno = 0;
1367         arglen = strtoul (buf, &c, 10);
1368         if (errno != 0 && arglen == 0)
1369         {
1370             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt");
1371         }
1372         if (*c != ',')
1373         {
1374             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
1375         }
1376         buf = c + 1;
1377 
1378         errno = 0;
1379         argnum = strtoul (buf, &c, 10);
1380         if (errno != 0 && argnum == 0)
1381         {
1382             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt");
1383         }
1384         if (*c != ',')
1385         {
1386             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
1387         }
1388         buf = c + 1;
1389 
1390         c = buf;
1391         buf = buf + arglen;
1392         while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0')
1393         {
1394             char smallbuf[3];
1395             smallbuf[0] = *c;
1396             smallbuf[1] = *(c + 1);
1397             smallbuf[2] = '\0';
1398 
1399             errno = 0;
1400             int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
1401             if (errno != 0 && ch == 0)
1402             {
1403                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt");
1404             }
1405 
1406             arg.push_back(ch);
1407             c += 2;
1408         }
1409 
1410         ctx.PushArgument (arg.c_str());
1411         if (*buf == ',')
1412             buf++;
1413     }
1414     SendPacket ("OK");
1415 
1416     return rnb_success;
1417 }
1418 
1419 /* 'H c t'
1420  Set the thread for subsequent actions; 'c' for step/continue ops,
1421  'g' for other ops.  -1 means all threads, 0 means any thread.  */
1422 
1423 rnb_err_t
1424 RNBRemote::HandlePacket_H (const char *p)
1425 {
1426     p++;  // skip 'H'
1427     if (*p != 'c' && *p != 'g')
1428     {
1429         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet");
1430     }
1431 
1432     if (!m_ctx.HasValidProcessID())
1433     {
1434         // We allow gdb to connect to a server that hasn't started running
1435         // the target yet.  gdb still wants to ask questions about it and
1436         // freaks out if it gets an error.  So just return OK here.
1437     }
1438 
1439     errno = 0;
1440     nub_thread_t tid = strtoul (p + 1, NULL, 16);
1441     if (errno != 0 && tid == 0)
1442     {
1443         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet");
1444     }
1445     if (*p == 'c')
1446         SetContinueThread (tid);
1447     if (*p == 'g')
1448         SetCurrentThread (tid);
1449 
1450     return SendPacket ("OK");
1451 }
1452 
1453 
1454 rnb_err_t
1455 RNBRemote::HandlePacket_qLaunchSuccess (const char *p)
1456 {
1457     if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0)
1458         return SendPacket("OK");
1459     std::ostringstream ret_str;
1460     std::string status_str;
1461     ret_str << "E" << m_ctx.LaunchStatusAsString(status_str);
1462 
1463     return SendPacket (ret_str.str());
1464 }
1465 
1466 rnb_err_t
1467 RNBRemote::HandlePacket_qShlibInfoAddr (const char *p)
1468 {
1469     if (m_ctx.HasValidProcessID())
1470     {
1471         nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID());
1472         if (shlib_info_addr != INVALID_NUB_ADDRESS)
1473         {
1474             std::ostringstream ostrm;
1475             ostrm << RAW_HEXBASE << shlib_info_addr;
1476             return SendPacket (ostrm.str ());
1477         }
1478     }
1479     return SendPacket ("E44");
1480 }
1481 
1482 rnb_err_t
1483 RNBRemote::HandlePacket_qStepPacketSupported (const char *p)
1484 {
1485     // Normally the "s" packet is mandatory, yet in gdb when using ARM, they
1486     // get around the need for this packet by implementing software single
1487     // stepping from gdb. Current versions of debugserver do support the "s"
1488     // packet, yet some older versions do not. We need a way to tell if this
1489     // packet is supported so we can disable software single stepping in gdb
1490     // for remote targets (so the "s" packet will get used).
1491     return SendPacket("OK");
1492 }
1493 
1494 rnb_err_t
1495 RNBRemote::HandlePacket_qSyncThreadStateSupported (const char *p)
1496 {
1497     // We support attachOrWait meaning attach if the process exists, otherwise wait to attach.
1498     return SendPacket("OK");
1499 }
1500 
1501 rnb_err_t
1502 RNBRemote::HandlePacket_qVAttachOrWaitSupported (const char *p)
1503 {
1504     // We support attachOrWait meaning attach if the process exists, otherwise wait to attach.
1505     return SendPacket("OK");
1506 }
1507 
1508 rnb_err_t
1509 RNBRemote::HandlePacket_qThreadStopInfo (const char *p)
1510 {
1511     p += strlen ("qThreadStopInfo");
1512     nub_thread_t tid = strtoul(p, 0, 16);
1513     return SendStopReplyPacketForThread (tid);
1514 }
1515 
1516 rnb_err_t
1517 RNBRemote::HandlePacket_qThreadInfo (const char *p)
1518 {
1519     // We allow gdb to connect to a server that hasn't started running
1520     // the target yet.  gdb still wants to ask questions about it and
1521     // freaks out if it gets an error.  So just return OK here.
1522     nub_process_t pid = m_ctx.ProcessID();
1523     if (pid == INVALID_NUB_PROCESS)
1524         return SendPacket ("OK");
1525 
1526     // Only "qfThreadInfo" and "qsThreadInfo" get into this function so
1527     // we only need to check the second byte to tell which is which
1528     if (p[1] == 'f')
1529     {
1530         nub_size_t numthreads = DNBProcessGetNumThreads (pid);
1531         std::ostringstream ostrm;
1532         ostrm << "m";
1533         bool first = true;
1534         for (nub_size_t i = 0; i < numthreads; ++i)
1535         {
1536             if (first)
1537                 first = false;
1538             else
1539                 ostrm << ",";
1540             nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
1541             ostrm << std::hex << th;
1542         }
1543         return SendPacket (ostrm.str ());
1544     }
1545     else
1546     {
1547         return SendPacket ("l");
1548     }
1549 }
1550 
1551 rnb_err_t
1552 RNBRemote::HandlePacket_qThreadExtraInfo (const char *p)
1553 {
1554     // We allow gdb to connect to a server that hasn't started running
1555     // the target yet.  gdb still wants to ask questions about it and
1556     // freaks out if it gets an error.  So just return OK here.
1557     nub_process_t pid = m_ctx.ProcessID();
1558     if (pid == INVALID_NUB_PROCESS)
1559         return SendPacket ("OK");
1560 
1561     /* This is supposed to return a string like 'Runnable' or
1562      'Blocked on Mutex'.
1563      The returned string is formatted like the "A" packet - a
1564      sequence of letters encoded in as 2-hex-chars-per-letter.  */
1565     p += strlen ("qThreadExtraInfo");
1566     if (*p++ != ',')
1567         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet");
1568     errno = 0;
1569     nub_thread_t tid = strtoul (p, NULL, 16);
1570     if (errno != 0 && tid == 0)
1571     {
1572         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet");
1573     }
1574 
1575     const char * threadInfo = DNBThreadGetInfo(pid, tid);
1576     if (threadInfo != NULL && threadInfo[0])
1577     {
1578         return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL);
1579     }
1580     else
1581     {
1582         // "OK" == 4f6b
1583         // Return "OK" as a ASCII hex byte stream if things go wrong
1584         return SendPacket ("4f6b");
1585     }
1586 
1587     return SendPacket ("");
1588 }
1589 
1590 
1591 const char *k_space_delimiters = " \t";
1592 static void
1593 skip_spaces (std::string &line)
1594 {
1595     if (!line.empty())
1596     {
1597         size_t space_pos = line.find_first_not_of (k_space_delimiters);
1598         if (space_pos > 0)
1599             line.erase(0, space_pos);
1600     }
1601 }
1602 
1603 static std::string
1604 get_identifier (std::string &line)
1605 {
1606     std::string word;
1607     skip_spaces (line);
1608     const size_t line_size = line.size();
1609     size_t end_pos;
1610     for (end_pos = 0; end_pos < line_size; ++end_pos)
1611     {
1612         if (end_pos == 0)
1613         {
1614             if (isalpha(line[end_pos]) || line[end_pos] == '_')
1615                 continue;
1616         }
1617         else if (isalnum(line[end_pos]) || line[end_pos] == '_')
1618             continue;
1619         break;
1620     }
1621     word.assign (line, 0, end_pos);
1622     line.erase(0, end_pos);
1623     return word;
1624 }
1625 
1626 static std::string
1627 get_operator (std::string &line)
1628 {
1629     std::string op;
1630     skip_spaces (line);
1631     if (!line.empty())
1632     {
1633         if (line[0] == '=')
1634         {
1635             op = '=';
1636             line.erase(0,1);
1637         }
1638     }
1639     return op;
1640 }
1641 
1642 static std::string
1643 get_value (std::string &line)
1644 {
1645     std::string value;
1646     skip_spaces (line);
1647     if (!line.empty())
1648     {
1649         value.swap(line);
1650     }
1651     return value;
1652 }
1653 
1654 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
1655 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
1656 
1657 rnb_err_t
1658 RNBRemote::HandlePacket_qRcmd (const char *p)
1659 {
1660     const char *c = p + strlen("qRcmd,");
1661     std::string line;
1662     while (c[0] && c[1])
1663     {
1664         char smallbuf[3] = { c[0], c[1], '\0' };
1665         errno = 0;
1666         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
1667         if (errno != 0 && ch == 0)
1668             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet");
1669         line.push_back(ch);
1670         c += 2;
1671     }
1672     if (*c == '\0')
1673     {
1674         std::string command = get_identifier(line);
1675         if (command.compare("set") == 0)
1676         {
1677             std::string variable = get_identifier (line);
1678             std::string op = get_operator (line);
1679             std::string value = get_value (line);
1680             if (variable.compare("logfile") == 0)
1681             {
1682                 FILE *log_file = fopen(value.c_str(), "w");
1683                 if (log_file)
1684                 {
1685                     DNBLogSetLogCallback(FileLogCallback, log_file);
1686                     return SendPacket ("OK");
1687                 }
1688                 return SendPacket ("E71");
1689             }
1690             else if (variable.compare("logmask") == 0)
1691             {
1692                 char *end;
1693                 errno = 0;
1694                 uint32_t logmask = static_cast<uint32_t>(strtoul (value.c_str(), &end, 0));
1695                 if (errno == 0 && end && *end == '\0')
1696                 {
1697                     DNBLogSetLogMask (logmask);
1698                     if (!DNBLogGetLogCallback())
1699                         DNBLogSetLogCallback(ASLLogCallback, NULL);
1700                     return SendPacket ("OK");
1701                 }
1702                 errno = 0;
1703                 logmask = static_cast<uint32_t>(strtoul (value.c_str(), &end, 16));
1704                 if (errno == 0 && end && *end == '\0')
1705                 {
1706                     DNBLogSetLogMask (logmask);
1707                     return SendPacket ("OK");
1708                 }
1709                 return SendPacket ("E72");
1710             }
1711             return SendPacket ("E70");
1712         }
1713         return SendPacket ("E69");
1714     }
1715     return SendPacket ("E73");
1716 }
1717 
1718 rnb_err_t
1719 RNBRemote::HandlePacket_qC (const char *p)
1720 {
1721     nub_thread_t tid;
1722     std::ostringstream rep;
1723     // If we haven't run the process yet, we tell the debugger the
1724     // pid is 0.  That way it can know to tell use to run later on.
1725     if (!m_ctx.HasValidProcessID())
1726         tid = 0;
1727     else
1728     {
1729         // Grab the current thread.
1730         tid = DNBProcessGetCurrentThread (m_ctx.ProcessID());
1731         // Make sure we set the current thread so g and p packets return
1732         // the data the gdb will expect.
1733         SetCurrentThread (tid);
1734     }
1735     rep << "QC" << std::hex << tid;
1736     return SendPacket (rep.str());
1737 }
1738 
1739 rnb_err_t
1740 RNBRemote::HandlePacket_qEcho (const char *p)
1741 {
1742     // Just send the exact same packet back that we received to
1743     // synchronize the response packets after a previous packet
1744     // timed out. This allows the debugger to get back on track
1745     // with responses after a packet timeout.
1746     return SendPacket (p);
1747 }
1748 
1749 rnb_err_t
1750 RNBRemote::HandlePacket_qGetPid (const char *p)
1751 {
1752     nub_process_t pid;
1753     std::ostringstream rep;
1754     // If we haven't run the process yet, we tell the debugger the
1755     // pid is 0.  That way it can know to tell use to run later on.
1756     if (m_ctx.HasValidProcessID())
1757         pid = m_ctx.ProcessID();
1758     else
1759         pid = 0;
1760     rep << std::hex << pid;
1761     return SendPacket (rep.str());
1762 }
1763 
1764 rnb_err_t
1765 RNBRemote::HandlePacket_qRegisterInfo (const char *p)
1766 {
1767     if (g_num_reg_entries == 0)
1768         InitializeRegisters ();
1769 
1770     p += strlen ("qRegisterInfo");
1771 
1772     nub_size_t num_reg_sets = 0;
1773     const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets);
1774     uint32_t reg_num = static_cast<uint32_t>(strtoul(p, 0, 16));
1775 
1776     if (reg_num < g_num_reg_entries)
1777     {
1778         const register_map_entry_t *reg_entry = &g_reg_entries[reg_num];
1779         std::ostringstream ostrm;
1780         if (reg_entry->nub_info.name)
1781             ostrm << "name:" << reg_entry->nub_info.name << ';';
1782         if (reg_entry->nub_info.alt)
1783             ostrm << "alt-name:" << reg_entry->nub_info.alt << ';';
1784 
1785         ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';';
1786         ostrm << "offset:" << std::dec << reg_entry->offset << ';';
1787 
1788         switch (reg_entry->nub_info.type)
1789         {
1790             case Uint:      ostrm << "encoding:uint;"; break;
1791             case Sint:      ostrm << "encoding:sint;"; break;
1792             case IEEE754:   ostrm << "encoding:ieee754;"; break;
1793             case Vector:    ostrm << "encoding:vector;"; break;
1794         }
1795 
1796         switch (reg_entry->nub_info.format)
1797         {
1798             case Binary:            ostrm << "format:binary;"; break;
1799             case Decimal:           ostrm << "format:decimal;"; break;
1800             case Hex:               ostrm << "format:hex;"; break;
1801             case Float:             ostrm << "format:float;"; break;
1802             case VectorOfSInt8:     ostrm << "format:vector-sint8;"; break;
1803             case VectorOfUInt8:     ostrm << "format:vector-uint8;"; break;
1804             case VectorOfSInt16:    ostrm << "format:vector-sint16;"; break;
1805             case VectorOfUInt16:    ostrm << "format:vector-uint16;"; break;
1806             case VectorOfSInt32:    ostrm << "format:vector-sint32;"; break;
1807             case VectorOfUInt32:    ostrm << "format:vector-uint32;"; break;
1808             case VectorOfFloat32:   ostrm << "format:vector-float32;"; break;
1809             case VectorOfUInt128:   ostrm << "format:vector-uint128;"; break;
1810         };
1811 
1812         if (reg_set_info && reg_entry->nub_info.set < num_reg_sets)
1813             ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';';
1814 
1815         if (reg_entry->nub_info.reg_ehframe != INVALID_NUB_REGNUM)
1816             ostrm << "ehframe:" << std::dec << reg_entry->nub_info.reg_ehframe << ';';
1817 
1818         if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM)
1819             ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';';
1820 
1821         switch (reg_entry->nub_info.reg_generic)
1822         {
1823             case GENERIC_REGNUM_FP:     ostrm << "generic:fp;"; break;
1824             case GENERIC_REGNUM_PC:     ostrm << "generic:pc;"; break;
1825             case GENERIC_REGNUM_SP:     ostrm << "generic:sp;"; break;
1826             case GENERIC_REGNUM_RA:     ostrm << "generic:ra;"; break;
1827             case GENERIC_REGNUM_FLAGS:  ostrm << "generic:flags;"; break;
1828             case GENERIC_REGNUM_ARG1:   ostrm << "generic:arg1;"; break;
1829             case GENERIC_REGNUM_ARG2:   ostrm << "generic:arg2;"; break;
1830             case GENERIC_REGNUM_ARG3:   ostrm << "generic:arg3;"; break;
1831             case GENERIC_REGNUM_ARG4:   ostrm << "generic:arg4;"; break;
1832             case GENERIC_REGNUM_ARG5:   ostrm << "generic:arg5;"; break;
1833             case GENERIC_REGNUM_ARG6:   ostrm << "generic:arg6;"; break;
1834             case GENERIC_REGNUM_ARG7:   ostrm << "generic:arg7;"; break;
1835             case GENERIC_REGNUM_ARG8:   ostrm << "generic:arg8;"; break;
1836             default: break;
1837         }
1838 
1839         if (!reg_entry->value_regnums.empty())
1840         {
1841             ostrm << "container-regs:";
1842             for (size_t i=0, n=reg_entry->value_regnums.size(); i < n; ++i)
1843             {
1844                 if (i > 0)
1845                     ostrm << ',';
1846                 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i];
1847             }
1848             ostrm << ';';
1849         }
1850 
1851         if (!reg_entry->invalidate_regnums.empty())
1852         {
1853             ostrm << "invalidate-regs:";
1854             for (size_t i=0, n=reg_entry->invalidate_regnums.size(); i < n; ++i)
1855             {
1856                 if (i > 0)
1857                     ostrm << ',';
1858                 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i];
1859             }
1860             ostrm << ';';
1861         }
1862 
1863         return SendPacket (ostrm.str ());
1864     }
1865     return SendPacket ("E45");
1866 }
1867 
1868 
1869 /* This expects a packet formatted like
1870 
1871  QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
1872 
1873  with the "QSetLogging:" already removed from the start.  Maybe in the
1874  future this packet will include other keyvalue pairs like
1875 
1876  QSetLogging:bitmask=LOG_ALL;mode=asl;
1877  */
1878 
1879 rnb_err_t
1880 set_logging (const char *p)
1881 {
1882     int bitmask = 0;
1883     while (p && *p != '\0')
1884     {
1885         if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0)
1886         {
1887             p += sizeof ("bitmask=") - 1;
1888             while (p && *p != '\0' && *p != ';')
1889             {
1890                 if (*p == '|')
1891                     p++;
1892 
1893 // to regenerate the LOG_ entries (not including the LOG_RNB entries)
1894 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'`
1895 // do
1896 //   echo "                else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)"
1897 //   echo "                {"
1898 //   echo "                    p += sizeof (\"$logname\") - 1;"
1899 //   echo "                    bitmask |= $logname;"
1900 //   echo "                }"
1901 // done
1902                 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
1903                 {
1904                     p += sizeof ("LOG_VERBOSE") - 1;
1905                     bitmask |= LOG_VERBOSE;
1906                 }
1907                 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0)
1908                 {
1909                     p += sizeof ("LOG_PROCESS") - 1;
1910                     bitmask |= LOG_PROCESS;
1911                 }
1912                 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0)
1913                 {
1914                     p += sizeof ("LOG_THREAD") - 1;
1915                     bitmask |= LOG_THREAD;
1916                 }
1917                 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0)
1918                 {
1919                     p += sizeof ("LOG_EXCEPTIONS") - 1;
1920                     bitmask |= LOG_EXCEPTIONS;
1921                 }
1922                 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0)
1923                 {
1924                     p += sizeof ("LOG_SHLIB") - 1;
1925                     bitmask |= LOG_SHLIB;
1926                 }
1927                 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0)
1928                 {
1929                     p += sizeof ("LOG_MEMORY") - 1;
1930                     bitmask |= LOG_MEMORY;
1931                 }
1932                 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0)
1933                 {
1934                     p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1;
1935                     bitmask |= LOG_MEMORY_DATA_SHORT;
1936                 }
1937                 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0)
1938                 {
1939                     p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
1940                     bitmask |= LOG_MEMORY_DATA_LONG;
1941                 }
1942                 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0)
1943                 {
1944                     p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1;
1945                     bitmask |= LOG_MEMORY_PROTECTIONS;
1946                 }
1947                 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
1948                 {
1949                     p += sizeof ("LOG_BREAKPOINTS") - 1;
1950                     bitmask |= LOG_BREAKPOINTS;
1951                 }
1952                 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
1953                 {
1954                     p += sizeof ("LOG_EVENTS") - 1;
1955                     bitmask |= LOG_EVENTS;
1956                 }
1957                 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0)
1958                 {
1959                     p += sizeof ("LOG_WATCHPOINTS") - 1;
1960                     bitmask |= LOG_WATCHPOINTS;
1961                 }
1962                 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0)
1963                 {
1964                     p += sizeof ("LOG_STEP") - 1;
1965                     bitmask |= LOG_STEP;
1966                 }
1967                 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0)
1968                 {
1969                     p += sizeof ("LOG_TASK") - 1;
1970                     bitmask |= LOG_TASK;
1971                 }
1972                 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
1973                 {
1974                     p += sizeof ("LOG_ALL") - 1;
1975                     bitmask |= LOG_ALL;
1976                 }
1977                 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
1978                 {
1979                     p += sizeof ("LOG_DEFAULT") - 1;
1980                     bitmask |= LOG_DEFAULT;
1981                 }
1982 // end of auto-generated entries
1983 
1984                 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
1985                 {
1986                     p += sizeof ("LOG_NONE") - 1;
1987                     bitmask = 0;
1988                 }
1989                 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0)
1990                 {
1991                     p += sizeof ("LOG_RNB_MINIMAL") - 1;
1992                     bitmask |= LOG_RNB_MINIMAL;
1993                 }
1994                 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0)
1995                 {
1996                     p += sizeof ("LOG_RNB_MEDIUM") - 1;
1997                     bitmask |= LOG_RNB_MEDIUM;
1998                 }
1999                 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0)
2000                 {
2001                     p += sizeof ("LOG_RNB_MAX") - 1;
2002                     bitmask |= LOG_RNB_MAX;
2003                 }
2004                 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0)
2005                 {
2006                     p += sizeof ("LOG_RNB_COMM") - 1;
2007                     bitmask |= LOG_RNB_COMM;
2008                 }
2009                 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0)
2010                 {
2011                     p += sizeof ("LOG_RNB_REMOTE") - 1;
2012                     bitmask |= LOG_RNB_REMOTE;
2013                 }
2014                 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0)
2015                 {
2016                     p += sizeof ("LOG_RNB_EVENTS") - 1;
2017                     bitmask |= LOG_RNB_EVENTS;
2018                 }
2019                 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0)
2020                 {
2021                     p += sizeof ("LOG_RNB_PROC") - 1;
2022                     bitmask |= LOG_RNB_PROC;
2023                 }
2024                 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0)
2025                 {
2026                     p += sizeof ("LOG_RNB_PACKETS") - 1;
2027                     bitmask |= LOG_RNB_PACKETS;
2028                 }
2029                 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0)
2030                 {
2031                     p += sizeof ("LOG_RNB_ALL") - 1;
2032                     bitmask |= LOG_RNB_ALL;
2033                 }
2034                 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0)
2035                 {
2036                     p += sizeof ("LOG_RNB_DEFAULT") - 1;
2037                     bitmask |= LOG_RNB_DEFAULT;
2038                 }
2039                 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0)
2040                 {
2041                     p += sizeof ("LOG_RNB_NONE") - 1;
2042                     bitmask = 0;
2043                 }
2044                 else
2045                 {
2046                     /* Unrecognized logging bit; ignore it.  */
2047                     const char *c = strchr (p, '|');
2048                     if (c)
2049                     {
2050                         p = c;
2051                     }
2052                     else
2053                     {
2054                         c = strchr (p, ';');
2055                         if (c)
2056                         {
2057                             p = c;
2058                         }
2059                         else
2060                         {
2061                             // Improperly terminated word; just go to end of str
2062                             p = strchr (p, '\0');
2063                         }
2064                     }
2065                 }
2066             }
2067             // Did we get a properly formatted logging bitmask?
2068             if (p && *p == ';')
2069             {
2070                 // Enable DNB logging
2071                 DNBLogSetLogCallback(ASLLogCallback, NULL);
2072                 DNBLogSetLogMask (bitmask);
2073                 p++;
2074             }
2075         }
2076         // We're not going to support logging to a file for now.  All logging
2077         // goes through ASL.
2078 #if 0
2079         else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
2080         {
2081             p += sizeof ("mode=") - 1;
2082             if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
2083             {
2084                 DNBLogToASL ();
2085                 p += sizeof ("asl;") - 1;
2086             }
2087             else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
2088             {
2089                 DNBLogToFile ();
2090                 p += sizeof ("file;") - 1;
2091             }
2092             else
2093             {
2094                 // Ignore unknown argument
2095                 const char *c = strchr (p, ';');
2096                 if (c)
2097                     p = c + 1;
2098                 else
2099                     p = strchr (p, '\0');
2100             }
2101         }
2102         else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
2103         {
2104             p += sizeof ("filename=") - 1;
2105             const char *c = strchr (p, ';');
2106             if (c == NULL)
2107             {
2108                 c = strchr (p, '\0');
2109                 continue;
2110             }
2111             char *fn = (char *) alloca (c - p + 1);
2112             strncpy (fn, p, c - p);
2113             fn[c - p] = '\0';
2114 
2115             // A file name of "asl" is special and is another way to indicate
2116             // that logging should be done via ASL, not by file.
2117             if (strcmp (fn, "asl") == 0)
2118             {
2119                 DNBLogToASL ();
2120             }
2121             else
2122             {
2123                 FILE *f = fopen (fn, "w");
2124                 if (f)
2125                 {
2126                     DNBLogSetLogFile (f);
2127                     DNBEnableLogging (f, DNBLogGetLogMask ());
2128                     DNBLogToFile ();
2129                 }
2130             }
2131             p = c + 1;
2132         }
2133 #endif /* #if 0 to enforce ASL logging only.  */
2134         else
2135         {
2136             // Ignore unknown argument
2137             const char *c = strchr (p, ';');
2138             if (c)
2139                 p = c + 1;
2140             else
2141                 p = strchr (p, '\0');
2142         }
2143     }
2144 
2145     return rnb_success;
2146 }
2147 
2148 rnb_err_t
2149 RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
2150 {
2151     m_thread_suffix_supported = true;
2152     return SendPacket ("OK");
2153 }
2154 
2155 rnb_err_t
2156 RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
2157 {
2158     // Send the OK packet first so the correct checksum is appended...
2159     rnb_err_t result = SendPacket ("OK");
2160     m_noack_mode = true;
2161     return result;
2162 }
2163 
2164 
2165 rnb_err_t
2166 RNBRemote::HandlePacket_QSetLogging (const char *p)
2167 {
2168     p += sizeof ("QSetLogging:") - 1;
2169     rnb_err_t result = set_logging (p);
2170     if (result == rnb_success)
2171         return SendPacket ("OK");
2172     else
2173         return SendPacket ("E35");
2174 }
2175 
2176 rnb_err_t
2177 RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
2178 {
2179     extern int g_disable_aslr;
2180     p += sizeof ("QSetDisableASLR:") - 1;
2181     switch (*p)
2182     {
2183     case '0': g_disable_aslr = 0; break;
2184     case '1': g_disable_aslr = 1; break;
2185     default:
2186         return SendPacket ("E56");
2187     }
2188     return SendPacket ("OK");
2189 }
2190 
2191 rnb_err_t
2192 RNBRemote::HandlePacket_QSetSTDIO (const char *p)
2193 {
2194     // Only set stdin/out/err if we don't already have a process
2195     if (!m_ctx.HasValidProcessID())
2196     {
2197         bool success = false;
2198         // Check the seventh character since the packet will be one of:
2199         // QSetSTDIN
2200         // QSetSTDOUT
2201         // QSetSTDERR
2202         StringExtractor packet(p);
2203         packet.SetFilePos (7);
2204         char ch = packet.GetChar();
2205         while (packet.GetChar() != ':')
2206             /* Do nothing. */;
2207 
2208         switch (ch)
2209         {
2210             case 'I': // STDIN
2211                 packet.GetHexByteString (m_ctx.GetSTDIN());
2212                 success = !m_ctx.GetSTDIN().empty();
2213                 break;
2214 
2215             case 'O': // STDOUT
2216                 packet.GetHexByteString (m_ctx.GetSTDOUT());
2217                 success = !m_ctx.GetSTDOUT().empty();
2218                 break;
2219 
2220             case 'E': // STDERR
2221                 packet.GetHexByteString (m_ctx.GetSTDERR());
2222                 success = !m_ctx.GetSTDERR().empty();
2223                 break;
2224 
2225             default:
2226                 break;
2227         }
2228         if (success)
2229             return SendPacket ("OK");
2230         return SendPacket ("E57");
2231     }
2232     return SendPacket ("E58");
2233 }
2234 
2235 rnb_err_t
2236 RNBRemote::HandlePacket_QSetWorkingDir (const char *p)
2237 {
2238     // Only set the working directory if we don't already have a process
2239     if (!m_ctx.HasValidProcessID())
2240     {
2241         StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);
2242         if (packet.GetHexByteString (m_ctx.GetWorkingDir()))
2243         {
2244             struct stat working_dir_stat;
2245             if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1)
2246             {
2247                 m_ctx.GetWorkingDir().clear();
2248                 return SendPacket ("E61");    // Working directory doesn't exist...
2249             }
2250             else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR)
2251             {
2252                 return SendPacket ("OK");
2253             }
2254             else
2255             {
2256                 m_ctx.GetWorkingDir().clear();
2257                 return SendPacket ("E62");    // Working directory isn't a directory...
2258             }
2259         }
2260         return SendPacket ("E59");  // Invalid path
2261     }
2262     return SendPacket ("E60"); // Already had a process, too late to set working dir
2263 }
2264 
2265 rnb_err_t
2266 RNBRemote::HandlePacket_QSyncThreadState (const char *p)
2267 {
2268     if (!m_ctx.HasValidProcessID())
2269     {
2270         // We allow gdb to connect to a server that hasn't started running
2271         // the target yet.  gdb still wants to ask questions about it and
2272         // freaks out if it gets an error.  So just return OK here.
2273         return SendPacket ("OK");
2274     }
2275 
2276     errno = 0;
2277     p += strlen("QSyncThreadState:");
2278     nub_thread_t tid = strtoul (p, NULL, 16);
2279     if (errno != 0 && tid == 0)
2280     {
2281         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet");
2282     }
2283     if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid))
2284         return SendPacket("OK");
2285     else
2286         return SendPacket ("E61");
2287 }
2288 
2289 rnb_err_t
2290 RNBRemote::HandlePacket_QSetDetachOnError (const char *p)
2291 {
2292     p += sizeof ("QSetDetachOnError:") - 1;
2293     bool should_detach = true;
2294     switch (*p)
2295     {
2296         case '0': should_detach = false; break;
2297         case '1': should_detach = true; break;
2298         default:
2299           return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid value for QSetDetachOnError - should be 0 or 1");
2300           break;
2301     }
2302 
2303     m_ctx.SetDetachOnError(should_detach);
2304     return SendPacket ("OK");
2305 }
2306 
2307 rnb_err_t
2308 RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p)
2309 {
2310     // If this packet is received, it allows us to send an extra key/value
2311     // pair in the stop reply packets where we will list all of the thread IDs
2312     // separated by commas:
2313     //
2314     //  "threads:10a,10b,10c;"
2315     //
2316     // This will get included in the stop reply packet as something like:
2317     //
2318     //  "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;"
2319     //
2320     // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and
2321     // speed things up a bit.
2322     //
2323     // Send the OK packet first so the correct checksum is appended...
2324     rnb_err_t result = SendPacket ("OK");
2325     m_list_threads_in_stop_reply = true;
2326 
2327     return result;
2328 }
2329 
2330 
2331 rnb_err_t
2332 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
2333 {
2334     /* The number of characters in a packet payload that gdb is
2335      prepared to accept.  The packet-start char, packet-end char,
2336      2 checksum chars and terminating null character are not included
2337      in this size.  */
2338     p += sizeof ("QSetMaxPayloadSize:") - 1;
2339     errno = 0;
2340     uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16));
2341     if (errno != 0 && size == 0)
2342     {
2343         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
2344     }
2345     m_max_payload_size = size;
2346     return SendPacket ("OK");
2347 }
2348 
2349 rnb_err_t
2350 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
2351 {
2352     /* This tells us the largest packet that gdb can handle.
2353      i.e. the size of gdb's packet-reading buffer.
2354      QSetMaxPayloadSize is preferred because it is less ambiguous.  */
2355     p += sizeof ("QSetMaxPacketSize:") - 1;
2356     errno = 0;
2357     uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16));
2358     if (errno != 0 && size == 0)
2359     {
2360         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
2361     }
2362     m_max_payload_size = size - 5;
2363     return SendPacket ("OK");
2364 }
2365 
2366 
2367 
2368 
2369 rnb_err_t
2370 RNBRemote::HandlePacket_QEnvironment (const char *p)
2371 {
2372     /* This sets the environment for the target program.  The packet is of the form:
2373 
2374      QEnvironment:VARIABLE=VALUE
2375 
2376      */
2377 
2378     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
2379                       (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2380 
2381     p += sizeof ("QEnvironment:") - 1;
2382     RNBContext& ctx = Context();
2383 
2384     ctx.PushEnvironment (p);
2385     return SendPacket ("OK");
2386 }
2387 
2388 rnb_err_t
2389 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p)
2390 {
2391     /* This sets the environment for the target program.  The packet is of the form:
2392 
2393         QEnvironmentHexEncoded:VARIABLE=VALUE
2394 
2395         The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with special
2396         meaning in the remote protocol won't break it.
2397     */
2398 
2399     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"",
2400         (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2401 
2402     p += sizeof ("QEnvironmentHexEncoded:") - 1;
2403 
2404     std::string arg;
2405     const char *c;
2406     c = p;
2407     while (*c != '\0')
2408       {
2409         if (*(c + 1) == '\0')
2410         {
2411             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2412         }
2413         char smallbuf[3];
2414         smallbuf[0] = *c;
2415         smallbuf[1] = *(c + 1);
2416         smallbuf[2] = '\0';
2417         errno = 0;
2418         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
2419         if (errno != 0 && ch == 0)
2420           {
2421             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2422           }
2423         arg.push_back(ch);
2424         c += 2;
2425       }
2426 
2427     RNBContext& ctx = Context();
2428     if (arg.length() > 0)
2429       ctx.PushEnvironment (arg.c_str());
2430 
2431     return SendPacket ("OK");
2432 }
2433 
2434 
2435 rnb_err_t
2436 RNBRemote::HandlePacket_QLaunchArch (const char *p)
2437 {
2438     p += sizeof ("QLaunchArch:") - 1;
2439     if (DNBSetArchitecture(p))
2440         return SendPacket ("OK");
2441     return SendPacket ("E63");
2442 }
2443 
2444 rnb_err_t
2445 RNBRemote::HandlePacket_QSetProcessEvent (const char *p)
2446 {
2447     p += sizeof ("QSetProcessEvent:") - 1;
2448     // If the process is running, then send the event to the process, otherwise
2449     // store it in the context.
2450     if (Context().HasValidProcessID())
2451     {
2452         if (DNBProcessSendEvent (Context().ProcessID(), p))
2453             return SendPacket("OK");
2454         else
2455             return SendPacket ("E80");
2456     }
2457     else
2458     {
2459         Context().PushProcessEvent(p);
2460     }
2461     return SendPacket ("OK");
2462 }
2463 
2464 void
2465 append_hex_value (std::ostream& ostrm, const void *buf, size_t buf_size, bool swap)
2466 {
2467     int i;
2468     const uint8_t *p = (const uint8_t *)buf;
2469     if (swap)
2470     {
2471         for (i = static_cast<int>(buf_size)-1; i >= 0; i--)
2472             ostrm << RAWHEX8(p[i]);
2473     }
2474     else
2475     {
2476         for (size_t i = 0; i < buf_size; i++)
2477             ostrm << RAWHEX8(p[i]);
2478     }
2479 }
2480 
2481 void
2482 append_hexified_string (std::ostream& ostrm, const std::string &string)
2483 {
2484     size_t string_size = string.size();
2485     const char *string_buf = string.c_str();
2486     for (size_t i = 0; i < string_size; i++)
2487     {
2488             ostrm << RAWHEX8(*(string_buf + i));
2489     }
2490 }
2491 
2492 
2493 
2494 void
2495 register_value_in_hex_fixed_width (std::ostream& ostrm,
2496                                    nub_process_t pid,
2497                                    nub_thread_t tid,
2498                                    const register_map_entry_t* reg,
2499                                    const DNBRegisterValue *reg_value_ptr)
2500 {
2501     if (reg != NULL)
2502     {
2503         DNBRegisterValue reg_value;
2504         if (reg_value_ptr == NULL)
2505         {
2506             if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &reg_value))
2507                 reg_value_ptr = &reg_value;
2508         }
2509 
2510         if (reg_value_ptr)
2511         {
2512             append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false);
2513         }
2514         else
2515         {
2516             // If we fail to read a register value, check if it has a default
2517             // fail value. If it does, return this instead in case some of
2518             // the registers are not available on the current system.
2519             if (reg->nub_info.size > 0)
2520             {
2521                 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0');
2522                 append_hex_value (ostrm, zeros.data(), zeros.size(), false);
2523             }
2524         }
2525     }
2526 }
2527 
2528 
2529 void
2530 debugserver_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
2531                                                 nub_process_t pid,
2532                                                 nub_thread_t tid,
2533                                                 const register_map_entry_t* reg,
2534                                                 const DNBRegisterValue *reg_value_ptr)
2535 {
2536     // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
2537     // gdb register number, and VVVVVVVV is the correct number of hex bytes
2538     // as ASCII for the register value.
2539     if (reg != NULL)
2540     {
2541         ostrm << RAWHEX8(reg->debugserver_regnum) << ':';
2542         register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr);
2543         ostrm << ';';
2544     }
2545 }
2546 
2547 
2548 void
2549 RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid,
2550                                                      nub_addr_t dispatch_qaddr,
2551                                                      nub_addr_t &dispatch_queue_t,
2552                                                      std::string &queue_name,
2553                                                      uint64_t &queue_width,
2554                                                      uint64_t &queue_serialnum) const
2555 {
2556     queue_name.clear();
2557     queue_width = 0;
2558     queue_serialnum = 0;
2559 
2560     if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && dispatch_qaddr != 0)
2561     {
2562         dispatch_queue_t = DNBProcessMemoryReadPointer (pid, dispatch_qaddr);
2563         if (dispatch_queue_t)
2564         {
2565             queue_width = DNBProcessMemoryReadInteger (pid, dispatch_queue_t + dqo_width, dqo_width_size, 0);
2566             queue_serialnum = DNBProcessMemoryReadInteger (pid, dispatch_queue_t + dqo_serialnum, dqo_serialnum_size, 0);
2567 
2568             if (dqo_version >= 4)
2569             {
2570                 // libdispatch versions 4+, pointer to dispatch name is in the
2571                 // queue structure.
2572                 nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label;
2573                 nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address);
2574                 if (label_addr)
2575                     queue_name = DNBProcessMemoryReadCString(pid, label_addr);
2576             }
2577             else
2578             {
2579                 // libdispatch versions 1-3, dispatch name is a fixed width char array
2580                 // in the queue structure.
2581                 queue_name = DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size);
2582             }
2583         }
2584     }
2585 }
2586 
2587 struct StackMemory
2588 {
2589     uint8_t bytes[2*sizeof(nub_addr_t)];
2590     nub_size_t length;
2591 };
2592 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap;
2593 
2594 
2595 static void
2596 ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap, uint32_t backtrace_limit = 256)
2597 {
2598     DNBRegisterValue reg_value;
2599     if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, &reg_value))
2600     {
2601         uint32_t frame_count = 0;
2602         uint64_t fp = 0;
2603         if (reg_value.info.size == 4)
2604             fp = reg_value.value.uint32;
2605         else
2606             fp = reg_value.value.uint64;
2607         while (fp != 0)
2608         {
2609             // Make sure we never recurse more than 256 times so we don't recurse too far or
2610             // store up too much memory in the expedited cache
2611             if (++frame_count > backtrace_limit)
2612                 break;
2613 
2614             const nub_size_t read_size = reg_value.info.size*2;
2615             StackMemory stack_memory;
2616             stack_memory.length = read_size;
2617             if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size)
2618                 break;
2619             // Make sure we don't try to put the same stack memory in more than once
2620             if (stack_mmap.find(fp) != stack_mmap.end())
2621                 break;
2622             // Put the entry into the cache
2623             stack_mmap[fp] = stack_memory;
2624             // Dereference the frame pointer to get to the previous frame pointer
2625             if (reg_value.info.size == 4)
2626                 fp = ((uint32_t *)stack_memory.bytes)[0];
2627             else
2628                 fp = ((uint64_t *)stack_memory.bytes)[0];
2629         }
2630     }
2631 }
2632 
2633 rnb_err_t
2634 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
2635 {
2636     const nub_process_t pid = m_ctx.ProcessID();
2637     if (pid == INVALID_NUB_PROCESS)
2638         return SendPacket("E50");
2639 
2640     struct DNBThreadStopInfo tid_stop_info;
2641 
2642     /* Fill the remaining space in this packet with as many registers
2643      as we can stuff in there.  */
2644 
2645     if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
2646     {
2647         const bool did_exec = tid_stop_info.reason == eStopTypeExec;
2648         if (did_exec)
2649         {
2650             RNBRemote::InitializeRegisters(true);
2651 
2652             // Reset any symbols that need resetting when we exec
2653             m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS;
2654             m_dispatch_queue_offsets.Clear();
2655         }
2656 
2657         std::ostringstream ostrm;
2658         // Output the T packet with the thread
2659         ostrm << 'T';
2660         int signum = tid_stop_info.details.signal.signo;
2661         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);
2662 
2663         // Translate any mach exceptions to gdb versions, unless they are
2664         // common exceptions like a breakpoint or a soft signal.
2665         switch (tid_stop_info.details.exception.type)
2666         {
2667             default:                    signum = 0; break;
2668             case EXC_BREAKPOINT:        signum = SIGTRAP; break;
2669             case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2670             case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2671             case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2672             case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2673             case EXC_SOFTWARE:
2674                 if (tid_stop_info.details.exception.data_count == 2 &&
2675                     tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2676                     signum = static_cast<int>(tid_stop_info.details.exception.data[1]);
2677                 else
2678                     signum = TARGET_EXC_SOFTWARE;
2679                 break;
2680         }
2681 
2682         ostrm << RAWHEX8(signum & 0xff);
2683 
2684         ostrm << std::hex << "thread:" << tid << ';';
2685 
2686         const char *thread_name = DNBThreadGetName (pid, tid);
2687         if (thread_name && thread_name[0])
2688         {
2689             size_t thread_name_len = strlen(thread_name);
2690 
2691 
2692             if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2693                 ostrm << std::hex << "name:" << thread_name << ';';
2694             else
2695             {
2696                 // the thread name contains special chars, send as hex bytes
2697                 ostrm << std::hex << "hexname:";
2698                 uint8_t *u_thread_name = (uint8_t *)thread_name;
2699                 for (size_t i = 0; i < thread_name_len; i++)
2700                     ostrm << RAWHEX8(u_thread_name[i]);
2701                 ostrm << ';';
2702             }
2703         }
2704 
2705         // If a 'QListThreadsInStopReply' was sent to enable this feature, we
2706         // will send all thread IDs back in the "threads" key whose value is
2707         // a list of hex thread IDs separated by commas:
2708         //  "threads:10a,10b,10c;"
2709         // This will save the debugger from having to send a pair of qfThreadInfo
2710         // and qsThreadInfo packets, but it also might take a lot of room in the
2711         // stop reply packet, so it must be enabled only on systems where there
2712         // are no limits on packet lengths.
2713         if (m_list_threads_in_stop_reply)
2714         {
2715             const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
2716             if (numthreads > 0)
2717             {
2718                 std::vector<uint64_t> pc_values;
2719                 ostrm << std::hex << "threads:";
2720                 for (nub_size_t i = 0; i < numthreads; ++i)
2721                 {
2722                     nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
2723                     if (i > 0)
2724                         ostrm << ',';
2725                     ostrm << std::hex << th;
2726                     DNBRegisterValue pc_regval;
2727                     if (DNBThreadGetRegisterValueByID (pid, th, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_regval))
2728                     {
2729                         uint64_t pc = INVALID_NUB_ADDRESS;
2730                         if (pc_regval.value.uint64 != INVALID_NUB_ADDRESS)
2731                         {
2732                             if (pc_regval.info.size == 4)
2733                             {
2734                                 pc = pc_regval.value.uint32;
2735                             }
2736                             else if (pc_regval.info.size == 8)
2737                             {
2738                                 pc = pc_regval.value.uint64;
2739                             }
2740                             if (pc != INVALID_NUB_ADDRESS)
2741                             {
2742                                 pc_values.push_back (pc);
2743                             }
2744                         }
2745                     }
2746                 }
2747                 ostrm << ';';
2748 
2749                 // If we failed to get any of the thread pc values, the size of our vector will not
2750                 // be the same as the # of threads.  Don't provide any expedited thread pc values in
2751                 // that case.  This should not happen.
2752                 if (pc_values.size() == numthreads)
2753                 {
2754                     ostrm << std::hex << "thread-pcs:";
2755                     for (nub_size_t i = 0; i < numthreads; ++i)
2756                     {
2757                         if (i > 0)
2758                             ostrm << ',';
2759                         ostrm << std::hex << pc_values[i];
2760                     }
2761                     ostrm << ';';
2762                 }
2763             }
2764 
2765             // Include JSON info that describes the stop reason for any threads
2766             // that actually have stop reasons. We use the new "jstopinfo" key
2767             // whose values is hex ascii JSON that contains the thread IDs
2768             // thread stop info only for threads that have stop reasons. Only send
2769             // this if we have more than one thread otherwise this packet has all
2770             // the info it needs.
2771             if (numthreads > 1)
2772             {
2773                 const bool threads_with_valid_stop_info_only = true;
2774                 JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only);
2775                 if (threads_info_sp)
2776                 {
2777                     ostrm << std::hex << "jstopinfo:";
2778                     std::ostringstream json_strm;
2779                     threads_info_sp->Dump (json_strm);
2780                     append_hexified_string (ostrm, json_strm.str());
2781                     ostrm << ';';
2782                 }
2783             }
2784         }
2785 
2786         if (g_num_reg_entries == 0)
2787             InitializeRegisters ();
2788 
2789         if (g_reg_entries != NULL)
2790         {
2791             DNBRegisterValue reg_value;
2792             for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2793             {
2794                 // Expedite all registers in the first register set that aren't
2795                 // contained in other registers
2796                 if (g_reg_entries[reg].nub_info.set == 1 &&
2797                     g_reg_entries[reg].nub_info.value_regs == NULL)
2798                 {
2799                     if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
2800                         continue;
2801 
2802                     debugserver_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], &reg_value);
2803                 }
2804             }
2805         }
2806 
2807         if (did_exec)
2808         {
2809             ostrm << "reason:exec;";
2810         }
2811         else if (tid_stop_info.details.exception.type)
2812         {
2813             ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';';
2814             ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';';
2815             for (nub_size_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
2816                 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';';
2817         }
2818 
2819         // Add expedited stack memory so stack backtracing doesn't need to read anything from the
2820         // frame pointer chain.
2821         StackMemoryMap stack_mmap;
2822         ReadStackMemory (pid, tid, stack_mmap, 2);
2823         if (!stack_mmap.empty())
2824         {
2825             for (const auto &stack_memory : stack_mmap)
2826             {
2827                 ostrm << "memory:" << HEXBASE << stack_memory.first << '=';
2828                 append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false);
2829                 ostrm << ';';
2830             }
2831         }
2832 
2833         return SendPacket (ostrm.str ());
2834     }
2835     return SendPacket("E51");
2836 }
2837 
2838 /* '?'
2839  The stop reply packet - tell gdb what the status of the inferior is.
2840  Often called the questionmark_packet.  */
2841 
2842 rnb_err_t
2843 RNBRemote::HandlePacket_last_signal (const char *unused)
2844 {
2845     if (!m_ctx.HasValidProcessID())
2846     {
2847         // Inferior is not yet specified/running
2848         return SendPacket ("E02");
2849     }
2850 
2851     nub_process_t pid = m_ctx.ProcessID();
2852     nub_state_t pid_state = DNBProcessGetState (pid);
2853 
2854     switch (pid_state)
2855     {
2856         case eStateAttaching:
2857         case eStateLaunching:
2858         case eStateRunning:
2859         case eStateStepping:
2860         case eStateDetached:
2861             return rnb_success;  // Ignore
2862 
2863         case eStateSuspended:
2864         case eStateStopped:
2865         case eStateCrashed:
2866             {
2867                 nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2868                 // Make sure we set the current thread so g and p packets return
2869                 // the data the gdb will expect.
2870                 SetCurrentThread (tid);
2871 
2872                 SendStopReplyPacketForThread (tid);
2873             }
2874             break;
2875 
2876         case eStateInvalid:
2877         case eStateUnloaded:
2878         case eStateExited:
2879             {
2880                 char pid_exited_packet[16] = "";
2881                 int pid_status = 0;
2882                 // Process exited with exit status
2883                 if (!DNBProcessGetExitStatus(pid, &pid_status))
2884                     pid_status = 0;
2885 
2886                 if (pid_status)
2887                 {
2888                     if (WIFEXITED (pid_status))
2889                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2890                     else if (WIFSIGNALED (pid_status))
2891                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2892                     else if (WIFSTOPPED (pid_status))
2893                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2894                 }
2895 
2896                 // If we have an empty exit packet, lets fill one in to be safe.
2897                 if (!pid_exited_packet[0])
2898                 {
2899                     strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2900                     pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2901                 }
2902 
2903                 const char *exit_info = DNBProcessGetExitInfo (pid);
2904                 if (exit_info != NULL && *exit_info != '\0')
2905                 {
2906                     std::ostringstream exit_packet;
2907                     exit_packet << pid_exited_packet;
2908                     exit_packet << ';';
2909                     exit_packet << RAW_HEXBASE << "description";
2910                     exit_packet << ':';
2911                     for (size_t i = 0; exit_info[i] != '\0'; i++)
2912                         exit_packet << RAWHEX8(exit_info[i]);
2913                     exit_packet << ';';
2914                     return SendPacket (exit_packet.str());
2915                 }
2916                 else
2917                     return SendPacket (pid_exited_packet);
2918             }
2919             break;
2920     }
2921     return rnb_success;
2922 }
2923 
2924 rnb_err_t
2925 RNBRemote::HandlePacket_M (const char *p)
2926 {
2927     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2928     {
2929         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2930     }
2931 
2932     char *c;
2933     p++;
2934     errno = 0;
2935     nub_addr_t addr = strtoull (p, &c, 16);
2936     if (errno != 0 && addr == 0)
2937     {
2938         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2939     }
2940     if (*c != ',')
2941     {
2942         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2943     }
2944 
2945     /* Advance 'p' to the length part of the packet.  */
2946     p += (c - p) + 1;
2947 
2948     errno = 0;
2949     unsigned long length = strtoul (p, &c, 16);
2950     if (errno != 0 && length == 0)
2951     {
2952         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2953     }
2954     if (length == 0)
2955     {
2956         return SendPacket ("OK");
2957     }
2958 
2959     if (*c != ':')
2960     {
2961         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2962     }
2963     /* Advance 'p' to the data part of the packet.  */
2964     p += (c - p) + 1;
2965 
2966     size_t datalen = strlen (p);
2967     if (datalen & 0x1)
2968     {
2969         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2970     }
2971     if (datalen == 0)
2972     {
2973         return SendPacket ("OK");
2974     }
2975 
2976     uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2977     uint8_t *i = buf;
2978 
2979     while (*p != '\0' && *(p + 1) != '\0')
2980     {
2981         char hexbuf[3];
2982         hexbuf[0] = *p;
2983         hexbuf[1] = *(p + 1);
2984         hexbuf[2] = '\0';
2985         errno = 0;
2986         uint8_t byte = strtoul (hexbuf, NULL, 16);
2987         if (errno != 0 && byte == 0)
2988         {
2989             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2990         }
2991         *i++ = byte;
2992         p += 2;
2993     }
2994 
2995     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2996     if (wrote != length)
2997         return SendPacket ("E09");
2998     else
2999         return SendPacket ("OK");
3000 }
3001 
3002 
3003 rnb_err_t
3004 RNBRemote::HandlePacket_m (const char *p)
3005 {
3006     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3007     {
3008         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
3009     }
3010 
3011     char *c;
3012     p++;
3013     errno = 0;
3014     nub_addr_t addr = strtoull (p, &c, 16);
3015     if (errno != 0 && addr == 0)
3016     {
3017         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
3018     }
3019     if (*c != ',')
3020     {
3021         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
3022     }
3023 
3024     /* Advance 'p' to the length part of the packet.  */
3025     p += (c - p) + 1;
3026 
3027     errno = 0;
3028     auto length = strtoul (p, NULL, 16);
3029     if (errno != 0 && length == 0)
3030     {
3031         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
3032     }
3033     if (length == 0)
3034     {
3035         return SendPacket ("");
3036     }
3037 
3038     std::string buf(length, '\0');
3039     if (buf.empty())
3040     {
3041         return SendPacket ("E78");
3042     }
3043     nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
3044     if (bytes_read == 0)
3045     {
3046         return SendPacket ("E08");
3047     }
3048 
3049     // "The reply may contain fewer bytes than requested if the server was able
3050     //  to read only part of the region of memory."
3051     length = bytes_read;
3052 
3053     std::ostringstream ostrm;
3054     for (unsigned long i = 0; i < length; i++)
3055         ostrm << RAWHEX8(buf[i]);
3056     return SendPacket (ostrm.str ());
3057 }
3058 
3059 // Read memory, sent it up as binary data.
3060 // Usage:  xADDR,LEN
3061 // ADDR and LEN are both base 16.
3062 
3063 // Responds with 'OK' for zero-length request
3064 // or
3065 //
3066 // DATA
3067 //
3068 // where DATA is the binary data payload.
3069 
3070 rnb_err_t
3071 RNBRemote::HandlePacket_x (const char *p)
3072 {
3073     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3074     {
3075         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
3076     }
3077 
3078     char *c;
3079     p++;
3080     errno = 0;
3081     nub_addr_t addr = strtoull (p, &c, 16);
3082     if (errno != 0)
3083     {
3084         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
3085     }
3086     if (*c != ',')
3087     {
3088         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
3089     }
3090 
3091     /* Advance 'p' to the number of bytes to be read.  */
3092     p += (c - p) + 1;
3093 
3094     errno = 0;
3095     auto length = strtoul (p, NULL, 16);
3096     if (errno != 0)
3097     {
3098         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet");
3099     }
3100 
3101     // zero length read means this is a test of whether that packet is implemented or not.
3102     if (length == 0)
3103     {
3104         return SendPacket ("OK");
3105     }
3106 
3107     std::vector<uint8_t> buf (length);
3108 
3109     if (buf.capacity() != length)
3110     {
3111         return SendPacket ("E79");
3112     }
3113     nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
3114     if (bytes_read == 0)
3115     {
3116         return SendPacket ("E80");
3117     }
3118 
3119     std::vector<uint8_t> buf_quoted;
3120     buf_quoted.reserve (bytes_read + 30);
3121     for (nub_size_t i = 0; i < bytes_read; i++)
3122     {
3123         if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*')
3124         {
3125             buf_quoted.push_back(0x7d);
3126             buf_quoted.push_back(buf[i] ^ 0x20);
3127         }
3128         else
3129         {
3130             buf_quoted.push_back(buf[i]);
3131         }
3132     }
3133     length = buf_quoted.size();
3134 
3135     std::ostringstream ostrm;
3136     for (unsigned long i = 0; i < length; i++)
3137         ostrm << buf_quoted[i];
3138 
3139     return SendPacket (ostrm.str ());
3140 }
3141 
3142 rnb_err_t
3143 RNBRemote::HandlePacket_X (const char *p)
3144 {
3145     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3146     {
3147         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
3148     }
3149 
3150     char *c;
3151     p++;
3152     errno = 0;
3153     nub_addr_t addr = strtoull (p, &c, 16);
3154     if (errno != 0 && addr == 0)
3155     {
3156         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
3157     }
3158     if (*c != ',')
3159     {
3160         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
3161     }
3162 
3163     /* Advance 'p' to the length part of the packet.  NB this is the length of the packet
3164        including any escaped chars.  The data payload may be a little bit smaller after
3165        decoding.  */
3166     p += (c - p) + 1;
3167 
3168     errno = 0;
3169     auto length = strtoul (p, NULL, 16);
3170     if (errno != 0 && length == 0)
3171     {
3172         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet");
3173     }
3174 
3175     // I think gdb sends a zero length write request to test whether this
3176     // packet is accepted.
3177     if (length == 0)
3178     {
3179         return SendPacket ("OK");
3180     }
3181 
3182     std::vector<uint8_t> data = decode_binary_data (c, -1);
3183     std::vector<uint8_t>::const_iterator it;
3184     uint8_t *buf = (uint8_t *) alloca (data.size ());
3185     uint8_t *i = buf;
3186     for (it = data.begin (); it != data.end (); ++it)
3187     {
3188         *i++ = *it;
3189     }
3190 
3191     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
3192     if (wrote != data.size ())
3193         return SendPacket ("E08");
3194     return SendPacket ("OK");
3195 }
3196 
3197 /* 'g' -- read registers
3198  Get the contents of the registers for the current thread,
3199  send them to gdb.
3200  Should the setting of the Hg packet determine which thread's registers
3201  are returned?  */
3202 
3203 rnb_err_t
3204 RNBRemote::HandlePacket_g (const char *p)
3205 {
3206     std::ostringstream ostrm;
3207     if (!m_ctx.HasValidProcessID())
3208     {
3209         return SendPacket ("E11");
3210     }
3211 
3212     if (g_num_reg_entries == 0)
3213         InitializeRegisters ();
3214 
3215     nub_process_t pid = m_ctx.ProcessID ();
3216     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
3217     if (tid == INVALID_NUB_THREAD)
3218         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3219 
3220     // Get the register context size first by calling with NULL buffer
3221     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
3222     if (reg_ctx_size)
3223     {
3224         // Now allocate enough space for the entire register context
3225         std::vector<uint8_t> reg_ctx;
3226         reg_ctx.resize(reg_ctx_size);
3227         // Now read the register context
3228         reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
3229         if (reg_ctx_size)
3230         {
3231             append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
3232             return SendPacket (ostrm.str ());
3233         }
3234     }
3235     return SendPacket ("E74");
3236 }
3237 
3238 /* 'G XXX...' -- write registers
3239  How is the thread for these specified, beyond "the current thread"?
3240  Does gdb actually use the Hg packet to set this?  */
3241 
3242 rnb_err_t
3243 RNBRemote::HandlePacket_G (const char *p)
3244 {
3245     if (!m_ctx.HasValidProcessID())
3246     {
3247         return SendPacket ("E11");
3248     }
3249 
3250     if (g_num_reg_entries == 0)
3251         InitializeRegisters ();
3252 
3253     StringExtractor packet(p);
3254     packet.SetFilePos(1); // Skip the 'G'
3255 
3256     nub_process_t pid = m_ctx.ProcessID();
3257     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3258     if (tid == INVALID_NUB_THREAD)
3259         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3260 
3261     // Get the register context size first by calling with NULL buffer
3262     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
3263     if (reg_ctx_size)
3264     {
3265         // Now allocate enough space for the entire register context
3266         std::vector<uint8_t> reg_ctx;
3267         reg_ctx.resize(reg_ctx_size);
3268 
3269         const nub_size_t bytes_extracted = packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc);
3270         if (bytes_extracted == reg_ctx.size())
3271         {
3272             // Now write the register context
3273             reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
3274             if (reg_ctx_size == reg_ctx.size())
3275                 return SendPacket ("OK");
3276             else
3277                 return SendPacket ("E55");
3278         }
3279         else
3280         {
3281             DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size);
3282             return SendPacket ("E64");
3283         }
3284     }
3285     return SendPacket ("E65");
3286 }
3287 
3288 static bool
3289 RNBRemoteShouldCancelCallback (void *not_used)
3290 {
3291     RNBRemoteSP remoteSP(g_remoteSP);
3292     if (remoteSP.get() != NULL)
3293     {
3294         RNBRemote* remote = remoteSP.get();
3295         if (remote->Comm().IsConnected())
3296             return false;
3297         else
3298             return true;
3299     }
3300     return true;
3301 }
3302 
3303 
3304 // FORMAT: _MXXXXXX,PPP
3305 //      XXXXXX: big endian hex chars
3306 //      PPP: permissions can be any combo of r w x chars
3307 //
3308 // RESPONSE: XXXXXX
3309 //      XXXXXX: hex address of the newly allocated memory
3310 //      EXX: error code
3311 //
3312 // EXAMPLES:
3313 //      _M123000,rw
3314 //      _M123000,rwx
3315 //      _M123000,xw
3316 
3317 rnb_err_t
3318 RNBRemote::HandlePacket_AllocateMemory (const char *p)
3319 {
3320     StringExtractor packet (p);
3321     packet.SetFilePos(2); // Skip the "_M"
3322 
3323     nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
3324     if (size != 0)
3325     {
3326         if (packet.GetChar() == ',')
3327         {
3328             uint32_t permissions = 0;
3329             char ch;
3330             bool success = true;
3331             while (success && (ch = packet.GetChar()) != '\0')
3332             {
3333                 switch (ch)
3334                 {
3335                 case 'r':   permissions |= eMemoryPermissionsReadable; break;
3336                 case 'w':   permissions |= eMemoryPermissionsWritable; break;
3337                 case 'x':   permissions |= eMemoryPermissionsExecutable; break;
3338                 default:    success = false; break;
3339                 }
3340             }
3341 
3342             if (success)
3343             {
3344                 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
3345                 if (addr != INVALID_NUB_ADDRESS)
3346                 {
3347                     std::ostringstream ostrm;
3348                     ostrm << RAW_HEXBASE << addr;
3349                     return SendPacket (ostrm.str ());
3350                 }
3351             }
3352         }
3353     }
3354     return SendPacket ("E53");
3355 }
3356 
3357 // FORMAT: _mXXXXXX
3358 //      XXXXXX: address that was previously allocated
3359 //
3360 // RESPONSE: XXXXXX
3361 //      OK: address was deallocated
3362 //      EXX: error code
3363 //
3364 // EXAMPLES:
3365 //      _m123000
3366 
3367 rnb_err_t
3368 RNBRemote::HandlePacket_DeallocateMemory (const char *p)
3369 {
3370     StringExtractor packet (p);
3371     packet.SetFilePos(2); // Skip the "_m"
3372     nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
3373 
3374     if (addr != INVALID_NUB_ADDRESS)
3375     {
3376         if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
3377             return SendPacket ("OK");
3378     }
3379     return SendPacket ("E54");
3380 }
3381 
3382 
3383 // FORMAT: QSaveRegisterState;thread:TTTT;  (when thread suffix is supported)
3384 // FORMAT: QSaveRegisterState               (when thread suffix is NOT supported)
3385 //      TTTT: thread ID in hex
3386 //
3387 // RESPONSE:
3388 //      SAVEID: Where SAVEID is a decimal number that represents the save ID
3389 //              that can be passed back into a "QRestoreRegisterState" packet
3390 //      EXX: error code
3391 //
3392 // EXAMPLES:
3393 //      QSaveRegisterState;thread:1E34;     (when thread suffix is supported)
3394 //      QSaveRegisterState                  (when thread suffix is NOT supported)
3395 
3396 rnb_err_t
3397 RNBRemote::HandlePacket_SaveRegisterState (const char *p)
3398 {
3399     nub_process_t pid = m_ctx.ProcessID ();
3400     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3401     if (tid == INVALID_NUB_THREAD)
3402     {
3403         if (m_thread_suffix_supported)
3404             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
3405         else
3406             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
3407     }
3408 
3409     // Get the register context size first by calling with NULL buffer
3410     const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid);
3411     if (save_id != 0)
3412     {
3413         char response[64];
3414         snprintf (response, sizeof(response), "%u", save_id);
3415         return SendPacket (response);
3416     }
3417     else
3418     {
3419         return SendPacket ("E75");
3420     }
3421 }
3422 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT;  (when thread suffix is supported)
3423 // FORMAT: QRestoreRegisterState:SAVEID               (when thread suffix is NOT supported)
3424 //      TTTT: thread ID in hex
3425 //      SAVEID: a decimal number that represents the save ID that was
3426 //              returned from a call to "QSaveRegisterState"
3427 //
3428 // RESPONSE:
3429 //      OK: successfully restored registers for the specified thread
3430 //      EXX: error code
3431 //
3432 // EXAMPLES:
3433 //      QRestoreRegisterState:1;thread:1E34;     (when thread suffix is supported)
3434 //      QRestoreRegisterState:1                  (when thread suffix is NOT supported)
3435 
3436 rnb_err_t
3437 RNBRemote::HandlePacket_RestoreRegisterState (const char *p)
3438 {
3439     nub_process_t pid = m_ctx.ProcessID ();
3440     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3441     if (tid == INVALID_NUB_THREAD)
3442     {
3443         if (m_thread_suffix_supported)
3444             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
3445         else
3446             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
3447     }
3448 
3449     StringExtractor packet (p);
3450     packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:"
3451     const uint32_t save_id = packet.GetU32(0);
3452 
3453     if (save_id != 0)
3454     {
3455         // Get the register context size first by calling with NULL buffer
3456         if (DNBThreadRestoreRegisterState(pid, tid, save_id))
3457             return SendPacket ("OK");
3458         else
3459             return SendPacket ("E77");
3460     }
3461     return SendPacket ("E76");
3462 }
3463 
3464 static bool
3465 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name)
3466 {
3467     bool return_val = true;
3468     while (*p != '\0')
3469     {
3470         char smallbuf[3];
3471         smallbuf[0] = *p;
3472         smallbuf[1] = *(p + 1);
3473         smallbuf[2] = '\0';
3474 
3475         errno = 0;
3476         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
3477         if (errno != 0 && ch == 0)
3478         {
3479             return_val = false;
3480             break;
3481         }
3482 
3483         attach_name.push_back(ch);
3484         p += 2;
3485     }
3486     return return_val;
3487 }
3488 
3489 rnb_err_t
3490 RNBRemote::HandlePacket_qSupported (const char *p)
3491 {
3492     uint32_t max_packet_size = 128 * 1024;  // 128KBytes is a reasonable max packet size--debugger can always use less
3493     char buf[256];
3494     snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", max_packet_size);
3495 
3496     // By default, don't enable compression.  It's only worth doing when we are working
3497     // with a low speed communication channel.
3498     bool enable_compression = false;
3499     (void)enable_compression;
3500 
3501     // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth.
3502 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
3503     enable_compression = true;
3504 #endif
3505 
3506 #if defined (HAVE_LIBCOMPRESSION)
3507     // libcompression is weak linked so test if compression_decode_buffer() is available
3508     if (enable_compression && compression_decode_buffer != NULL)
3509     {
3510         strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize=");
3511         char numbuf[16];
3512         snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize);
3513         numbuf[sizeof (numbuf) - 1] = '\0';
3514         strcat (buf, numbuf);
3515     }
3516 #elif defined (HAVE_LIBZ)
3517     if (enable_compression)
3518     {
3519         strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize=");
3520         char numbuf[16];
3521         snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize);
3522         numbuf[sizeof (numbuf) - 1] = '\0';
3523         strcat (buf, numbuf);
3524     }
3525 #endif
3526 
3527     return SendPacket (buf);
3528 }
3529 
3530 /*
3531  vAttach;pid
3532 
3533  Attach to a new process with the specified process ID. pid is a hexadecimal integer
3534  identifying the process. If the stub is currently controlling a process, it is
3535  killed. The attached process is stopped.This packet is only available in extended
3536  mode (see extended mode).
3537 
3538  Reply:
3539  "ENN"                      for an error
3540  "Any Stop Reply Packet"     for success
3541  */
3542 
3543 rnb_err_t
3544 RNBRemote::HandlePacket_v (const char *p)
3545 {
3546     if (strcmp (p, "vCont;c") == 0)
3547     {
3548         // Simple continue
3549         return RNBRemote::HandlePacket_c("c");
3550     }
3551     else if (strcmp (p, "vCont;s") == 0)
3552     {
3553         // Simple step
3554         return RNBRemote::HandlePacket_s("s");
3555     }
3556     else if (strstr (p, "vCont") == p)
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         DNBLogThreaded ("RNBRemote::HandlePacket_stop_process() sending extra stop reply because DNBProcessInterrupt returned false");
4431         HandlePacket_last_signal (NULL);
4432     }
4433     return rnb_success;
4434 #endif
4435 }
4436 
4437 /* 's'
4438  Step the inferior process.  */
4439 
4440 rnb_err_t
4441 RNBRemote::HandlePacket_s (const char *p)
4442 {
4443     const nub_process_t pid = m_ctx.ProcessID();
4444     if (pid == INVALID_NUB_PROCESS)
4445         return SendPacket ("E32");
4446 
4447     // Hardware supported stepping not supported on arm
4448     nub_thread_t tid = GetContinueThread ();
4449     if (tid == 0 || tid == (nub_thread_t)-1)
4450         tid = GetCurrentThread();
4451 
4452     if (tid == INVALID_NUB_THREAD)
4453         return SendPacket ("E33");
4454 
4455     DNBThreadResumeActions thread_actions;
4456     thread_actions.AppendAction(tid, eStateStepping);
4457 
4458     // Make all other threads stop when we are stepping
4459     thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
4460     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4461         return SendPacket ("E49");
4462     // Don't send an "OK" packet; response is the stopped/exited message.
4463     return rnb_success;
4464 }
4465 
4466 /* 'S sig [;addr]'
4467  Step with signal sig, optionally at address addr.  */
4468 
4469 rnb_err_t
4470 RNBRemote::HandlePacket_S (const char *p)
4471 {
4472     const nub_process_t pid = m_ctx.ProcessID();
4473     if (pid == INVALID_NUB_PROCESS)
4474         return SendPacket ("E36");
4475 
4476     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
4477 
4478     if (*(p + 1) != '\0')
4479     {
4480         char *end = NULL;
4481         errno = 0;
4482         action.signal = static_cast<int>(strtoul (p + 1, &end, 16));
4483         if (errno != 0)
4484             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
4485         else if (*end == ';')
4486         {
4487             errno = 0;
4488             action.addr = strtoull (end + 1, NULL, 16);
4489             if (errno != 0 && action.addr == 0)
4490             {
4491                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
4492             }
4493         }
4494     }
4495 
4496     action.tid = GetContinueThread ();
4497     if (action.tid == 0 || action.tid == (nub_thread_t)-1)
4498         return SendPacket ("E40");
4499 
4500     nub_state_t tstate = DNBThreadGetState (pid, action.tid);
4501     if (tstate == eStateInvalid || tstate == eStateExited)
4502         return SendPacket ("E37");
4503 
4504 
4505     DNBThreadResumeActions thread_actions;
4506     thread_actions.Append (action);
4507 
4508     // Make all other threads stop when we are stepping
4509     thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
4510     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4511         return SendPacket ("E39");
4512 
4513     // Don't send an "OK" packet; response is the stopped/exited message.
4514     return rnb_success;
4515 }
4516 
4517 static const char *
4518 GetArchName (const uint32_t cputype, const uint32_t cpusubtype)
4519 {
4520     switch (cputype)
4521     {
4522     case CPU_TYPE_ARM:
4523         switch (cpusubtype)
4524         {
4525         case 5:     return "armv4";
4526         case 6:     return "armv6";
4527         case 7:     return "armv5t";
4528         case 8:     return "xscale";
4529         case 9:     return "armv7";
4530         case 10:    return "armv7f";
4531         case 11:    return "armv7s";
4532         case 12:    return "armv7k";
4533         case 14:    return "armv6m";
4534         case 15:    return "armv7m";
4535         case 16:    return "armv7em";
4536         default:    return "arm";
4537         }
4538         break;
4539     case CPU_TYPE_ARM64:    return "arm64";
4540     case CPU_TYPE_I386:     return "i386";
4541     case CPU_TYPE_X86_64:
4542         switch (cpusubtype)
4543         {
4544         default:    return "x86_64";
4545         case 8:     return "x86_64h";
4546         }
4547         break;
4548     }
4549     return NULL;
4550 }
4551 
4552 static bool
4553 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64)
4554 {
4555     static uint32_t g_host_cputype = 0;
4556     static uint32_t g_host_cpusubtype = 0;
4557     static uint32_t g_is_64_bit_capable = 0;
4558     static bool g_promoted_to_64 = false;
4559 
4560     if (g_host_cputype == 0)
4561     {
4562         g_promoted_to_64 = false;
4563         size_t len = sizeof(uint32_t);
4564         if  (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0)
4565         {
4566             len = sizeof (uint32_t);
4567             if  (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0)
4568             {
4569                 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0))
4570                 {
4571                     g_promoted_to_64 = true;
4572                     g_host_cputype |= CPU_ARCH_ABI64;
4573                 }
4574             }
4575         }
4576 
4577         len = sizeof(uint32_t);
4578         if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0)
4579         {
4580             if (g_promoted_to_64 &&
4581                 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486)
4582                 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL;
4583         }
4584     }
4585 
4586     cputype = g_host_cputype;
4587     cpusubtype = g_host_cpusubtype;
4588     is_64_bit_capable = g_is_64_bit_capable;
4589     promoted_to_64 = g_promoted_to_64;
4590     return g_host_cputype != 0;
4591 }
4592 
4593 rnb_err_t
4594 RNBRemote::HandlePacket_qHostInfo (const char *p)
4595 {
4596     std::ostringstream strm;
4597 
4598     uint32_t cputype = 0;
4599     uint32_t cpusubtype = 0;
4600     uint32_t is_64_bit_capable = 0;
4601     bool promoted_to_64 = false;
4602     if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64))
4603     {
4604         strm << "cputype:" << std::dec << cputype << ';';
4605         strm << "cpusubtype:" << std::dec << cpusubtype << ';';
4606     }
4607 
4608     // The OS in the triple should be "ios" or "macosx" which doesn't match our
4609     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
4610     // this for now.
4611     if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
4612     {
4613 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
4614         strm << "ostype:tvos;";
4615 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
4616         strm << "ostype:watchos;";
4617 #else
4618         strm << "ostype:ios;";
4619 #endif
4620 
4621         // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
4622         strm << "watchpoint_exceptions_received:before;";
4623     }
4624     else
4625     {
4626         strm << "ostype:macosx;";
4627         strm << "watchpoint_exceptions_received:after;";
4628     }
4629 //    char ostype[64];
4630 //    len = sizeof(ostype);
4631 //    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
4632 //    {
4633 //        len = strlen(ostype);
4634 //        std::transform (ostype, ostype + len, ostype, tolower);
4635 //        strm << "ostype:" << std::dec << ostype << ';';
4636 //    }
4637 
4638     strm << "vendor:apple;";
4639 
4640     uint64_t major, minor, patch;
4641     if (DNBGetOSVersionNumbers (&major, &minor, &patch))
4642     {
4643         strm << "os_version:" << major << "." << minor;
4644         if (patch != UINT64_MAX)
4645             strm << "." << patch;
4646         strm << ";";
4647     }
4648 
4649 #if defined (__LITTLE_ENDIAN__)
4650     strm << "endian:little;";
4651 #elif defined (__BIG_ENDIAN__)
4652     strm << "endian:big;";
4653 #elif defined (__PDP_ENDIAN__)
4654     strm << "endian:pdp;";
4655 #endif
4656 
4657     if (promoted_to_64)
4658         strm << "ptrsize:8;";
4659     else
4660         strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
4661 
4662 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
4663     strm << "default_packet_timeout:10;";
4664 #endif
4665 
4666     return SendPacket (strm.str());
4667 }
4668 
4669 void
4670 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes)
4671 {
4672     if (indent)
4673         s << INDENT_WITH_SPACES(indent);
4674     s << '<' << name;
4675     if (!has_attributes)
4676         s << '>' << std::endl;
4677 }
4678 
4679 void
4680 XMLElementStartEndAttributes (std::ostringstream &s, bool empty)
4681 {
4682     if (empty)
4683         s << '/';
4684     s << '>' << std::endl;
4685 }
4686 
4687 void
4688 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name)
4689 {
4690     if (indent)
4691         s << INDENT_WITH_SPACES(indent);
4692     s << '<' << '/' << name << '>' << std::endl;
4693 }
4694 
4695 void
4696 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true)
4697 {
4698     if (value)
4699     {
4700         if (indent)
4701             s << INDENT_WITH_SPACES(indent);
4702         s << '<' << name << '>' << value;
4703         if (close)
4704             XMLElementEnd(s, 0, name);
4705     }
4706 }
4707 
4708 void
4709 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true)
4710 {
4711     if (indent)
4712         s << INDENT_WITH_SPACES(indent);
4713 
4714     s << '<' << name << '>' << DECIMAL << value;
4715     if (close)
4716         XMLElementEnd(s, 0, name);
4717 }
4718 
4719 void
4720 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL)
4721 {
4722     if (value)
4723     {
4724         if (default_value && strcmp(value, default_value) == 0)
4725             return; // No need to emit the attribute because it matches the default value
4726         s <<' ' << name << "=\"" << value << "\"";
4727     }
4728 }
4729 
4730 void
4731 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value)
4732 {
4733     s <<' ' << name << "=\"" << DECIMAL << value << "\"";
4734 }
4735 
4736 void
4737 GenerateTargetXMLRegister (std::ostringstream &s,
4738                            const uint32_t reg_num,
4739                            nub_size_t num_reg_sets,
4740                            const DNBRegisterSetInfo *reg_set_info,
4741                            const register_map_entry_t &reg)
4742 {
4743     const char *default_lldb_encoding = "uint";
4744     const char *lldb_encoding = default_lldb_encoding;
4745     const char *gdb_group = "general";
4746     const char *default_gdb_type = "int";
4747     const char *gdb_type = default_gdb_type;
4748     const char *default_lldb_format = "hex";
4749     const char *lldb_format = default_lldb_format;
4750     const char *lldb_set = NULL;
4751 
4752     switch (reg.nub_info.type)
4753     {
4754         case Uint:      lldb_encoding = "uint"; break;
4755         case Sint:      lldb_encoding = "sint"; break;
4756         case IEEE754:   lldb_encoding = "ieee754";  if (reg.nub_info.set > 0) gdb_group = "float"; break;
4757         case Vector:    lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break;
4758     }
4759 
4760     switch (reg.nub_info.format)
4761     {
4762         case Binary:            lldb_format = "binary"; break;
4763         case Decimal:           lldb_format = "decimal"; break;
4764         case Hex:               lldb_format = "hex"; break;
4765         case Float:             gdb_type = "float"; lldb_format = "float"; break;
4766         case VectorOfSInt8:     gdb_type = "float"; lldb_format = "vector-sint8"; break;
4767         case VectorOfUInt8:     gdb_type = "float"; lldb_format = "vector-uint8"; break;
4768         case VectorOfSInt16:    gdb_type = "float"; lldb_format = "vector-sint16"; break;
4769         case VectorOfUInt16:    gdb_type = "float"; lldb_format = "vector-uint16"; break;
4770         case VectorOfSInt32:    gdb_type = "float"; lldb_format = "vector-sint32"; break;
4771         case VectorOfUInt32:    gdb_type = "float"; lldb_format = "vector-uint32"; break;
4772         case VectorOfFloat32:   gdb_type = "float"; lldb_format = "vector-float32"; break;
4773         case VectorOfUInt128:   gdb_type = "float"; lldb_format = "vector-uint128"; break;
4774     };
4775     if (reg_set_info && reg.nub_info.set < num_reg_sets)
4776         lldb_set = reg_set_info[reg.nub_info.set].name;
4777 
4778     uint32_t indent = 2;
4779 
4780     XMLElementStart(s, indent, "reg", true);
4781     XMLAttributeString(s, "name", reg.nub_info.name);
4782     XMLAttributeUnsignedDecimal(s, "regnum", reg_num);
4783     XMLAttributeUnsignedDecimal(s, "offset", reg.offset);
4784     XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8);
4785     XMLAttributeString(s, "group", gdb_group);
4786     XMLAttributeString(s, "type", gdb_type, default_gdb_type);
4787     XMLAttributeString (s, "altname", reg.nub_info.alt);
4788     XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding);
4789     XMLAttributeString(s, "format", lldb_format, default_lldb_format);
4790     XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set);
4791     if (reg.nub_info.reg_ehframe != INVALID_NUB_REGNUM)
4792         XMLAttributeUnsignedDecimal(s, "ehframe_regnum", reg.nub_info.reg_ehframe);
4793     if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM)
4794         XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf);
4795 
4796     const char *lldb_generic = NULL;
4797     switch (reg.nub_info.reg_generic)
4798     {
4799         case GENERIC_REGNUM_FP:     lldb_generic = "fp"; break;
4800         case GENERIC_REGNUM_PC:     lldb_generic = "pc"; break;
4801         case GENERIC_REGNUM_SP:     lldb_generic = "sp"; break;
4802         case GENERIC_REGNUM_RA:     lldb_generic = "ra"; break;
4803         case GENERIC_REGNUM_FLAGS:  lldb_generic = "flags"; break;
4804         case GENERIC_REGNUM_ARG1:   lldb_generic = "arg1"; break;
4805         case GENERIC_REGNUM_ARG2:   lldb_generic = "arg2"; break;
4806         case GENERIC_REGNUM_ARG3:   lldb_generic = "arg3"; break;
4807         case GENERIC_REGNUM_ARG4:   lldb_generic = "arg4"; break;
4808         case GENERIC_REGNUM_ARG5:   lldb_generic = "arg5"; break;
4809         case GENERIC_REGNUM_ARG6:   lldb_generic = "arg6"; break;
4810         case GENERIC_REGNUM_ARG7:   lldb_generic = "arg7"; break;
4811         case GENERIC_REGNUM_ARG8:   lldb_generic = "arg8"; break;
4812         default: break;
4813     }
4814     XMLAttributeString(s, "generic", lldb_generic);
4815 
4816 
4817     bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty();
4818     if (!empty)
4819     {
4820         if (!reg.value_regnums.empty())
4821         {
4822             std::ostringstream regnums;
4823             bool first = true;
4824             regnums << DECIMAL;
4825             for (auto regnum : reg.value_regnums)
4826             {
4827                 if (!first)
4828                     regnums << ',';
4829                 regnums << regnum;
4830                 first = false;
4831             }
4832             XMLAttributeString(s, "value_regnums", regnums.str().c_str());
4833         }
4834 
4835         if (!reg.invalidate_regnums.empty())
4836         {
4837             std::ostringstream regnums;
4838             bool first = true;
4839             regnums << DECIMAL;
4840             for (auto regnum : reg.invalidate_regnums)
4841             {
4842                 if (!first)
4843                     regnums << ',';
4844                 regnums << regnum;
4845                 first = false;
4846             }
4847             XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str());
4848         }
4849     }
4850     XMLElementStartEndAttributes(s, true);
4851 }
4852 
4853 void
4854 GenerateTargetXMLRegisters (std::ostringstream &s)
4855 {
4856     nub_size_t num_reg_sets = 0;
4857     const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
4858 
4859 
4860     uint32_t cputype = DNBGetRegisterCPUType();
4861     if (cputype)
4862     {
4863         XMLElementStart(s, 0, "feature", true);
4864         std::ostringstream name_strm;
4865         name_strm << "com.apple.debugserver." << GetArchName (cputype, 0);
4866         XMLAttributeString(s, "name", name_strm.str().c_str());
4867         XMLElementStartEndAttributes(s, false);
4868         for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num)
4869 //        for (const auto &reg: g_dynamic_register_map)
4870         {
4871             GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]);
4872         }
4873         XMLElementEnd(s, 0, "feature");
4874 
4875         if (num_reg_sets > 0)
4876         {
4877             XMLElementStart(s, 0, "groups", false);
4878             for (uint32_t set=1; set<num_reg_sets; ++set)
4879             {
4880                 XMLElementStart(s, 2, "group", true);
4881                 XMLAttributeUnsignedDecimal(s, "id", set);
4882                 XMLAttributeString(s, "name", reg_sets[set].name);
4883                 XMLElementStartEndAttributes(s, true);
4884             }
4885             XMLElementEnd(s, 0, "groups");
4886         }
4887     }
4888 }
4889 
4890 static const char *g_target_xml_header = R"(<?xml version="1.0"?>
4891 <target version="1.0">)";
4892 
4893 static const char *g_target_xml_footer = "</target>";
4894 
4895 static std::string g_target_xml;
4896 
4897 void
4898 UpdateTargetXML ()
4899 {
4900     std::ostringstream s;
4901     s << g_target_xml_header << std::endl;
4902 
4903     // Set the architecture
4904     //s << "<architecture>" << arch "</architecture>" << std::endl;
4905 
4906     // Set the OSABI
4907     //s << "<osabi>abi-name</osabi>"
4908 
4909     GenerateTargetXMLRegisters(s);
4910 
4911     s << g_target_xml_footer << std::endl;
4912 
4913     // Save the XML output in case it gets retrieved in chunks
4914     g_target_xml = s.str();
4915 }
4916 
4917 rnb_err_t
4918 RNBRemote::HandlePacket_qXfer (const char *command)
4919 {
4920     const char *p = command;
4921     p += strlen ("qXfer:");
4922     const char *sep = strchr(p, ':');
4923     if (sep)
4924     {
4925         std::string object(p, sep - p);     // "auxv", "backtrace", "features", etc
4926         p = sep + 1;
4927         sep = strchr(p, ':');
4928         if (sep)
4929         {
4930             std::string rw(p, sep - p);    // "read" or "write"
4931             p = sep + 1;
4932             sep = strchr(p, ':');
4933             if (sep)
4934             {
4935                 std::string annex(p, sep - p);    // "read" or "write"
4936 
4937                 p = sep + 1;
4938                 sep = strchr(p, ',');
4939                 if (sep)
4940                 {
4941                     std::string offset_str(p, sep - p); // read the length as a string
4942                     p = sep + 1;
4943                     std::string length_str(p); // read the offset as a string
4944                     char *end = nullptr;
4945                     const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset
4946                     if (*end == '\0')
4947                     {
4948                         const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length
4949                         if (*end == '\0')
4950                         {
4951                             if (object == "features"  &&
4952                                 rw     == "read"      &&
4953                                 annex  == "target.xml")
4954                             {
4955                                 std::ostringstream xml_out;
4956 
4957                                 if (offset == 0)
4958                                 {
4959                                     InitializeRegisters (true);
4960 
4961                                     UpdateTargetXML();
4962                                     if (g_target_xml.empty())
4963                                         return SendPacket("E83");
4964 
4965                                     if (length > g_target_xml.size())
4966                                     {
4967                                         xml_out << 'l'; // No more data
4968                                         xml_out << binary_encode_string(g_target_xml);
4969                                     }
4970                                     else
4971                                     {
4972                                         xml_out << 'm'; // More data needs to be read with a subsequent call
4973                                         xml_out << binary_encode_string(std::string(g_target_xml, offset, length));
4974                                     }
4975                                 }
4976                                 else
4977                                 {
4978                                     // Retrieving target XML in chunks
4979                                     if (offset < g_target_xml.size())
4980                                     {
4981                                         std::string chunk(g_target_xml, offset, length);
4982                                         if (chunk.size() < length)
4983                                             xml_out << 'l'; // No more data
4984                                         else
4985                                             xml_out << 'm'; // More data needs to be read with a subsequent call
4986                                         xml_out << binary_encode_string(chunk.data());
4987                                     }
4988                                 }
4989                                 return SendPacket(xml_out.str());
4990                             }
4991                             // Well formed, put not supported
4992                             return HandlePacket_UNIMPLEMENTED (command);
4993                         }
4994                     }
4995                 }
4996             }
4997             else
4998             {
4999                 SendPacket ("E85");
5000             }
5001         }
5002         else
5003         {
5004             SendPacket ("E86");
5005         }
5006     }
5007     return SendPacket ("E82");
5008 }
5009 
5010 
5011 rnb_err_t
5012 RNBRemote::HandlePacket_qGDBServerVersion (const char *p)
5013 {
5014     std::ostringstream strm;
5015 
5016 #if defined(DEBUGSERVER_PROGRAM_NAME)
5017     strm << "name:" DEBUGSERVER_PROGRAM_NAME ";";
5018 #else
5019     strm << "name:debugserver;";
5020 #endif
5021     strm << "version:" << DEBUGSERVER_VERSION_NUM << ";";
5022 
5023     return SendPacket (strm.str());
5024 }
5025 
5026 // A helper function that retrieves a single integer value from
5027 // a one-level-deep JSON dictionary of key-value pairs.  e.g.
5028 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}]
5029 //
5030 uint64_t
5031 get_integer_value_for_key_name_from_json (const char *key, const char *json_string)
5032 {
5033     uint64_t retval = INVALID_NUB_ADDRESS;
5034     std::string key_with_quotes = "\"";
5035     key_with_quotes += key;
5036     key_with_quotes += "\"";
5037     const char *c = strstr (json_string, key_with_quotes.c_str());
5038     if (c)
5039     {
5040         c += key_with_quotes.size();
5041 
5042         while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5043             c++;
5044 
5045         if (*c == ':')
5046         {
5047             c++;
5048 
5049             while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
5050                 c++;
5051 
5052             errno = 0;
5053             retval = strtoul (c, NULL, 10);
5054             if (errno != 0)
5055             {
5056                 retval = INVALID_NUB_ADDRESS;
5057             }
5058         }
5059     }
5060     return retval;
5061 
5062 }
5063 
5064 JSONGenerator::ObjectSP
5065 RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only)
5066 {
5067     JSONGenerator::ArraySP threads_array_sp;
5068     if (m_ctx.HasValidProcessID())
5069     {
5070         threads_array_sp.reset(new JSONGenerator::Array());
5071 
5072         nub_process_t pid = m_ctx.ProcessID();
5073 
5074         nub_size_t numthreads = DNBProcessGetNumThreads (pid);
5075         for (nub_size_t i = 0; i < numthreads; ++i)
5076         {
5077             nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i);
5078 
5079             struct DNBThreadStopInfo tid_stop_info;
5080 
5081             const bool stop_info_valid = DNBThreadGetStopReason (pid, tid, &tid_stop_info);
5082 
5083             // If we are doing stop info only, then we only show threads that have a
5084             // valid stop reason
5085             if (threads_with_valid_stop_info_only)
5086             {
5087                 if (!stop_info_valid || tid_stop_info.reason == eStopTypeInvalid)
5088                     continue;
5089             }
5090 
5091             JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary());
5092             thread_dict_sp->AddIntegerItem("tid", tid);
5093 
5094             std::string reason_value("none");
5095 
5096             if (stop_info_valid)
5097             {
5098                 switch (tid_stop_info.reason)
5099                 {
5100                     case eStopTypeInvalid:
5101                         break;
5102 
5103                     case eStopTypeSignal:
5104                         if (tid_stop_info.details.signal.signo != 0)
5105                         {
5106                             thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo);
5107                             reason_value = "signal";
5108                         }
5109                         break;
5110 
5111                     case eStopTypeException:
5112                         if (tid_stop_info.details.exception.type != 0)
5113                         {
5114                             reason_value = "exception";
5115                             thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type);
5116                             JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array());
5117                             for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i)
5118                             {
5119                                 medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i])));
5120                             }
5121                             thread_dict_sp->AddItem("medata", medata_array_sp);
5122                         }
5123                         break;
5124 
5125                     case eStopTypeExec:
5126                         reason_value = "exec";
5127                         break;
5128                 }
5129             }
5130 
5131             thread_dict_sp->AddStringItem("reason", reason_value);
5132 
5133             if (threads_with_valid_stop_info_only == false)
5134             {
5135                 const char *thread_name = DNBThreadGetName (pid, tid);
5136                 if (thread_name && thread_name[0])
5137                     thread_dict_sp->AddStringItem("name", thread_name);
5138 
5139                 thread_identifier_info_data_t thread_ident_info;
5140                 if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
5141                 {
5142                     if (thread_ident_info.dispatch_qaddr != 0)
5143                     {
5144                         thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr);
5145 
5146                         const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets();
5147                         if (dispatch_queue_offsets)
5148                         {
5149                             std::string queue_name;
5150                             uint64_t queue_width = 0;
5151                             uint64_t queue_serialnum = 0;
5152                             nub_addr_t dispatch_queue_t = INVALID_NUB_ADDRESS;
5153                             dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, dispatch_queue_t, queue_name, queue_width, queue_serialnum);
5154                             if (dispatch_queue_t == 0 && queue_name.empty() && queue_serialnum == 0)
5155                             {
5156                                 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", false);
5157                             }
5158                             else
5159                             {
5160                                 thread_dict_sp->AddBooleanItem ("associated_with_dispatch_queue", true);
5161                             }
5162                             if (dispatch_queue_t != INVALID_NUB_ADDRESS && dispatch_queue_t != 0)
5163                                 thread_dict_sp->AddIntegerItem("dispatch_queue_t", dispatch_queue_t);
5164                             if (!queue_name.empty())
5165                                 thread_dict_sp->AddStringItem("qname", queue_name);
5166                             if (queue_width == 1)
5167                                 thread_dict_sp->AddStringItem("qkind", "serial");
5168                             else if (queue_width > 1)
5169                                 thread_dict_sp->AddStringItem("qkind", "concurrent");
5170                             if (queue_serialnum > 0)
5171                                 thread_dict_sp->AddIntegerItem("qserialnum", queue_serialnum);
5172                         }
5173                     }
5174                 }
5175 
5176                 DNBRegisterValue reg_value;
5177 
5178                 if (g_reg_entries != NULL)
5179                 {
5180                     JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary());
5181 
5182                     for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
5183                     {
5184                         // Expedite all registers in the first register set that aren't
5185                         // contained in other registers
5186                         if (g_reg_entries[reg].nub_info.set == 1 &&
5187                             g_reg_entries[reg].nub_info.value_regs == NULL)
5188                         {
5189                             if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
5190                                 continue;
5191 
5192                             std::ostringstream reg_num;
5193                             reg_num << std::dec << g_reg_entries[reg].debugserver_regnum;
5194                             // Encode native byte ordered bytes as hex ascii
5195                             registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size);
5196                         }
5197                     }
5198                     thread_dict_sp->AddItem("registers", registers_dict_sp);
5199                 }
5200 
5201                 // Add expedited stack memory so stack backtracing doesn't need to read anything from the
5202                 // frame pointer chain.
5203                 StackMemoryMap stack_mmap;
5204                 ReadStackMemory (pid, tid, stack_mmap);
5205                 if (!stack_mmap.empty())
5206                 {
5207                     JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array());
5208 
5209                     for (const auto &stack_memory : stack_mmap)
5210                     {
5211                         JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary());
5212                         stack_memory_sp->AddIntegerItem("address", stack_memory.first);
5213                         stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length);
5214                         memory_array_sp->AddItem(stack_memory_sp);
5215                     }
5216                     thread_dict_sp->AddItem("memory", memory_array_sp);
5217                 }
5218             }
5219 
5220             threads_array_sp->AddItem(thread_dict_sp);
5221         }
5222     }
5223     return threads_array_sp;
5224 }
5225 
5226 rnb_err_t
5227 RNBRemote::HandlePacket_jThreadsInfo (const char *p)
5228 {
5229     JSONGenerator::ObjectSP threads_info_sp;
5230     std::ostringstream json;
5231     std::ostringstream reply_strm;
5232     // If we haven't run the process yet, return an error.
5233     if (m_ctx.HasValidProcessID())
5234     {
5235         const bool threads_with_valid_stop_info_only = false;
5236         JSONGenerator::ObjectSP threads_info_sp = GetJSONThreadsInfo(threads_with_valid_stop_info_only);
5237 
5238         if (threads_info_sp)
5239         {
5240             std::ostringstream strm;
5241             threads_info_sp->Dump (strm);
5242             std::string binary_packet = binary_encode_string (strm.str());
5243             if (!binary_packet.empty())
5244                 return SendPacket (binary_packet.c_str());
5245         }
5246     }
5247     return SendPacket ("E85");
5248 
5249 }
5250 
5251 rnb_err_t
5252 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
5253 {
5254     nub_process_t pid;
5255     std::ostringstream json;
5256     // If we haven't run the process yet, return an error.
5257     if (!m_ctx.HasValidProcessID())
5258     {
5259         return SendPacket ("E81");
5260     }
5261 
5262     pid = m_ctx.ProcessID();
5263 
5264     const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" };
5265     if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0)
5266     {
5267         p += strlen (thread_extended_info_str);
5268 
5269         uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p);
5270         uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p);
5271         uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p);
5272         uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p);
5273         uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p);
5274         // Commented out the two variables below as they are not being used
5275 //        uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p);
5276 //        uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p);
5277 
5278         if (tid != INVALID_NUB_ADDRESS)
5279         {
5280             nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid);
5281 
5282             uint64_t tsd_address = INVALID_NUB_ADDRESS;
5283             if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS
5284                 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS
5285                 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS)
5286             {
5287                 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
5288             }
5289 
5290             bool timed_out = false;
5291             Genealogy::ThreadActivitySP thread_activity_sp;
5292 
5293             // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base
5294             // and got an invalid value back, then we have a thread in early startup or shutdown and
5295             // it's possible that gathering the genealogy information for this thread go badly.
5296             // Ideally fetching this info for a thread in these odd states shouldn't matter - but
5297             // we've seen some problems with these new SPI and threads in edge-casey states.
5298 
5299             double genealogy_fetch_time = 0;
5300             if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS)
5301             {
5302                 DNBTimer timer(false);
5303                 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out);
5304                 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0;
5305             }
5306 
5307             std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen
5308 
5309             json << "{";
5310 
5311             bool need_to_print_comma = false;
5312 
5313             if (thread_activity_sp && timed_out == false)
5314             {
5315                 const Genealogy::Activity *activity = &thread_activity_sp->current_activity;
5316                 bool need_vouchers_comma_sep = false;
5317                 json << "\"activity_query_timed_out\":false,";
5318                 if (genealogy_fetch_time != 0)
5319                 {
5320                     //  If we append the floating point value with << we'll get it in scientific
5321                     //  notation.
5322                     char floating_point_ascii_buffer[64];
5323                     floating_point_ascii_buffer[0] = '\0';
5324                     snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time);
5325                     if (strlen (floating_point_ascii_buffer) > 0)
5326                     {
5327                         if (need_to_print_comma)
5328                             json << ",";
5329                         need_to_print_comma = true;
5330                         json << "\"activity_query_duration\":" << floating_point_ascii_buffer;
5331                     }
5332                 }
5333                 if (activity->activity_id != 0)
5334                 {
5335                     if (need_to_print_comma)
5336                         json << ",";
5337                     need_to_print_comma = true;
5338                     need_vouchers_comma_sep = true;
5339                     json << "\"activity\":{";
5340                     json <<    "\"start\":" << activity->activity_start << ",";
5341                     json <<    "\"id\":" << activity->activity_id << ",";
5342                     json <<    "\"parent_id\":" << activity->parent_id << ",";
5343                     json <<    "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\",";
5344                     json <<    "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\"";
5345                     json << "}";
5346                 }
5347                 if (thread_activity_sp->messages.size() > 0)
5348                 {
5349                     need_to_print_comma = true;
5350                     if (need_vouchers_comma_sep)
5351                         json << ",";
5352                     need_vouchers_comma_sep = true;
5353                     json << "\"trace_messages\":[";
5354                     bool printed_one_message = false;
5355                     for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter)
5356                     {
5357                         if (printed_one_message)
5358                             json << ",";
5359                         else
5360                             printed_one_message = true;
5361                         json << "{";
5362                         json <<   "\"timestamp\":" << iter->timestamp << ",";
5363                         json <<   "\"activity_id\":" << iter->activity_id << ",";
5364                         json <<   "\"trace_id\":" << iter->trace_id << ",";
5365                         json <<   "\"thread\":" << iter->thread << ",";
5366                         json <<   "\"type\":" << (int) iter->type << ",";
5367                         json <<   "\"process_info_index\":" << iter->process_info_index << ",";
5368                         process_info_indexes.insert (iter->process_info_index);
5369                         json <<   "\"message\":\"" << json_string_quote_metachars (iter->message) << "\"";
5370                         json << "}";
5371                     }
5372                     json << "]";
5373                 }
5374                 if (thread_activity_sp->breadcrumbs.size() == 1)
5375                 {
5376                     need_to_print_comma = true;
5377                     if (need_vouchers_comma_sep)
5378                         json << ",";
5379                     need_vouchers_comma_sep = true;
5380                     json << "\"breadcrumb\":{";
5381                     for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter)
5382                     {
5383                         json <<   "\"breadcrumb_id\":" << iter->breadcrumb_id << ",";
5384                         json <<   "\"activity_id\":" << iter->activity_id << ",";
5385                         json <<   "\"timestamp\":" << iter->timestamp << ",";
5386                         json <<   "\"name\":\"" << json_string_quote_metachars (iter->name) << "\"";
5387                     }
5388                     json << "}";
5389                 }
5390                 if (process_info_indexes.size() > 0)
5391                 {
5392                     need_to_print_comma = true;
5393                     if (need_vouchers_comma_sep)
5394                         json << ",";
5395                     need_vouchers_comma_sep = true;
5396                     json << "\"process_infos\":[";
5397                     bool printed_one_process_info = false;
5398                     for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter)
5399                     {
5400                         if (printed_one_process_info)
5401                             json << ",";
5402                         else
5403                             printed_one_process_info = true;
5404                         Genealogy::ProcessExecutableInfoSP image_info_sp;
5405                         uint32_t idx = *iter;
5406                         image_info_sp = DNBGetGenealogyImageInfo (pid, idx);
5407                         json << "{";
5408                         char uuid_buf[37];
5409                         uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf);
5410                         json <<   "\"process_info_index\":" << idx << ",";
5411                         json <<  "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\",";
5412                         json <<  "\"image_uuid\":\"" << uuid_buf <<"\"";
5413                         json << "}";
5414                     }
5415                     json << "]";
5416                 }
5417             }
5418             else
5419             {
5420                 if (timed_out)
5421                 {
5422                     if (need_to_print_comma)
5423                         json << ",";
5424                     need_to_print_comma = true;
5425                     json << "\"activity_query_timed_out\":true";
5426                     if (genealogy_fetch_time != 0)
5427                     {
5428                         //  If we append the floating point value with << we'll get it in scientific
5429                         //  notation.
5430                         char floating_point_ascii_buffer[64];
5431                         floating_point_ascii_buffer[0] = '\0';
5432                         snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time);
5433                         if (strlen (floating_point_ascii_buffer) > 0)
5434                         {
5435                             json << ",";
5436                             json << "\"activity_query_duration\":" << floating_point_ascii_buffer;
5437                         }
5438                     }
5439                 }
5440             }
5441 
5442             if (tsd_address != INVALID_NUB_ADDRESS)
5443             {
5444                 if (need_to_print_comma)
5445                     json << ",";
5446                 need_to_print_comma = true;
5447                 json << "\"tsd_address\":" << tsd_address;
5448 
5449                 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX)
5450                 {
5451                     ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index);
5452                     if (requested_qos.IsValid())
5453                     {
5454                         if (need_to_print_comma)
5455                             json << ",";
5456                         need_to_print_comma = true;
5457                         json << "\"requested_qos\":{";
5458                         json <<    "\"enum_value\":" << requested_qos.enum_value << ",";
5459                         json <<    "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\",";
5460                         json <<    "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\"";
5461                         json << "}";
5462                     }
5463                 }
5464             }
5465 
5466             if (pthread_t_value != INVALID_NUB_ADDRESS)
5467             {
5468                 if (need_to_print_comma)
5469                     json << ",";
5470                 need_to_print_comma = true;
5471                 json << "\"pthread_t\":" << pthread_t_value;
5472             }
5473 
5474             nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid);
5475             if (dispatch_queue_t_value != INVALID_NUB_ADDRESS)
5476             {
5477                 if (need_to_print_comma)
5478                     json << ",";
5479                 need_to_print_comma = true;
5480                 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value;
5481             }
5482 
5483             json << "}";
5484             std::string json_quoted = binary_encode_string (json.str());
5485             return SendPacket (json_quoted);
5486         }
5487     }
5488     return SendPacket ("OK");
5489 }
5490 
5491 rnb_err_t
5492 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
5493 {
5494     nub_process_t pid;
5495     // If we haven't run the process yet, return an error.
5496     if (!m_ctx.HasValidProcessID())
5497     {
5498         return SendPacket ("E83");
5499     }
5500 
5501     pid = m_ctx.ProcessID();
5502 
5503     const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" };
5504     if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0)
5505     {
5506         p += strlen (get_loaded_dynamic_libraries_infos_str);
5507 
5508         nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
5509         nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
5510 
5511         if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
5512         {
5513             JSONGenerator::ObjectSP json_sp;
5514 
5515             json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
5516 
5517             if (json_sp.get())
5518             {
5519                 std::ostringstream json_str;
5520                 json_sp->Dump (json_str);
5521                 if (json_str.str().size() > 0)
5522                 {
5523                     std::string json_str_quoted = binary_encode_string (json_str.str());
5524                     return SendPacket (json_str_quoted.c_str());
5525                 }
5526                 else
5527                 {
5528                     SendPacket ("E84");
5529                 }
5530             }
5531         }
5532     }
5533     return SendPacket ("OK");
5534 }
5535 
5536 static bool
5537 MachHeaderIsMainExecutable (nub_process_t pid, uint32_t addr_size, nub_addr_t mach_header_addr, mach_header &mh)
5538 {
5539     DNBLogThreadedIf (LOG_RNB_PROC, "GetMachHeaderForMainExecutable(pid = %u, addr_size = %u, mach_header_addr = 0x%16.16llx)", pid, addr_size, mach_header_addr);
5540     const nub_size_t bytes_read = DNBProcessMemoryRead(pid, mach_header_addr, sizeof(mh), &mh);
5541     if (bytes_read == sizeof(mh))
5542     {
5543         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);
5544         if ((addr_size == 4 && mh.magic == MH_MAGIC) ||
5545             (addr_size == 8 && mh.magic == MH_MAGIC_64))
5546         {
5547             if (mh.filetype == MH_EXECUTE)
5548             {
5549                 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);
5550                 return true;
5551             }
5552         }
5553     }
5554     return false;
5555 }
5556 
5557 static nub_addr_t
5558 GetMachHeaderForMainExecutable (const nub_process_t pid, const uint32_t addr_size, mach_header &mh)
5559 {
5560     struct AllImageInfos
5561     {
5562         uint32_t version;
5563         uint32_t dylib_info_count;
5564         uint64_t dylib_info_addr;
5565     };
5566 
5567     uint64_t mach_header_addr = 0;
5568 
5569     const nub_addr_t shlib_addr = DNBProcessGetSharedLibraryInfoAddress (pid);
5570     uint8_t bytes[256];
5571     nub_size_t bytes_read = 0;
5572     DNBDataRef data (bytes, sizeof(bytes), false);
5573     DNBDataRef::offset_t offset = 0;
5574     data.SetPointerSize(addr_size);
5575 
5576     //----------------------------------------------------------------------
5577     // When we are sitting at __dyld_start, the kernel has placed the
5578     // address of the mach header of the main executable on the stack. If we
5579     // read the SP and dereference a pointer, we might find the mach header
5580     // for the executable. We also just make sure there is only 1 thread
5581     // since if we are at __dyld_start we shouldn't have multiple threads.
5582     //----------------------------------------------------------------------
5583     if (DNBProcessGetNumThreads(pid) == 1)
5584     {
5585         nub_thread_t tid = DNBProcessGetThreadAtIndex(pid, 0);
5586         if (tid != INVALID_NUB_THREAD)
5587         {
5588             DNBRegisterValue sp_value;
5589             if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_SP, &sp_value))
5590             {
5591                 uint64_t sp = addr_size == 8 ? sp_value.value.uint64 : sp_value.value.uint32;
5592                 bytes_read = DNBProcessMemoryRead(pid, sp, addr_size, bytes);
5593                 if (bytes_read == addr_size)
5594                 {
5595                     offset = 0;
5596                     mach_header_addr = data.GetPointer(&offset);
5597                     if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
5598                         return mach_header_addr;
5599                 }
5600             }
5601         }
5602     }
5603 
5604     //----------------------------------------------------------------------
5605     // Check the dyld_all_image_info structure for a list of mach header
5606     // since it is a very easy thing to check
5607     //----------------------------------------------------------------------
5608     if (shlib_addr != INVALID_NUB_ADDRESS)
5609     {
5610         bytes_read = DNBProcessMemoryRead(pid, shlib_addr, sizeof(AllImageInfos), bytes);
5611         if (bytes_read > 0)
5612         {
5613             AllImageInfos aii;
5614             offset = 0;
5615             aii.version = data.Get32(&offset);
5616             aii.dylib_info_count = data.Get32(&offset);
5617             if (aii.dylib_info_count > 0)
5618             {
5619                 aii.dylib_info_addr = data.GetPointer(&offset);
5620                 if (aii.dylib_info_addr != 0)
5621                 {
5622                     const size_t image_info_byte_size = 3 * addr_size;
5623                     for (uint32_t i=0; i<aii.dylib_info_count; ++i)
5624                     {
5625                         bytes_read = DNBProcessMemoryRead(pid, aii.dylib_info_addr + i * image_info_byte_size, image_info_byte_size, bytes);
5626                         if (bytes_read != image_info_byte_size)
5627                             break;
5628                         offset = 0;
5629                         mach_header_addr = data.GetPointer(&offset);
5630                         if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
5631                             return mach_header_addr;
5632                     }
5633                 }
5634             }
5635         }
5636     }
5637 
5638     //----------------------------------------------------------------------
5639     // We failed to find the executable's mach header from the all image
5640     // infos and by dereferencing the stack pointer. Now we fall back to
5641     // enumerating the memory regions and looking for regions that are
5642     // executable.
5643     //----------------------------------------------------------------------
5644     DNBRegionInfo region_info;
5645     mach_header_addr = 0;
5646     while (DNBProcessMemoryRegionInfo(pid, mach_header_addr, &region_info))
5647     {
5648         if (region_info.size == 0)
5649             break;
5650 
5651         if (region_info.permissions & eMemoryPermissionsExecutable)
5652         {
5653             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' : '-');
5654             if (MachHeaderIsMainExecutable(pid, addr_size, mach_header_addr, mh))
5655                 return mach_header_addr;
5656         }
5657         else
5658         {
5659             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' : '-');
5660         }
5661         // Set the address to the next mapped region
5662         mach_header_addr = region_info.addr + region_info.size;
5663     }
5664     bzero (&mh, sizeof(mh));
5665     return INVALID_NUB_ADDRESS;
5666 }
5667 
5668 rnb_err_t
5669 RNBRemote::HandlePacket_qSymbol (const char *command)
5670 {
5671     const char *p = command;
5672     p += strlen ("qSymbol:");
5673     const char *sep = strchr(p, ':');
5674 
5675     std::string symbol_name;
5676     std::string symbol_value_str;
5677     // Extract the symbol value if there is one
5678     if (sep > p)
5679         symbol_value_str.assign(p, sep - p);
5680     p = sep + 1;
5681 
5682     if (*p)
5683     {
5684         // We have a symbol name
5685         symbol_name = decode_hex_ascii_string(p);
5686         if (!symbol_value_str.empty())
5687         {
5688             nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16);
5689             if (symbol_name == "dispatch_queue_offsets")
5690                 m_dispatch_queue_offsets_addr = symbol_value;
5691         }
5692         ++m_qSymbol_index;
5693     }
5694     else
5695     {
5696         // No symbol name, set our symbol index to zero so we can
5697         // read any symbols that we need
5698         m_qSymbol_index = 0;
5699     }
5700 
5701     symbol_name.clear();
5702 
5703     if (m_qSymbol_index == 0)
5704     {
5705         if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS)
5706             symbol_name = "dispatch_queue_offsets";
5707         else
5708             ++m_qSymbol_index;
5709     }
5710 
5711 //    // Lookup next symbol when we have one...
5712 //    if (m_qSymbol_index == 1)
5713 //    {
5714 //    }
5715 
5716 
5717     if (symbol_name.empty())
5718     {
5719         // Done with symbol lookups
5720         return SendPacket ("OK");
5721     }
5722     else
5723     {
5724         std::ostringstream reply;
5725         reply << "qSymbol:";
5726         for (size_t i = 0; i < symbol_name.size(); ++i)
5727             reply << RAWHEX8(symbol_name[i]);
5728         return SendPacket (reply.str().c_str());
5729     }
5730 }
5731 
5732 // Note that all numeric values returned by qProcessInfo are hex encoded,
5733 // including the pid and the cpu type.
5734 
5735 rnb_err_t
5736 RNBRemote::HandlePacket_qProcessInfo (const char *p)
5737 {
5738     nub_process_t pid;
5739     std::ostringstream rep;
5740 
5741     // If we haven't run the process yet, return an error.
5742     if (!m_ctx.HasValidProcessID())
5743         return SendPacket ("E68");
5744 
5745     pid = m_ctx.ProcessID();
5746 
5747     rep << "pid:" << std::hex << pid << ';';
5748 
5749     int procpid_mib[4];
5750     procpid_mib[0] = CTL_KERN;
5751     procpid_mib[1] = KERN_PROC;
5752     procpid_mib[2] = KERN_PROC_PID;
5753     procpid_mib[3] = pid;
5754     struct kinfo_proc proc_kinfo;
5755     size_t proc_kinfo_size = sizeof(struct kinfo_proc);
5756 
5757     if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
5758     {
5759         if (proc_kinfo_size > 0)
5760         {
5761             rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';';
5762             rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ';';
5763             rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ';';
5764             rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ';';
5765             if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
5766                 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';';
5767         }
5768     }
5769 
5770     cpu_type_t cputype = DNBProcessGetCPUType (pid);
5771     if (cputype == 0)
5772     {
5773         DNBLog ("Unable to get the process cpu_type, making a best guess.");
5774         cputype = best_guess_cpu_type();
5775     }
5776 
5777     uint32_t addr_size = 0;
5778     if (cputype != 0)
5779     {
5780         rep << "cputype:" << std::hex << cputype << ";";
5781         if (cputype & CPU_ARCH_ABI64)
5782             addr_size = 8;
5783         else
5784             addr_size = 4;
5785     }
5786 
5787     bool host_cpu_is_64bit = false;
5788     uint32_t is64bit_capable;
5789     size_t is64bit_capable_len = sizeof (is64bit_capable);
5790     if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0)
5791         host_cpu_is_64bit = is64bit_capable != 0;
5792 
5793     uint32_t cpusubtype;
5794     size_t cpusubtype_len = sizeof(cpusubtype);
5795     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
5796     {
5797         // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected
5798         // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the
5799         // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype
5800         // for i386...
5801         if (host_cpu_is_64bit)
5802         {
5803             if (cputype == CPU_TYPE_X86)
5804             {
5805                 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
5806             }
5807             else if (cputype == CPU_TYPE_ARM)
5808             {
5809                 // We can query a process' cputype but we cannot query a process' cpusubtype.
5810                 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we
5811                 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace)
5812                 // with a reasonable CPU_SUBTYPE_ARMV7 subtype.
5813                 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S
5814             }
5815         }
5816         rep << "cpusubtype:" << std::hex << cpusubtype << ';';
5817     }
5818 
5819     bool os_handled = false;
5820     if (addr_size > 0)
5821     {
5822         rep << "ptrsize:" << std::dec << addr_size << ';';
5823 
5824 #if (defined (__x86_64__) || defined (__i386__))
5825         // Try and get the OS type by looking at the load commands in the main
5826         // executable and looking for a LC_VERSION_MIN load command. This is the
5827         // most reliable way to determine the "ostype" value when on desktop.
5828 
5829         mach_header mh;
5830         nub_addr_t exe_mach_header_addr = GetMachHeaderForMainExecutable (pid, addr_size, mh);
5831         if (exe_mach_header_addr != INVALID_NUB_ADDRESS)
5832         {
5833             uint64_t load_command_addr = exe_mach_header_addr + ((addr_size == 8) ? sizeof(mach_header_64) : sizeof(mach_header));
5834             load_command lc;
5835             for (uint32_t i=0; i<mh.ncmds && !os_handled; ++i)
5836             {
5837                 const nub_size_t bytes_read = DNBProcessMemoryRead (pid, load_command_addr, sizeof(lc), &lc);
5838                 uint32_t raw_cmd = lc.cmd & ~LC_REQ_DYLD;
5839                 if (bytes_read != sizeof(lc))
5840                     break;
5841                 switch (raw_cmd)
5842                 {
5843                 case LC_VERSION_MIN_IPHONEOS:
5844                     os_handled = true;
5845                     rep << "ostype:ios;";
5846                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_IPHONEOS -> 'ostype:ios;'");
5847                     break;
5848 
5849                 case LC_VERSION_MIN_MACOSX:
5850                     os_handled = true;
5851                     rep << "ostype:macosx;";
5852                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'");
5853                     break;
5854 
5855 #if defined (LC_VERSION_MIN_TVOS)
5856                 case LC_VERSION_MIN_TVOS:
5857                     os_handled = true;
5858                     rep << "ostype:tvos;";
5859                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_TVOS -> 'ostype:tvos;'");
5860                     break;
5861 #endif
5862 
5863 #if defined (LC_VERSION_MIN_WATCHOS)
5864                 case LC_VERSION_MIN_WATCHOS:
5865                     os_handled = true;
5866                     rep << "ostype:watchos;";
5867                     DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_WATCHOS -> 'ostype:watchos;'");
5868                     break;
5869 #endif
5870 
5871                 default:
5872                     break;
5873                 }
5874                 load_command_addr = load_command_addr + lc.cmdsize;
5875             }
5876         }
5877 #endif
5878     }
5879 
5880     // If we weren't able to find the OS in a LC_VERSION_MIN load command, try
5881     // to set it correctly by using the cpu type and other tricks
5882     if (!os_handled)
5883     {
5884         // The OS in the triple should be "ios" or "macosx" which doesn't match our
5885         // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
5886         // this for now.
5887         if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
5888         {
5889 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
5890             rep << "ostype:tvos;";
5891 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
5892             rep << "ostype:watchos;";
5893 #else
5894             rep << "ostype:ios;";
5895 #endif
5896         }
5897         else
5898         {
5899             bool is_ios_simulator = false;
5900             if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64)
5901             {
5902                 // Check for iOS simulator binaries by getting the process argument
5903                 // and environment and checking for SIMULATOR_UDID in the environment
5904                 int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid };
5905 
5906                 uint8_t arg_data[8192];
5907                 size_t arg_data_size = sizeof(arg_data);
5908                 if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
5909                 {
5910                     DNBDataRef data (arg_data, arg_data_size, false);
5911                     DNBDataRef::offset_t offset = 0;
5912                     uint32_t argc = data.Get32 (&offset);
5913                     const char *cstr;
5914 
5915                     cstr = data.GetCStr (&offset);
5916                     if (cstr)
5917                     {
5918                         // Skip NULLs
5919                         while (1)
5920                         {
5921                             const char *p = data.PeekCStr(offset);
5922                             if ((p == NULL) || (*p != '\0'))
5923                                 break;
5924                             ++offset;
5925                         }
5926                         // Now skip all arguments
5927                         for (uint32_t i = 0; i < argc; ++i)
5928                         {
5929                             data.GetCStr(&offset);
5930                         }
5931 
5932                         // Now iterate across all environment variables
5933                         while ((cstr = data.GetCStr(&offset)))
5934                         {
5935                             if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0)
5936                             {
5937                                 is_ios_simulator = true;
5938                                 break;
5939                             }
5940                             if (cstr[0] == '\0')
5941                                 break;
5942 
5943                         }
5944                     }
5945                 }
5946             }
5947             if (is_ios_simulator)
5948             {
5949 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
5950                 rep << "ostype:tvos;";
5951 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
5952                 rep << "ostype:watchos;";
5953 #else
5954                 rep << "ostype:ios;";
5955 #endif
5956             }
5957             else
5958             {
5959                 rep << "ostype:macosx;";
5960             }
5961         }
5962     }
5963 
5964     rep << "vendor:apple;";
5965 
5966 #if defined (__LITTLE_ENDIAN__)
5967     rep << "endian:little;";
5968 #elif defined (__BIG_ENDIAN__)
5969     rep << "endian:big;";
5970 #elif defined (__PDP_ENDIAN__)
5971     rep << "endian:pdp;";
5972 #endif
5973 
5974     if (addr_size == 0)
5975     {
5976 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
5977         nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
5978         kern_return_t kr;
5979         x86_thread_state_t gp_regs;
5980         mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
5981         kr = thread_get_state (static_cast<thread_act_t>(thread),
5982                                x86_THREAD_STATE,
5983                                (thread_state_t) &gp_regs,
5984                                &gp_count);
5985         if (kr == KERN_SUCCESS)
5986         {
5987             if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
5988                 rep << "ptrsize:8;";
5989             else
5990                 rep << "ptrsize:4;";
5991         }
5992 #elif defined (__arm__)
5993         rep << "ptrsize:4;";
5994 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE)
5995         nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
5996         kern_return_t kr;
5997         arm_unified_thread_state_t gp_regs;
5998         mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT;
5999         kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE,
6000                                (thread_state_t) &gp_regs, &gp_count);
6001         if (kr == KERN_SUCCESS)
6002         {
6003             if (gp_regs.ash.flavor == ARM_THREAD_STATE64)
6004                 rep << "ptrsize:8;";
6005             else
6006                 rep << "ptrsize:4;";
6007         }
6008 #endif
6009     }
6010 
6011     return SendPacket (rep.str());
6012 }
6013 
6014 const RNBRemote::DispatchQueueOffsets *
6015 RNBRemote::GetDispatchQueueOffsets()
6016 {
6017     if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID())
6018     {
6019         nub_process_t pid = m_ctx.ProcessID();
6020         nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets);
6021         if (bytes_read != sizeof(m_dispatch_queue_offsets))
6022             m_dispatch_queue_offsets.Clear();
6023     }
6024 
6025     if (m_dispatch_queue_offsets.IsValid())
6026         return &m_dispatch_queue_offsets;
6027     else
6028         return nullptr;
6029 }
6030 
6031 void
6032 RNBRemote::EnableCompressionNextSendPacket (compression_types type)
6033 {
6034     m_compression_mode = type;
6035     m_enable_compression_next_send_packet = true;
6036 }
6037 
6038 compression_types
6039 RNBRemote::GetCompressionType ()
6040 {
6041     // The first packet we send back to the debugger after a QEnableCompression request
6042     // should be uncompressed -- so we can indicate whether the compression was enabled
6043     // or not via OK / Enn returns.  After that, all packets sent will be using the
6044     // compression protocol.
6045 
6046     if (m_enable_compression_next_send_packet)
6047     {
6048         // One time, we send back "None" as our compression type
6049         m_enable_compression_next_send_packet = false;
6050         return compression_types::none;
6051     }
6052     return m_compression_mode;
6053 }
6054