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