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