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