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     return result;
2308 }
2309 
2310 
2311 rnb_err_t
2312 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
2313 {
2314     /* The number of characters in a packet payload that gdb is
2315      prepared to accept.  The packet-start char, packet-end char,
2316      2 checksum chars and terminating null character are not included
2317      in this size.  */
2318     p += sizeof ("QSetMaxPayloadSize:") - 1;
2319     errno = 0;
2320     uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16));
2321     if (errno != 0 && size == 0)
2322     {
2323         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
2324     }
2325     m_max_payload_size = size;
2326     return SendPacket ("OK");
2327 }
2328 
2329 rnb_err_t
2330 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
2331 {
2332     /* This tells us the largest packet that gdb can handle.
2333      i.e. the size of gdb's packet-reading buffer.
2334      QSetMaxPayloadSize is preferred because it is less ambiguous.  */
2335     p += sizeof ("QSetMaxPacketSize:") - 1;
2336     errno = 0;
2337     uint32_t size = static_cast<uint32_t>(strtoul (p, NULL, 16));
2338     if (errno != 0 && size == 0)
2339     {
2340         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
2341     }
2342     m_max_payload_size = size - 5;
2343     return SendPacket ("OK");
2344 }
2345 
2346 
2347 
2348 
2349 rnb_err_t
2350 RNBRemote::HandlePacket_QEnvironment (const char *p)
2351 {
2352     /* This sets the environment for the target program.  The packet is of the form:
2353 
2354      QEnvironment:VARIABLE=VALUE
2355 
2356      */
2357 
2358     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
2359                       (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2360 
2361     p += sizeof ("QEnvironment:") - 1;
2362     RNBContext& ctx = Context();
2363 
2364     ctx.PushEnvironment (p);
2365     return SendPacket ("OK");
2366 }
2367 
2368 rnb_err_t
2369 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p)
2370 {
2371     /* This sets the environment for the target program.  The packet is of the form:
2372 
2373         QEnvironmentHexEncoded:VARIABLE=VALUE
2374 
2375         The VARIABLE=VALUE part is sent hex-encoded so characters like '#' with special
2376         meaning in the remote protocol won't break it.
2377     */
2378 
2379     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"",
2380         (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2381 
2382     p += sizeof ("QEnvironmentHexEncoded:") - 1;
2383 
2384     std::string arg;
2385     const char *c;
2386     c = p;
2387     while (*c != '\0')
2388       {
2389         if (*(c + 1) == '\0')
2390         {
2391             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2392         }
2393         char smallbuf[3];
2394         smallbuf[0] = *c;
2395         smallbuf[1] = *(c + 1);
2396         smallbuf[2] = '\0';
2397         errno = 0;
2398         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
2399         if (errno != 0 && ch == 0)
2400           {
2401             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2402           }
2403         arg.push_back(ch);
2404         c += 2;
2405       }
2406 
2407     RNBContext& ctx = Context();
2408     if (arg.length() > 0)
2409       ctx.PushEnvironment (arg.c_str());
2410 
2411     return SendPacket ("OK");
2412 }
2413 
2414 
2415 rnb_err_t
2416 RNBRemote::HandlePacket_QLaunchArch (const char *p)
2417 {
2418     p += sizeof ("QLaunchArch:") - 1;
2419     if (DNBSetArchitecture(p))
2420         return SendPacket ("OK");
2421     return SendPacket ("E63");
2422 }
2423 
2424 rnb_err_t
2425 RNBRemote::HandlePacket_QSetProcessEvent (const char *p)
2426 {
2427     p += sizeof ("QSetProcessEvent:") - 1;
2428     // If the process is running, then send the event to the process, otherwise
2429     // store it in the context.
2430     if (Context().HasValidProcessID())
2431     {
2432         if (DNBProcessSendEvent (Context().ProcessID(), p))
2433             return SendPacket("OK");
2434         else
2435             return SendPacket ("E80");
2436     }
2437     else
2438     {
2439         Context().PushProcessEvent(p);
2440     }
2441     return SendPacket ("OK");
2442 }
2443 
2444 void
2445 append_hex_value (std::ostream& ostrm, const void *buf, size_t buf_size, bool swap)
2446 {
2447     int i;
2448     const uint8_t *p = (const uint8_t *)buf;
2449     if (swap)
2450     {
2451         for (i = static_cast<int>(buf_size)-1; i >= 0; i--)
2452             ostrm << RAWHEX8(p[i]);
2453     }
2454     else
2455     {
2456         for (i = 0; i < buf_size; i++)
2457             ostrm << RAWHEX8(p[i]);
2458     }
2459 }
2460 
2461 void
2462 append_hexified_string (std::ostream& ostrm, const std::string &string)
2463 {
2464     size_t string_size = string.size();
2465     const char *string_buf = string.c_str();
2466     for (size_t i = 0; i < string_size; i++)
2467     {
2468             ostrm << RAWHEX8(*(string_buf + i));
2469     }
2470 }
2471 
2472 
2473 
2474 void
2475 register_value_in_hex_fixed_width (std::ostream& ostrm,
2476                                    nub_process_t pid,
2477                                    nub_thread_t tid,
2478                                    const register_map_entry_t* reg,
2479                                    const DNBRegisterValue *reg_value_ptr)
2480 {
2481     if (reg != NULL)
2482     {
2483         DNBRegisterValue reg_value;
2484         if (reg_value_ptr == NULL)
2485         {
2486             if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &reg_value))
2487                 reg_value_ptr = &reg_value;
2488         }
2489 
2490         if (reg_value_ptr)
2491         {
2492             append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false);
2493         }
2494         else
2495         {
2496             // If we fail to read a register value, check if it has a default
2497             // fail value. If it does, return this instead in case some of
2498             // the registers are not available on the current system.
2499             if (reg->nub_info.size > 0)
2500             {
2501                 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0');
2502                 append_hex_value (ostrm, zeros.data(), zeros.size(), false);
2503             }
2504         }
2505     }
2506 }
2507 
2508 
2509 void
2510 gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
2511                                                 nub_process_t pid,
2512                                                 nub_thread_t tid,
2513                                                 const register_map_entry_t* reg,
2514                                                 const DNBRegisterValue *reg_value_ptr)
2515 {
2516     // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
2517     // gdb register number, and VVVVVVVV is the correct number of hex bytes
2518     // as ASCII for the register value.
2519     if (reg != NULL)
2520     {
2521         ostrm << RAWHEX8(reg->gdb_regnum) << ':';
2522         register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr);
2523         ostrm << ';';
2524     }
2525 }
2526 
2527 
2528 void
2529 RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid,
2530                                                      nub_addr_t dispatch_qaddr,
2531                                                      std::string &queue_name,
2532                                                      uint64_t &queue_width,
2533                                                      uint64_t &queue_serialnum) const
2534 {
2535     queue_name.clear();
2536     queue_width = 0;
2537     queue_serialnum = 0;
2538 
2539     if (IsValid() && dispatch_qaddr != INVALID_NUB_ADDRESS && dispatch_qaddr != 0)
2540     {
2541         nub_addr_t dispatch_queue_addr = DNBProcessMemoryReadPointer (pid, dispatch_qaddr);
2542         if (dispatch_queue_addr)
2543         {
2544             queue_width = DNBProcessMemoryReadInteger (pid, dispatch_queue_addr + dqo_width, dqo_width_size, 0);
2545             queue_serialnum = DNBProcessMemoryReadInteger (pid, dispatch_queue_addr + dqo_serialnum, dqo_serialnum_size, 0);
2546 
2547             if (dqo_version >= 4)
2548             {
2549                 // libdispatch versions 4+, pointer to dispatch name is in the
2550                 // queue structure.
2551                 nub_addr_t pointer_to_label_address = dispatch_queue_addr + dqo_label;
2552                 nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address);
2553                 if (label_addr)
2554                     queue_name = std::move(DNBProcessMemoryReadCString (pid, label_addr));
2555             }
2556             else
2557             {
2558                 // libdispatch versions 1-3, dispatch name is a fixed width char array
2559                 // in the queue structure.
2560                 queue_name = std::move(DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_addr + dqo_label, dqo_label_size));
2561             }
2562         }
2563     }
2564 }
2565 
2566 struct StackMemory
2567 {
2568     uint8_t bytes[2*sizeof(nub_addr_t)];
2569     nub_size_t length;
2570 };
2571 typedef std::map<nub_addr_t, StackMemory> StackMemoryMap;
2572 
2573 
2574 static void
2575 ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap)
2576 {
2577     DNBRegisterValue reg_value;
2578     if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, &reg_value))
2579     {
2580         uint32_t frame_count = 0;
2581         uint64_t fp = 0;
2582         if (reg_value.info.size == 4)
2583             fp = reg_value.value.uint32;
2584         else
2585             fp = reg_value.value.uint64;
2586         while (fp != 0)
2587         {
2588             // Make sure we never recurse more than 256 times so we don't recurse too far or
2589             // store up too much memory in the expedited cache
2590             if (++frame_count > 256)
2591                 break;
2592 
2593             const nub_size_t read_size = reg_value.info.size*2;
2594             StackMemory stack_memory;
2595             stack_memory.length = read_size;
2596             if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size)
2597                 break;
2598             // Make sure we don't try to put the same stack memory in more than once
2599             if (stack_mmap.find(fp) != stack_mmap.end())
2600                 break;
2601             // Put the entry into the cache
2602             stack_mmap[fp] = stack_memory;
2603             // Dereference the frame pointer to get to the previous frame pointer
2604             if (reg_value.info.size == 4)
2605                 fp = ((uint32_t *)stack_memory.bytes)[0];
2606             else
2607                 fp = ((uint64_t *)stack_memory.bytes)[0];
2608         }
2609     }
2610 }
2611 
2612 rnb_err_t
2613 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
2614 {
2615     const nub_process_t pid = m_ctx.ProcessID();
2616     if (pid == INVALID_NUB_PROCESS)
2617         return SendPacket("E50");
2618 
2619     struct DNBThreadStopInfo tid_stop_info;
2620 
2621     /* Fill the remaining space in this packet with as many registers
2622      as we can stuff in there.  */
2623 
2624     if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
2625     {
2626         const bool did_exec = tid_stop_info.reason == eStopTypeExec;
2627         if (did_exec)
2628         {
2629             RNBRemote::InitializeRegisters(true);
2630 
2631             // Reset any symbols that need resetting when we exec
2632             m_dispatch_queue_offsets_addr = INVALID_NUB_ADDRESS;
2633             m_dispatch_queue_offsets.Clear();
2634         }
2635 
2636         std::ostringstream ostrm;
2637         // Output the T packet with the thread
2638         ostrm << 'T';
2639         int signum = tid_stop_info.details.signal.signo;
2640         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);
2641 
2642         // Translate any mach exceptions to gdb versions, unless they are
2643         // common exceptions like a breakpoint or a soft signal.
2644         switch (tid_stop_info.details.exception.type)
2645         {
2646             default:                    signum = 0; break;
2647             case EXC_BREAKPOINT:        signum = SIGTRAP; break;
2648             case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2649             case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2650             case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2651             case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2652             case EXC_SOFTWARE:
2653                 if (tid_stop_info.details.exception.data_count == 2 &&
2654                     tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2655                     signum = static_cast<int>(tid_stop_info.details.exception.data[1]);
2656                 else
2657                     signum = TARGET_EXC_SOFTWARE;
2658                 break;
2659         }
2660 
2661         ostrm << RAWHEX8(signum & 0xff);
2662 
2663         ostrm << std::hex << "thread:" << tid << ';';
2664 
2665         const char *thread_name = DNBThreadGetName (pid, tid);
2666         if (thread_name && thread_name[0])
2667         {
2668             size_t thread_name_len = strlen(thread_name);
2669 
2670 
2671             if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2672                 ostrm << std::hex << "name:" << thread_name << ';';
2673             else
2674             {
2675                 // the thread name contains special chars, send as hex bytes
2676                 ostrm << std::hex << "hexname:";
2677                 uint8_t *u_thread_name = (uint8_t *)thread_name;
2678                 for (int i = 0; i < thread_name_len; i++)
2679                     ostrm << RAWHEX8(u_thread_name[i]);
2680                 ostrm << ';';
2681             }
2682         }
2683 
2684         thread_identifier_info_data_t thread_ident_info;
2685         if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
2686         {
2687             if (thread_ident_info.dispatch_qaddr != 0)
2688             {
2689                 ostrm << "qaddr:" << std::hex << thread_ident_info.dispatch_qaddr << ';';
2690                 const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets();
2691                 if (dispatch_queue_offsets)
2692                 {
2693                     std::string queue_name;
2694                     uint64_t queue_width = 0;
2695                     uint64_t queue_serialnum = 0;
2696                     dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum);
2697                     if (!queue_name.empty())
2698                     {
2699                         ostrm << "qname:";
2700                         append_hex_value(ostrm, queue_name.data(), queue_name.size(), false);
2701                         ostrm << ';';
2702                     }
2703                     if (queue_width == 1)
2704                         ostrm << "qkind:serial;";
2705                     else if (queue_width > 1)
2706                         ostrm << "qkind:concurrent;";
2707 
2708                     if (queue_serialnum > 0)
2709                         ostrm << "qserial:" << DECIMAL << queue_serialnum << ';';
2710                 }
2711             }
2712         }
2713 
2714         // If a 'QListThreadsInStopReply' was sent to enable this feature, we
2715         // will send all thread IDs back in the "threads" key whose value is
2716         // a list of hex thread IDs separated by commas:
2717         //  "threads:10a,10b,10c;"
2718         // This will save the debugger from having to send a pair of qfThreadInfo
2719         // and qsThreadInfo packets, but it also might take a lot of room in the
2720         // stop reply packet, so it must be enabled only on systems where there
2721         // are no limits on packet lengths.
2722 
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 
2740         if (g_num_reg_entries == 0)
2741             InitializeRegisters ();
2742 
2743         if (g_reg_entries != NULL)
2744         {
2745             DNBRegisterValue reg_value;
2746             for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2747             {
2748                 // Expedite all registers in the first register set that aren't
2749                 // contained in other registers
2750                 if (g_reg_entries[reg].nub_info.set == 1 &&
2751                     g_reg_entries[reg].nub_info.value_regs == NULL)
2752                 {
2753                     if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
2754                         continue;
2755 
2756                     gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], &reg_value);
2757                 }
2758             }
2759         }
2760 
2761         if (did_exec)
2762         {
2763             ostrm << "reason:exec;";
2764         }
2765         else if (tid_stop_info.details.exception.type)
2766         {
2767             ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';';
2768             ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';';
2769             for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
2770                 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';';
2771         }
2772 
2773         // Add expedited stack memory so stack backtracing doesn't need to read anything from the
2774         // frame pointer chain.
2775         StackMemoryMap stack_mmap;
2776         ReadStackMemory (pid, tid, stack_mmap);
2777         if (!stack_mmap.empty())
2778         {
2779             for (const auto &stack_memory : stack_mmap)
2780             {
2781                 ostrm << "memory:" << HEXBASE << stack_memory.first << '=';
2782                 append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false);
2783                 ostrm << ';';
2784             }
2785         }
2786 
2787         return SendPacket (ostrm.str ());
2788     }
2789     return SendPacket("E51");
2790 }
2791 
2792 /* '?'
2793  The stop reply packet - tell gdb what the status of the inferior is.
2794  Often called the questionmark_packet.  */
2795 
2796 rnb_err_t
2797 RNBRemote::HandlePacket_last_signal (const char *unused)
2798 {
2799     if (!m_ctx.HasValidProcessID())
2800     {
2801         // Inferior is not yet specified/running
2802         return SendPacket ("E02");
2803     }
2804 
2805     nub_process_t pid = m_ctx.ProcessID();
2806     nub_state_t pid_state = DNBProcessGetState (pid);
2807 
2808     switch (pid_state)
2809     {
2810         case eStateAttaching:
2811         case eStateLaunching:
2812         case eStateRunning:
2813         case eStateStepping:
2814         case eStateDetached:
2815             return rnb_success;  // Ignore
2816 
2817         case eStateSuspended:
2818         case eStateStopped:
2819         case eStateCrashed:
2820             {
2821                 nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2822                 // Make sure we set the current thread so g and p packets return
2823                 // the data the gdb will expect.
2824                 SetCurrentThread (tid);
2825 
2826                 SendStopReplyPacketForThread (tid);
2827             }
2828             break;
2829 
2830         case eStateInvalid:
2831         case eStateUnloaded:
2832         case eStateExited:
2833             {
2834                 char pid_exited_packet[16] = "";
2835                 int pid_status = 0;
2836                 // Process exited with exit status
2837                 if (!DNBProcessGetExitStatus(pid, &pid_status))
2838                     pid_status = 0;
2839 
2840                 if (pid_status)
2841                 {
2842                     if (WIFEXITED (pid_status))
2843                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2844                     else if (WIFSIGNALED (pid_status))
2845                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2846                     else if (WIFSTOPPED (pid_status))
2847                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2848                 }
2849 
2850                 // If we have an empty exit packet, lets fill one in to be safe.
2851                 if (!pid_exited_packet[0])
2852                 {
2853                     strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2854                     pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2855                 }
2856 
2857                 const char *exit_info = DNBProcessGetExitInfo (pid);
2858                 if (exit_info != NULL && *exit_info != '\0')
2859                 {
2860                     std::ostringstream exit_packet;
2861                     exit_packet << pid_exited_packet;
2862                     exit_packet << ';';
2863                     exit_packet << RAW_HEXBASE << "description";
2864                     exit_packet << ':';
2865                     for (size_t i = 0; exit_info[i] != '\0'; i++)
2866                         exit_packet << RAWHEX8(exit_info[i]);
2867                     exit_packet << ';';
2868                     return SendPacket (exit_packet.str());
2869                 }
2870                 else
2871                     return SendPacket (pid_exited_packet);
2872             }
2873             break;
2874     }
2875     return rnb_success;
2876 }
2877 
2878 rnb_err_t
2879 RNBRemote::HandlePacket_M (const char *p)
2880 {
2881     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2882     {
2883         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2884     }
2885 
2886     char *c;
2887     p++;
2888     errno = 0;
2889     nub_addr_t addr = strtoull (p, &c, 16);
2890     if (errno != 0 && addr == 0)
2891     {
2892         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2893     }
2894     if (*c != ',')
2895     {
2896         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2897     }
2898 
2899     /* Advance 'p' to the length part of the packet.  */
2900     p += (c - p) + 1;
2901 
2902     errno = 0;
2903     unsigned long length = strtoul (p, &c, 16);
2904     if (errno != 0 && length == 0)
2905     {
2906         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2907     }
2908     if (length == 0)
2909     {
2910         return SendPacket ("OK");
2911     }
2912 
2913     if (*c != ':')
2914     {
2915         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2916     }
2917     /* Advance 'p' to the data part of the packet.  */
2918     p += (c - p) + 1;
2919 
2920     size_t datalen = strlen (p);
2921     if (datalen & 0x1)
2922     {
2923         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2924     }
2925     if (datalen == 0)
2926     {
2927         return SendPacket ("OK");
2928     }
2929 
2930     uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2931     uint8_t *i = buf;
2932 
2933     while (*p != '\0' && *(p + 1) != '\0')
2934     {
2935         char hexbuf[3];
2936         hexbuf[0] = *p;
2937         hexbuf[1] = *(p + 1);
2938         hexbuf[2] = '\0';
2939         errno = 0;
2940         uint8_t byte = strtoul (hexbuf, NULL, 16);
2941         if (errno != 0 && byte == 0)
2942         {
2943             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2944         }
2945         *i++ = byte;
2946         p += 2;
2947     }
2948 
2949     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2950     if (wrote != length)
2951         return SendPacket ("E09");
2952     else
2953         return SendPacket ("OK");
2954 }
2955 
2956 
2957 rnb_err_t
2958 RNBRemote::HandlePacket_m (const char *p)
2959 {
2960     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2961     {
2962         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
2963     }
2964 
2965     char *c;
2966     p++;
2967     errno = 0;
2968     nub_addr_t addr = strtoull (p, &c, 16);
2969     if (errno != 0 && addr == 0)
2970     {
2971         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
2972     }
2973     if (*c != ',')
2974     {
2975         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
2976     }
2977 
2978     /* Advance 'p' to the length part of the packet.  */
2979     p += (c - p) + 1;
2980 
2981     errno = 0;
2982     auto length = strtoul (p, NULL, 16);
2983     if (errno != 0 && length == 0)
2984     {
2985         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2986     }
2987     if (length == 0)
2988     {
2989         return SendPacket ("");
2990     }
2991 
2992     std::string buf(length, '\0');
2993     if (buf.empty())
2994     {
2995         return SendPacket ("E78");
2996     }
2997     nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
2998     if (bytes_read == 0)
2999     {
3000         return SendPacket ("E08");
3001     }
3002 
3003     // "The reply may contain fewer bytes than requested if the server was able
3004     //  to read only part of the region of memory."
3005     length = bytes_read;
3006 
3007     std::ostringstream ostrm;
3008     for (int i = 0; i < length; i++)
3009         ostrm << RAWHEX8(buf[i]);
3010     return SendPacket (ostrm.str ());
3011 }
3012 
3013 // Read memory, sent it up as binary data.
3014 // Usage:  xADDR,LEN
3015 // ADDR and LEN are both base 16.
3016 
3017 // Responds with 'OK' for zero-length request
3018 // or
3019 //
3020 // DATA
3021 //
3022 // where DATA is the binary data payload.
3023 
3024 rnb_err_t
3025 RNBRemote::HandlePacket_x (const char *p)
3026 {
3027     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3028     {
3029         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
3030     }
3031 
3032     char *c;
3033     p++;
3034     errno = 0;
3035     nub_addr_t addr = strtoull (p, &c, 16);
3036     if (errno != 0)
3037     {
3038         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
3039     }
3040     if (*c != ',')
3041     {
3042         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
3043     }
3044 
3045     /* Advance 'p' to the number of bytes to be read.  */
3046     p += (c - p) + 1;
3047 
3048     errno = 0;
3049     auto length = strtoul (p, NULL, 16);
3050     if (errno != 0)
3051     {
3052         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in x packet");
3053     }
3054 
3055     // zero length read means this is a test of whether that packet is implemented or not.
3056     if (length == 0)
3057     {
3058         return SendPacket ("OK");
3059     }
3060 
3061     std::vector<uint8_t> buf (length);
3062 
3063     if (buf.capacity() != length)
3064     {
3065         return SendPacket ("E79");
3066     }
3067     nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
3068     if (bytes_read == 0)
3069     {
3070         return SendPacket ("E80");
3071     }
3072 
3073     std::vector<uint8_t> buf_quoted;
3074     buf_quoted.reserve (bytes_read + 30);
3075     for (int i = 0; i < bytes_read; i++)
3076     {
3077         if (buf[i] == '#' || buf[i] == '$' || buf[i] == '}' || buf[i] == '*')
3078         {
3079             buf_quoted.push_back(0x7d);
3080             buf_quoted.push_back(buf[i] ^ 0x20);
3081         }
3082         else
3083         {
3084             buf_quoted.push_back(buf[i]);
3085         }
3086     }
3087     length = buf_quoted.size();
3088 
3089     std::ostringstream ostrm;
3090     for (int i = 0; i < length; i++)
3091         ostrm << buf_quoted[i];
3092 
3093     return SendPacket (ostrm.str ());
3094 }
3095 
3096 rnb_err_t
3097 RNBRemote::HandlePacket_X (const char *p)
3098 {
3099     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
3100     {
3101         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
3102     }
3103 
3104     char *c;
3105     p++;
3106     errno = 0;
3107     nub_addr_t addr = strtoull (p, &c, 16);
3108     if (errno != 0 && addr == 0)
3109     {
3110         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
3111     }
3112     if (*c != ',')
3113     {
3114         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
3115     }
3116 
3117     /* Advance 'p' to the length part of the packet.  NB this is the length of the packet
3118        including any escaped chars.  The data payload may be a little bit smaller after
3119        decoding.  */
3120     p += (c - p) + 1;
3121 
3122     errno = 0;
3123     auto length = strtoul (p, NULL, 16);
3124     if (errno != 0 && length == 0)
3125     {
3126         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in X packet");
3127     }
3128 
3129     // I think gdb sends a zero length write request to test whether this
3130     // packet is accepted.
3131     if (length == 0)
3132     {
3133         return SendPacket ("OK");
3134     }
3135 
3136     std::vector<uint8_t> data = decode_binary_data (c, -1);
3137     std::vector<uint8_t>::const_iterator it;
3138     uint8_t *buf = (uint8_t *) alloca (data.size ());
3139     uint8_t *i = buf;
3140     for (it = data.begin (); it != data.end (); ++it)
3141     {
3142         *i++ = *it;
3143     }
3144 
3145     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
3146     if (wrote != data.size ())
3147         return SendPacket ("E08");
3148     return SendPacket ("OK");
3149 }
3150 
3151 /* 'g' -- read registers
3152  Get the contents of the registers for the current thread,
3153  send them to gdb.
3154  Should the setting of the Hg packet determine which thread's registers
3155  are returned?  */
3156 
3157 rnb_err_t
3158 RNBRemote::HandlePacket_g (const char *p)
3159 {
3160     std::ostringstream ostrm;
3161     if (!m_ctx.HasValidProcessID())
3162     {
3163         return SendPacket ("E11");
3164     }
3165 
3166     if (g_num_reg_entries == 0)
3167         InitializeRegisters ();
3168 
3169     nub_process_t pid = m_ctx.ProcessID ();
3170     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
3171     if (tid == INVALID_NUB_THREAD)
3172         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3173 
3174     // Get the register context size first by calling with NULL buffer
3175     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
3176     if (reg_ctx_size)
3177     {
3178         // Now allocate enough space for the entire register context
3179         std::vector<uint8_t> reg_ctx;
3180         reg_ctx.resize(reg_ctx_size);
3181         // Now read the register context
3182         reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
3183         if (reg_ctx_size)
3184         {
3185             append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
3186             return SendPacket (ostrm.str ());
3187         }
3188     }
3189     return SendPacket ("E74");
3190 }
3191 
3192 /* 'G XXX...' -- write registers
3193  How is the thread for these specified, beyond "the current thread"?
3194  Does gdb actually use the Hg packet to set this?  */
3195 
3196 rnb_err_t
3197 RNBRemote::HandlePacket_G (const char *p)
3198 {
3199     if (!m_ctx.HasValidProcessID())
3200     {
3201         return SendPacket ("E11");
3202     }
3203 
3204     if (g_num_reg_entries == 0)
3205         InitializeRegisters ();
3206 
3207     StringExtractor packet(p);
3208     packet.SetFilePos(1); // Skip the 'G'
3209 
3210     nub_process_t pid = m_ctx.ProcessID();
3211     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3212     if (tid == INVALID_NUB_THREAD)
3213         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3214 
3215     // Get the register context size first by calling with NULL buffer
3216     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
3217     if (reg_ctx_size)
3218     {
3219         // Now allocate enough space for the entire register context
3220         std::vector<uint8_t> reg_ctx;
3221         reg_ctx.resize(reg_ctx_size);
3222 
3223         const nub_size_t bytes_extracted = packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc);
3224         if (bytes_extracted == reg_ctx.size())
3225         {
3226             // Now write the register context
3227             reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
3228             if (reg_ctx_size == reg_ctx.size())
3229                 return SendPacket ("OK");
3230             else
3231                 return SendPacket ("E55");
3232         }
3233         else
3234         {
3235             DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size);
3236             return SendPacket ("E64");
3237         }
3238     }
3239     return SendPacket ("E65");
3240 }
3241 
3242 static bool
3243 RNBRemoteShouldCancelCallback (void *not_used)
3244 {
3245     RNBRemoteSP remoteSP(g_remoteSP);
3246     if (remoteSP.get() != NULL)
3247     {
3248         RNBRemote* remote = remoteSP.get();
3249         if (remote->Comm().IsConnected())
3250             return false;
3251         else
3252             return true;
3253     }
3254     return true;
3255 }
3256 
3257 
3258 // FORMAT: _MXXXXXX,PPP
3259 //      XXXXXX: big endian hex chars
3260 //      PPP: permissions can be any combo of r w x chars
3261 //
3262 // RESPONSE: XXXXXX
3263 //      XXXXXX: hex address of the newly allocated memory
3264 //      EXX: error code
3265 //
3266 // EXAMPLES:
3267 //      _M123000,rw
3268 //      _M123000,rwx
3269 //      _M123000,xw
3270 
3271 rnb_err_t
3272 RNBRemote::HandlePacket_AllocateMemory (const char *p)
3273 {
3274     StringExtractor packet (p);
3275     packet.SetFilePos(2); // Skip the "_M"
3276 
3277     nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
3278     if (size != 0)
3279     {
3280         if (packet.GetChar() == ',')
3281         {
3282             uint32_t permissions = 0;
3283             char ch;
3284             bool success = true;
3285             while (success && (ch = packet.GetChar()) != '\0')
3286             {
3287                 switch (ch)
3288                 {
3289                 case 'r':   permissions |= eMemoryPermissionsReadable; break;
3290                 case 'w':   permissions |= eMemoryPermissionsWritable; break;
3291                 case 'x':   permissions |= eMemoryPermissionsExecutable; break;
3292                 default:    success = false; break;
3293                 }
3294             }
3295 
3296             if (success)
3297             {
3298                 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
3299                 if (addr != INVALID_NUB_ADDRESS)
3300                 {
3301                     std::ostringstream ostrm;
3302                     ostrm << RAW_HEXBASE << addr;
3303                     return SendPacket (ostrm.str ());
3304                 }
3305             }
3306         }
3307     }
3308     return SendPacket ("E53");
3309 }
3310 
3311 // FORMAT: _mXXXXXX
3312 //      XXXXXX: address that was previously allocated
3313 //
3314 // RESPONSE: XXXXXX
3315 //      OK: address was deallocated
3316 //      EXX: error code
3317 //
3318 // EXAMPLES:
3319 //      _m123000
3320 
3321 rnb_err_t
3322 RNBRemote::HandlePacket_DeallocateMemory (const char *p)
3323 {
3324     StringExtractor packet (p);
3325     packet.SetFilePos(2); // Skip the "_m"
3326     nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
3327 
3328     if (addr != INVALID_NUB_ADDRESS)
3329     {
3330         if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
3331             return SendPacket ("OK");
3332     }
3333     return SendPacket ("E54");
3334 }
3335 
3336 
3337 // FORMAT: QSaveRegisterState;thread:TTTT;  (when thread suffix is supported)
3338 // FORMAT: QSaveRegisterState               (when thread suffix is NOT supported)
3339 //      TTTT: thread ID in hex
3340 //
3341 // RESPONSE:
3342 //      SAVEID: Where SAVEID is a decimal number that represents the save ID
3343 //              that can be passed back into a "QRestoreRegisterState" packet
3344 //      EXX: error code
3345 //
3346 // EXAMPLES:
3347 //      QSaveRegisterState;thread:1E34;     (when thread suffix is supported)
3348 //      QSaveRegisterState                  (when thread suffix is NOT supported)
3349 
3350 rnb_err_t
3351 RNBRemote::HandlePacket_SaveRegisterState (const char *p)
3352 {
3353     nub_process_t pid = m_ctx.ProcessID ();
3354     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3355     if (tid == INVALID_NUB_THREAD)
3356     {
3357         if (m_thread_suffix_supported)
3358             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
3359         else
3360             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
3361     }
3362 
3363     // Get the register context size first by calling with NULL buffer
3364     const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid);
3365     if (save_id != 0)
3366     {
3367         char response[64];
3368         snprintf (response, sizeof(response), "%u", save_id);
3369         return SendPacket (response);
3370     }
3371     else
3372     {
3373         return SendPacket ("E75");
3374     }
3375 }
3376 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT;  (when thread suffix is supported)
3377 // FORMAT: QRestoreRegisterState:SAVEID               (when thread suffix is NOT supported)
3378 //      TTTT: thread ID in hex
3379 //      SAVEID: a decimal number that represents the save ID that was
3380 //              returned from a call to "QSaveRegisterState"
3381 //
3382 // RESPONSE:
3383 //      OK: successfully restored registers for the specified thread
3384 //      EXX: error code
3385 //
3386 // EXAMPLES:
3387 //      QRestoreRegisterState:1;thread:1E34;     (when thread suffix is supported)
3388 //      QRestoreRegisterState:1                  (when thread suffix is NOT supported)
3389 
3390 rnb_err_t
3391 RNBRemote::HandlePacket_RestoreRegisterState (const char *p)
3392 {
3393     nub_process_t pid = m_ctx.ProcessID ();
3394     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3395     if (tid == INVALID_NUB_THREAD)
3396     {
3397         if (m_thread_suffix_supported)
3398             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
3399         else
3400             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
3401     }
3402 
3403     StringExtractor packet (p);
3404     packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:"
3405     const uint32_t save_id = packet.GetU32(0);
3406 
3407     if (save_id != 0)
3408     {
3409         // Get the register context size first by calling with NULL buffer
3410         if (DNBThreadRestoreRegisterState(pid, tid, save_id))
3411             return SendPacket ("OK");
3412         else
3413             return SendPacket ("E77");
3414     }
3415     return SendPacket ("E76");
3416 }
3417 
3418 static bool
3419 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name)
3420 {
3421     bool return_val = true;
3422     while (*p != '\0')
3423     {
3424         char smallbuf[3];
3425         smallbuf[0] = *p;
3426         smallbuf[1] = *(p + 1);
3427         smallbuf[2] = '\0';
3428 
3429         errno = 0;
3430         int ch = static_cast<int>(strtoul (smallbuf, NULL, 16));
3431         if (errno != 0 && ch == 0)
3432         {
3433             return_val = false;
3434             break;
3435         }
3436 
3437         attach_name.push_back(ch);
3438         p += 2;
3439     }
3440     return return_val;
3441 }
3442 
3443 rnb_err_t
3444 RNBRemote::HandlePacket_qSupported (const char *p)
3445 {
3446     uint32_t max_packet_size = 128 * 1024;  // 128KBytes is a reasonable max packet size--debugger can always use less
3447     char buf[256];
3448     snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", max_packet_size);
3449 
3450     // By default, don't enable compression.  It's only worth doing when we are working
3451     // with a low speed communication channel.
3452     bool enable_compression = false;
3453 
3454     // Enable compression when debugserver is running on a watchOS device where communication may be over Bluetooth.
3455 #if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
3456     enable_compression = true;
3457 #endif
3458 
3459 #if defined (HAVE_LIBCOMPRESSION)
3460     // libcompression is weak linked so test if compression_decode_buffer() is available
3461     if (enable_compression && compression_decode_buffer != NULL)
3462     {
3463         strcat (buf, ";SupportedCompressions=lzfse,zlib-deflate,lz4,lzma;DefaultCompressionMinSize=");
3464         char numbuf[16];
3465         snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize);
3466         numbuf[sizeof (numbuf) - 1] = '\0';
3467         strcat (buf, numbuf);
3468     }
3469 #elif defined (HAVE_LIBZ)
3470     if (enable_compression)
3471     {
3472         strcat (buf, ";SupportedCompressions=zlib-deflate;DefaultCompressionMinSize=");
3473         char numbuf[16];
3474         snprintf (numbuf, sizeof (numbuf), "%zu", m_compression_minsize);
3475         numbuf[sizeof (numbuf) - 1] = '\0';
3476         strcat (buf, numbuf);
3477     }
3478 #endif
3479 
3480     return SendPacket (buf);
3481 }
3482 
3483 /*
3484  vAttach;pid
3485 
3486  Attach to a new process with the specified process ID. pid is a hexadecimal integer
3487  identifying the process. If the stub is currently controlling a process, it is
3488  killed. The attached process is stopped.This packet is only available in extended
3489  mode (see extended mode).
3490 
3491  Reply:
3492  "ENN"                      for an error
3493  "Any Stop Reply Packet"     for success
3494  */
3495 
3496 rnb_err_t
3497 RNBRemote::HandlePacket_v (const char *p)
3498 {
3499     if (strcmp (p, "vCont;c") == 0)
3500     {
3501         // Simple continue
3502         return RNBRemote::HandlePacket_c("c");
3503     }
3504     else if (strcmp (p, "vCont;s") == 0)
3505     {
3506         // Simple step
3507         return RNBRemote::HandlePacket_s("s");
3508     }
3509     else if (strstr (p, "vCont") == p)
3510     {
3511         typedef struct
3512         {
3513             nub_thread_t tid;
3514             char action;
3515             int signal;
3516         } vcont_action_t;
3517 
3518         DNBThreadResumeActions thread_actions;
3519         char *c = (char *)(p += strlen("vCont"));
3520         char *c_end = c + strlen(c);
3521         if (*c == '?')
3522             return SendPacket ("vCont;c;C;s;S");
3523 
3524         while (c < c_end && *c == ';')
3525         {
3526             ++c;    // Skip the semi-colon
3527             DNBThreadResumeAction thread_action;
3528             thread_action.tid = INVALID_NUB_THREAD;
3529             thread_action.state = eStateInvalid;
3530             thread_action.signal = 0;
3531             thread_action.addr = INVALID_NUB_ADDRESS;
3532 
3533             char action = *c++;
3534 
3535             switch (action)
3536             {
3537                 case 'C':
3538                     errno = 0;
3539                     thread_action.signal = static_cast<int>(strtoul (c, &c, 16));
3540                     if (errno != 0)
3541                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
3542                     // Fall through to next case...
3543 
3544                 case 'c':
3545                     // Continue
3546                     thread_action.state = eStateRunning;
3547                     break;
3548 
3549                 case 'S':
3550                     errno = 0;
3551                     thread_action.signal = static_cast<int>(strtoul (c, &c, 16));
3552                     if (errno != 0)
3553                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
3554                     // Fall through to next case...
3555 
3556                 case 's':
3557                     // Step
3558                     thread_action.state = eStateStepping;
3559                     break;
3560 
3561                 default:
3562                     HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
3563                     break;
3564             }
3565             if (*c == ':')
3566             {
3567                 errno = 0;
3568                 thread_action.tid = strtoul (++c, &c, 16);
3569                 if (errno != 0)
3570                     return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
3571             }
3572 
3573             thread_actions.Append (thread_action);
3574         }
3575 
3576         // If a default action for all other threads wasn't mentioned
3577         // then we should stop the threads
3578         thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3579         DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
3580         return rnb_success;
3581     }
3582     else if (strstr (p, "vAttach") == p)
3583     {
3584         nub_process_t attach_pid = INVALID_NUB_PROCESS;
3585         char err_str[1024]={'\0'};
3586 
3587         if (strstr (p, "vAttachWait;") == p)
3588         {
3589             p += strlen("vAttachWait;");
3590             std::string attach_name;
3591             if (!GetProcessNameFrom_vAttach(p, attach_name))
3592             {
3593                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
3594             }
3595             const bool ignore_existing = true;
3596             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
3597 
3598         }
3599         else if (strstr (p, "vAttachOrWait;") == p)
3600         {
3601             p += strlen("vAttachOrWait;");
3602             std::string attach_name;
3603             if (!GetProcessNameFrom_vAttach(p, attach_name))
3604             {
3605                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt");
3606             }
3607             const bool ignore_existing = false;
3608             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
3609         }
3610         else if (strstr (p, "vAttachName;") == p)
3611         {
3612             p += strlen("vAttachName;");
3613             std::string attach_name;
3614             if (!GetProcessNameFrom_vAttach(p, attach_name))
3615             {
3616                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
3617             }
3618 
3619             attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
3620 
3621         }
3622         else if (strstr (p, "vAttach;") == p)
3623         {
3624             p += strlen("vAttach;");
3625             char *end = NULL;
3626             attach_pid = static_cast<int>(strtoul (p, &end, 16));    // PID will be in hex, so use base 16 to decode
3627             if (p != end && *end == '\0')
3628             {
3629                 // Wait at most 30 second for attach
3630                 struct timespec attach_timeout_abstime;
3631                 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
3632                 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
3633             }
3634         }
3635         else
3636         {
3637             return HandlePacket_UNIMPLEMENTED(p);
3638         }
3639 
3640 
3641         if (attach_pid != INVALID_NUB_PROCESS)
3642         {
3643             if (m_ctx.ProcessID() != attach_pid)
3644                 m_ctx.SetProcessID(attach_pid);
3645             // Send a stop reply packet to indicate we successfully attached!
3646             NotifyThatProcessStopped ();
3647             return rnb_success;
3648         }
3649         else
3650         {
3651             m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
3652             if (err_str[0])
3653                 m_ctx.LaunchStatus().SetErrorString(err_str);
3654             else
3655                 m_ctx.LaunchStatus().SetErrorString("attach failed");
3656             SendPacket ("E01");  // E01 is our magic error value for attach failed.
3657             DNBLogError ("Attach failed: \"%s\".", err_str);
3658             return rnb_err;
3659         }
3660     }
3661 
3662     // All other failures come through here
3663     return HandlePacket_UNIMPLEMENTED(p);
3664 }
3665 
3666 /* 'T XX' -- status of thread
3667  Check if the specified thread is alive.
3668  The thread number is in hex?  */
3669 
3670 rnb_err_t
3671 RNBRemote::HandlePacket_T (const char *p)
3672 {
3673     p++;
3674     if (p == NULL || *p == '\0')
3675     {
3676         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
3677     }
3678     if (!m_ctx.HasValidProcessID())
3679     {
3680         return SendPacket ("E15");
3681     }
3682     errno = 0;
3683     nub_thread_t tid = strtoul (p, NULL, 16);
3684     if (errno != 0 && tid == 0)
3685     {
3686         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
3687     }
3688 
3689     nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
3690     if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
3691     {
3692         return SendPacket ("E16");
3693     }
3694 
3695     return SendPacket ("OK");
3696 }
3697 
3698 
3699 rnb_err_t
3700 RNBRemote::HandlePacket_z (const char *p)
3701 {
3702     if (p == NULL || *p == '\0')
3703         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
3704 
3705     if (!m_ctx.HasValidProcessID())
3706         return SendPacket ("E15");
3707 
3708     char packet_cmd = *p++;
3709     char break_type = *p++;
3710 
3711     if (*p++ != ',')
3712         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
3713 
3714     char *c = NULL;
3715     nub_process_t pid = m_ctx.ProcessID();
3716     errno = 0;
3717     nub_addr_t addr = strtoull (p, &c, 16);
3718     if (errno != 0 && addr == 0)
3719         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
3720     p = c;
3721     if (*p++ != ',')
3722         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
3723 
3724     errno = 0;
3725     auto byte_size = strtoul (p, &c, 16);
3726     if (errno != 0 && byte_size == 0)
3727         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
3728 
3729     if (packet_cmd == 'Z')
3730     {
3731         // set
3732         switch (break_type)
3733         {
3734             case '0':   // set software breakpoint
3735             case '1':   // set hardware breakpoint
3736                 {
3737                     // gdb can send multiple Z packets for the same address and
3738                     // these calls must be ref counted.
3739                     bool hardware = (break_type == '1');
3740 
3741                     if (DNBBreakpointSet (pid, addr, byte_size, hardware))
3742                     {
3743                         // We successfully created a breakpoint, now lets full out
3744                         // a ref count structure with the breakID and add it to our
3745                         // map.
3746                         return SendPacket ("OK");
3747                     }
3748                     else
3749                     {
3750                         // We failed to set the software breakpoint
3751                         return SendPacket ("E09");
3752                     }
3753                 }
3754                 break;
3755 
3756             case '2':   // set write watchpoint
3757             case '3':   // set read watchpoint
3758             case '4':   // set access watchpoint
3759                 {
3760                     bool hardware = true;
3761                     uint32_t watch_flags = 0;
3762                     if (break_type == '2')
3763                         watch_flags = WATCH_TYPE_WRITE;
3764                     else if (break_type == '3')
3765                         watch_flags = WATCH_TYPE_READ;
3766                     else
3767                         watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
3768 
3769                     if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware))
3770                     {
3771                         return SendPacket ("OK");
3772                     }
3773                     else
3774                     {
3775                         // We failed to set the watchpoint
3776                         return SendPacket ("E09");
3777                     }
3778                 }
3779                 break;
3780 
3781             default:
3782                 break;
3783         }
3784     }
3785     else if (packet_cmd == 'z')
3786     {
3787         // remove
3788         switch (break_type)
3789         {
3790             case '0':   // remove software breakpoint
3791             case '1':   // remove hardware breakpoint
3792                 if (DNBBreakpointClear (pid, addr))
3793                 {
3794                     return SendPacket ("OK");
3795                 }
3796                 else
3797                 {
3798                     return SendPacket ("E08");
3799                 }
3800                 break;
3801 
3802             case '2':   // remove write watchpoint
3803             case '3':   // remove read watchpoint
3804             case '4':   // remove access watchpoint
3805                 if (DNBWatchpointClear (pid, addr))
3806                 {
3807                     return SendPacket ("OK");
3808                 }
3809                 else
3810                 {
3811                     return SendPacket ("E08");
3812                 }
3813                 break;
3814 
3815             default:
3816                 break;
3817         }
3818     }
3819     return HandlePacket_UNIMPLEMENTED(p);
3820 }
3821 
3822 // Extract the thread number from the thread suffix that might be appended to
3823 // thread specific packets. This will only be enabled if m_thread_suffix_supported
3824 // is true.
3825 nub_thread_t
3826 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
3827 {
3828     if (m_thread_suffix_supported)
3829     {
3830         nub_thread_t tid = INVALID_NUB_THREAD;
3831         if (p)
3832         {
3833             const char *tid_cstr = strstr (p, "thread:");
3834             if (tid_cstr)
3835             {
3836                 tid_cstr += strlen ("thread:");
3837                 tid = strtoul(tid_cstr, NULL, 16);
3838             }
3839         }
3840         return tid;
3841     }
3842     return GetCurrentThread();
3843 
3844 }
3845 
3846 /* 'p XX'
3847  print the contents of register X */
3848 
3849 rnb_err_t
3850 RNBRemote::HandlePacket_p (const char *p)
3851 {
3852     if (g_num_reg_entries == 0)
3853         InitializeRegisters ();
3854 
3855     if (p == NULL || *p == '\0')
3856     {
3857         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3858     }
3859     if (!m_ctx.HasValidProcessID())
3860     {
3861         return SendPacket ("E15");
3862     }
3863     nub_process_t pid = m_ctx.ProcessID();
3864     errno = 0;
3865     char *tid_cstr = NULL;
3866     uint32_t reg = static_cast<uint32_t>(strtoul (p + 1, &tid_cstr, 16));
3867     if (errno != 0 && reg == 0)
3868     {
3869         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
3870     }
3871 
3872     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
3873     if (tid == INVALID_NUB_THREAD)
3874         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3875 
3876     const register_map_entry_t *reg_entry;
3877 
3878     if (reg < g_num_reg_entries)
3879         reg_entry = &g_reg_entries[reg];
3880     else
3881         reg_entry = NULL;
3882 
3883     std::ostringstream ostrm;
3884     if (reg_entry == NULL)
3885     {
3886         DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
3887         ostrm << "00000000";
3888     }
3889     else if (reg_entry->nub_info.reg == -1)
3890     {
3891         if (reg_entry->nub_info.size > 0)
3892         {
3893             std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0');
3894             append_hex_value(ostrm, zeros.data(), zeros.size(), false);
3895         }
3896     }
3897     else
3898     {
3899         register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL);
3900     }
3901     return SendPacket (ostrm.str());
3902 }
3903 
3904 /* 'Pnn=rrrrr'
3905  Set register number n to value r.
3906  n and r are hex strings.  */
3907 
3908 rnb_err_t
3909 RNBRemote::HandlePacket_P (const char *p)
3910 {
3911     if (g_num_reg_entries == 0)
3912         InitializeRegisters ();
3913 
3914     if (p == NULL || *p == '\0')
3915     {
3916         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
3917     }
3918     if (!m_ctx.HasValidProcessID())
3919     {
3920         return SendPacket ("E28");
3921     }
3922 
3923     nub_process_t pid = m_ctx.ProcessID();
3924 
3925     StringExtractor packet (p);
3926 
3927     const char cmd_char = packet.GetChar();
3928     // Register ID is always in big endian
3929     const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
3930     const char equal_char = packet.GetChar();
3931 
3932     if (cmd_char != 'P')
3933         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
3934 
3935     if (reg == UINT32_MAX)
3936         return SendPacket ("E29");
3937 
3938     if (equal_char != '=')
3939         return SendPacket ("E30");
3940 
3941     const register_map_entry_t *reg_entry;
3942 
3943     if (reg >= g_num_reg_entries)
3944         return SendPacket("E47");
3945 
3946     reg_entry = &g_reg_entries[reg];
3947 
3948     if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3949     {
3950         DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3951         return SendPacket("E48");
3952     }
3953 
3954     DNBRegisterValue reg_value;
3955     reg_value.info = reg_entry->nub_info;
3956     packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc);
3957 
3958     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3959     if (tid == INVALID_NUB_THREAD)
3960         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3961 
3962     if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3963     {
3964         return SendPacket ("E32");
3965     }
3966     return SendPacket ("OK");
3967 }
3968 
3969 /* 'c [addr]'
3970  Continue, optionally from a specified address. */
3971 
3972 rnb_err_t
3973 RNBRemote::HandlePacket_c (const char *p)
3974 {
3975     const nub_process_t pid = m_ctx.ProcessID();
3976 
3977     if (pid == INVALID_NUB_PROCESS)
3978         return SendPacket ("E23");
3979 
3980     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3981 
3982     if (*(p + 1) != '\0')
3983     {
3984         action.tid = GetContinueThread();
3985         errno = 0;
3986         action.addr = strtoull (p + 1, NULL, 16);
3987         if (errno != 0 && action.addr == 0)
3988             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
3989     }
3990 
3991     DNBThreadResumeActions thread_actions;
3992     thread_actions.Append(action);
3993     thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3994     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3995         return SendPacket ("E25");
3996     // Don't send an "OK" packet; response is the stopped/exited message.
3997     return rnb_success;
3998 }
3999 
4000 rnb_err_t
4001 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
4002 {
4003     /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code)
4004        for the memory region containing a given address and return that information.
4005 
4006        Users of this packet must be prepared for three results:
4007 
4008            Region information is returned
4009            Region information is unavailable for this address because the address is in unmapped memory
4010            Region lookup cannot be performed on this platform or process is not yet launched
4011            This packet isn't implemented
4012 
4013        Examples of use:
4014           qMemoryRegionInfo:3a55140
4015           start:3a50000,size:100000,permissions:rwx
4016 
4017           qMemoryRegionInfo:0
4018           error:address in unmapped region
4019 
4020           qMemoryRegionInfo:3a551140   (on a different platform)
4021           error:region lookup cannot be performed
4022 
4023           qMemoryRegionInfo
4024           OK                   // this packet is implemented by the remote nub
4025     */
4026 
4027     p += sizeof ("qMemoryRegionInfo") - 1;
4028     if (*p == '\0')
4029        return SendPacket ("OK");
4030     if (*p++ != ':')
4031        return SendPacket ("E67");
4032     if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
4033        p += 2;
4034 
4035     errno = 0;
4036     uint64_t address = strtoul (p, NULL, 16);
4037     if (errno != 0 && address == 0)
4038     {
4039         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
4040     }
4041 
4042     DNBRegionInfo region_info = { 0, 0, 0 };
4043     DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, &region_info);
4044     std::ostringstream ostrm;
4045 
4046         // start:3a50000,size:100000,permissions:rwx
4047     ostrm << "start:" << std::hex << region_info.addr << ';';
4048 
4049     if (region_info.size > 0)
4050         ostrm << "size:"  << std::hex << region_info.size << ';';
4051 
4052     if (region_info.permissions)
4053     {
4054         ostrm << "permissions:";
4055 
4056         if (region_info.permissions & eMemoryPermissionsReadable)
4057             ostrm << 'r';
4058         if (region_info.permissions & eMemoryPermissionsWritable)
4059             ostrm << 'w';
4060         if (region_info.permissions & eMemoryPermissionsExecutable)
4061             ostrm << 'x';
4062         ostrm << ';';
4063     }
4064     return SendPacket (ostrm.str());
4065 }
4066 
4067 // qGetProfileData;scan_type:0xYYYYYYY
4068 rnb_err_t
4069 RNBRemote::HandlePacket_GetProfileData (const char *p)
4070 {
4071     nub_process_t pid = m_ctx.ProcessID();
4072     if (pid == INVALID_NUB_PROCESS)
4073         return SendPacket ("OK");
4074 
4075     StringExtractor packet(p += sizeof ("qGetProfileData"));
4076     DNBProfileDataScanType scan_type = eProfileAll;
4077     std::string name;
4078     std::string value;
4079     while (packet.GetNameColonValue(name, value))
4080     {
4081         if (name.compare ("scan_type") == 0)
4082         {
4083             std::istringstream iss(value);
4084             uint32_t int_value = 0;
4085             if (iss >> std::hex >> int_value)
4086             {
4087                 scan_type = (DNBProfileDataScanType)int_value;
4088             }
4089         }
4090     }
4091 
4092     std::string data = DNBProcessGetProfileData(pid, scan_type);
4093     if (!data.empty())
4094     {
4095         return SendPacket (data.c_str());
4096     }
4097     else
4098     {
4099         return SendPacket ("OK");
4100     }
4101 }
4102 
4103 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY
4104 rnb_err_t
4105 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
4106 {
4107     nub_process_t pid = m_ctx.ProcessID();
4108     if (pid == INVALID_NUB_PROCESS)
4109         return SendPacket ("OK");
4110 
4111     StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));
4112     bool enable = false;
4113     uint64_t interval_usec = 0;
4114     DNBProfileDataScanType scan_type = eProfileAll;
4115     std::string name;
4116     std::string value;
4117     while (packet.GetNameColonValue(name, value))
4118     {
4119         if (name.compare ("enable") == 0)
4120         {
4121             enable  = strtoul(value.c_str(), NULL, 10) > 0;
4122         }
4123         else if (name.compare ("interval_usec") == 0)
4124         {
4125             interval_usec  = strtoul(value.c_str(), NULL, 10);
4126         }
4127         else if (name.compare ("scan_type") == 0)
4128         {
4129             std::istringstream iss(value);
4130             uint32_t int_value = 0;
4131             if (iss >> std::hex >> int_value)
4132             {
4133                 scan_type = (DNBProfileDataScanType)int_value;
4134             }
4135         }
4136     }
4137 
4138     if (interval_usec == 0)
4139     {
4140         enable = 0;
4141     }
4142 
4143     DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type);
4144     return SendPacket ("OK");
4145 }
4146 
4147 // QEnableCompression:type:<COMPRESSION-TYPE>;minsize:<MINIMUM PACKET SIZE TO COMPRESS>;
4148 //
4149 // type: must be a type previously reported by the qXfer:features: SupportedCompressions list
4150 //
4151 // minsize: is optional; by default the qXfer:features: DefaultCompressionMinSize value is used
4152 // debugserver may have a better idea of what a good minimum packet size to compress is than lldb.
4153 
4154 rnb_err_t
4155 RNBRemote::HandlePacket_QEnableCompression (const char *p)
4156 {
4157     p += sizeof ("QEnableCompression:") - 1;
4158 
4159     size_t new_compression_minsize = m_compression_minsize;
4160     const char *new_compression_minsize_str = strstr (p, "minsize:");
4161     if (new_compression_minsize_str)
4162     {
4163         new_compression_minsize_str += strlen ("minsize:");
4164         errno = 0;
4165         new_compression_minsize = strtoul (new_compression_minsize_str, NULL, 10);
4166         if (errno != 0 || new_compression_minsize == ULONG_MAX)
4167         {
4168             new_compression_minsize = m_compression_minsize;
4169         }
4170     }
4171 
4172 #if defined (HAVE_LIBCOMPRESSION)
4173     if (compression_decode_buffer != NULL)
4174     {
4175         if (strstr (p, "type:zlib-deflate;") != nullptr)
4176         {
4177             EnableCompressionNextSendPacket (compression_types::zlib_deflate);
4178             m_compression_minsize = new_compression_minsize;
4179             return SendPacket ("OK");
4180         }
4181         else if (strstr (p, "type:lz4;") != nullptr)
4182         {
4183             EnableCompressionNextSendPacket (compression_types::lz4);
4184             m_compression_minsize = new_compression_minsize;
4185             return SendPacket ("OK");
4186         }
4187         else if (strstr (p, "type:lzma;") != nullptr)
4188         {
4189             EnableCompressionNextSendPacket (compression_types::lzma);
4190             m_compression_minsize = new_compression_minsize;
4191             return SendPacket ("OK");
4192         }
4193         else if (strstr (p, "type:lzfse;") != nullptr)
4194         {
4195             EnableCompressionNextSendPacket (compression_types::lzfse);
4196             m_compression_minsize = new_compression_minsize;
4197             return SendPacket ("OK");
4198         }
4199     }
4200 #endif
4201 
4202 #if defined (HAVE_LIBZ)
4203     if (strstr (p, "type:zlib-deflate;") != nullptr)
4204     {
4205         EnableCompressionNextSendPacket (compression_types::zlib_deflate);
4206         m_compression_minsize = new_compression_minsize;
4207         return SendPacket ("OK");
4208     }
4209 #endif
4210 
4211     return SendPacket ("E88");
4212 }
4213 
4214 rnb_err_t
4215 RNBRemote::HandlePacket_qSpeedTest (const char *p)
4216 {
4217     p += strlen ("qSpeedTest:response_size:");
4218     char *end = NULL;
4219     errno = 0;
4220     uint64_t response_size = ::strtoul (p, &end, 16);
4221     if (errno != 0)
4222         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Didn't find response_size value at right offset");
4223     else if (*end == ';')
4224     {
4225         static char g_data[4*1024*1024+16] = "data:";
4226         memset(g_data + 5, 'a', response_size);
4227         g_data[response_size + 5] = '\0';
4228         return SendPacket (g_data);
4229     }
4230     else
4231     {
4232         return SendPacket ("E79");
4233     }
4234 }
4235 
4236 rnb_err_t
4237 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p)
4238 {
4239     /* This packet simply returns the number of supported hardware watchpoints.
4240 
4241        Examples of use:
4242           qWatchpointSupportInfo:
4243           num:4
4244 
4245           qWatchpointSupportInfo
4246           OK                   // this packet is implemented by the remote nub
4247     */
4248 
4249     p += sizeof ("qWatchpointSupportInfo") - 1;
4250     if (*p == '\0')
4251        return SendPacket ("OK");
4252     if (*p++ != ':')
4253        return SendPacket ("E67");
4254 
4255     errno = 0;
4256     uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID());
4257     std::ostringstream ostrm;
4258 
4259     // size:4
4260     ostrm << "num:" << std::dec << num << ';';
4261     return SendPacket (ostrm.str());
4262 }
4263 
4264 /* 'C sig [;addr]'
4265  Resume with signal sig, optionally at address addr.  */
4266 
4267 rnb_err_t
4268 RNBRemote::HandlePacket_C (const char *p)
4269 {
4270     const nub_process_t pid = m_ctx.ProcessID();
4271 
4272     if (pid == INVALID_NUB_PROCESS)
4273         return SendPacket ("E36");
4274 
4275     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
4276     int process_signo = -1;
4277     if (*(p + 1) != '\0')
4278     {
4279         action.tid = GetContinueThread();
4280         char *end = NULL;
4281         errno = 0;
4282         process_signo = static_cast<int>(strtoul (p + 1, &end, 16));
4283         if (errno != 0)
4284             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
4285         else if (*end == ';')
4286         {
4287             errno = 0;
4288             action.addr = strtoull (end + 1, NULL, 16);
4289             if (errno != 0 && action.addr == 0)
4290                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
4291         }
4292     }
4293 
4294     DNBThreadResumeActions thread_actions;
4295     thread_actions.Append (action);
4296     thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
4297     if (!DNBProcessSignal(pid, process_signo))
4298         return SendPacket ("E52");
4299     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4300         return SendPacket ("E38");
4301     /* Don't send an "OK" packet; response is the stopped/exited message.  */
4302     return rnb_success;
4303 }
4304 
4305 //----------------------------------------------------------------------
4306 // 'D' packet
4307 // Detach from gdb.
4308 //----------------------------------------------------------------------
4309 rnb_err_t
4310 RNBRemote::HandlePacket_D (const char *p)
4311 {
4312     if (m_ctx.HasValidProcessID())
4313     {
4314         if (DNBProcessDetach(m_ctx.ProcessID()))
4315             SendPacket ("OK");
4316         else
4317             SendPacket ("E");
4318     }
4319     else
4320     {
4321         SendPacket ("E");
4322     }
4323     return rnb_success;
4324 }
4325 
4326 /* 'k'
4327  Kill the inferior process.  */
4328 
4329 rnb_err_t
4330 RNBRemote::HandlePacket_k (const char *p)
4331 {
4332     DNBLog ("Got a 'k' packet, killing the inferior process.");
4333     // No response to should be sent to the kill packet
4334     if (m_ctx.HasValidProcessID())
4335         DNBProcessKill (m_ctx.ProcessID());
4336     SendPacket ("X09");
4337     return rnb_success;
4338 }
4339 
4340 rnb_err_t
4341 RNBRemote::HandlePacket_stop_process (const char *p)
4342 {
4343 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt
4344 #if defined(TEST_EXIT_ON_INTERRUPT)
4345     rnb_err_t err = HandlePacket_k (p);
4346     m_comm.Disconnect(true);
4347     return err;
4348 #else
4349     if (!DNBProcessInterrupt(m_ctx.ProcessID()))
4350     {
4351         // If we failed to interrupt the process, then send a stop
4352         // reply packet as the process was probably already stopped
4353         HandlePacket_last_signal (NULL);
4354     }
4355     return rnb_success;
4356 #endif
4357 }
4358 
4359 /* 's'
4360  Step the inferior process.  */
4361 
4362 rnb_err_t
4363 RNBRemote::HandlePacket_s (const char *p)
4364 {
4365     const nub_process_t pid = m_ctx.ProcessID();
4366     if (pid == INVALID_NUB_PROCESS)
4367         return SendPacket ("E32");
4368 
4369     // Hardware supported stepping not supported on arm
4370     nub_thread_t tid = GetContinueThread ();
4371     if (tid == 0 || tid == -1)
4372         tid = GetCurrentThread();
4373 
4374     if (tid == INVALID_NUB_THREAD)
4375         return SendPacket ("E33");
4376 
4377     DNBThreadResumeActions thread_actions;
4378     thread_actions.AppendAction(tid, eStateStepping);
4379 
4380     // Make all other threads stop when we are stepping
4381     thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
4382     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4383         return SendPacket ("E49");
4384     // Don't send an "OK" packet; response is the stopped/exited message.
4385     return rnb_success;
4386 }
4387 
4388 /* 'S sig [;addr]'
4389  Step with signal sig, optionally at address addr.  */
4390 
4391 rnb_err_t
4392 RNBRemote::HandlePacket_S (const char *p)
4393 {
4394     const nub_process_t pid = m_ctx.ProcessID();
4395     if (pid == INVALID_NUB_PROCESS)
4396         return SendPacket ("E36");
4397 
4398     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
4399 
4400     if (*(p + 1) != '\0')
4401     {
4402         char *end = NULL;
4403         errno = 0;
4404         action.signal = static_cast<int>(strtoul (p + 1, &end, 16));
4405         if (errno != 0)
4406             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
4407         else if (*end == ';')
4408         {
4409             errno = 0;
4410             action.addr = strtoull (end + 1, NULL, 16);
4411             if (errno != 0 && action.addr == 0)
4412             {
4413                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
4414             }
4415         }
4416     }
4417 
4418     action.tid = GetContinueThread ();
4419     if (action.tid == 0 || action.tid == -1)
4420         return SendPacket ("E40");
4421 
4422     nub_state_t tstate = DNBThreadGetState (pid, action.tid);
4423     if (tstate == eStateInvalid || tstate == eStateExited)
4424         return SendPacket ("E37");
4425 
4426 
4427     DNBThreadResumeActions thread_actions;
4428     thread_actions.Append (action);
4429 
4430     // Make all other threads stop when we are stepping
4431     thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
4432     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
4433         return SendPacket ("E39");
4434 
4435     // Don't send an "OK" packet; response is the stopped/exited message.
4436     return rnb_success;
4437 }
4438 
4439 static const char *
4440 GetArchName (const uint32_t cputype, const uint32_t cpusubtype)
4441 {
4442     switch (cputype)
4443     {
4444     case CPU_TYPE_ARM:
4445         switch (cpusubtype)
4446         {
4447         case 5:     return "armv4";
4448         case 6:     return "armv6";
4449         case 7:     return "armv5t";
4450         case 8:     return "xscale";
4451         case 9:     return "armv7";
4452         case 10:    return "armv7f";
4453         case 11:    return "armv7s";
4454         case 12:    return "armv7k";
4455         case 14:    return "armv6m";
4456         case 15:    return "armv7m";
4457         case 16:    return "armv7em";
4458         default:    return "arm";
4459         }
4460         break;
4461     case CPU_TYPE_ARM64:    return "arm64";
4462     case CPU_TYPE_I386:     return "i386";
4463     case CPU_TYPE_X86_64:
4464         switch (cpusubtype)
4465         {
4466         default:    return "x86_64";
4467         case 8:     return "x86_64h";
4468         }
4469         break;
4470     }
4471     return NULL;
4472 }
4473 
4474 static bool
4475 GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64)
4476 {
4477     static uint32_t g_host_cputype = 0;
4478     static uint32_t g_host_cpusubtype = 0;
4479     static uint32_t g_is_64_bit_capable = 0;
4480     static bool g_promoted_to_64 = false;
4481 
4482     if (g_host_cputype == 0)
4483     {
4484         g_promoted_to_64 = false;
4485         size_t len = sizeof(uint32_t);
4486         if  (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0)
4487         {
4488             len = sizeof (uint32_t);
4489             if  (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0)
4490             {
4491                 if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0))
4492                 {
4493                     g_promoted_to_64 = true;
4494                     g_host_cputype |= CPU_ARCH_ABI64;
4495                 }
4496             }
4497         }
4498 
4499         len = sizeof(uint32_t);
4500         if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0)
4501         {
4502             if (g_promoted_to_64 &&
4503                 g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486)
4504                 g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL;
4505         }
4506     }
4507 
4508     cputype = g_host_cputype;
4509     cpusubtype = g_host_cpusubtype;
4510     is_64_bit_capable = g_is_64_bit_capable;
4511     promoted_to_64 = g_promoted_to_64;
4512     return g_host_cputype != 0;
4513 }
4514 
4515 rnb_err_t
4516 RNBRemote::HandlePacket_qHostInfo (const char *p)
4517 {
4518     std::ostringstream strm;
4519 
4520     uint32_t cputype = 0;
4521     uint32_t cpusubtype = 0;
4522     uint32_t is_64_bit_capable = 0;
4523     bool promoted_to_64 = false;
4524     if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64))
4525     {
4526         strm << "cputype:" << std::dec << cputype << ';';
4527         strm << "cpusubtype:" << std::dec << cpusubtype << ';';
4528     }
4529 
4530     // The OS in the triple should be "ios" or "macosx" which doesn't match our
4531     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
4532     // this for now.
4533     if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
4534     {
4535         strm << "ostype:ios;";
4536         // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
4537         strm << "watchpoint_exceptions_received:before;";
4538     }
4539     else
4540     {
4541         strm << "ostype:macosx;";
4542         strm << "watchpoint_exceptions_received:after;";
4543     }
4544 //    char ostype[64];
4545 //    len = sizeof(ostype);
4546 //    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
4547 //    {
4548 //        len = strlen(ostype);
4549 //        std::transform (ostype, ostype + len, ostype, tolower);
4550 //        strm << "ostype:" << std::dec << ostype << ';';
4551 //    }
4552 
4553     strm << "vendor:apple;";
4554 
4555 #if defined (__LITTLE_ENDIAN__)
4556     strm << "endian:little;";
4557 #elif defined (__BIG_ENDIAN__)
4558     strm << "endian:big;";
4559 #elif defined (__PDP_ENDIAN__)
4560     strm << "endian:pdp;";
4561 #endif
4562 
4563     if (promoted_to_64)
4564         strm << "ptrsize:8;";
4565     else
4566         strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
4567     return SendPacket (strm.str());
4568 }
4569 
4570 void
4571 XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes)
4572 {
4573     if (indent)
4574         s << INDENT_WITH_SPACES(indent);
4575     s << '<' << name;
4576     if (!has_attributes)
4577         s << '>' << std::endl;
4578 }
4579 
4580 void
4581 XMLElementStartEndAttributes (std::ostringstream &s, bool empty)
4582 {
4583     if (empty)
4584         s << '/';
4585     s << '>' << std::endl;
4586 }
4587 
4588 void
4589 XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name)
4590 {
4591     if (indent)
4592         s << INDENT_WITH_SPACES(indent);
4593     s << '<' << '/' << name << '>' << std::endl;
4594 }
4595 
4596 void
4597 XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true)
4598 {
4599     if (value)
4600     {
4601         if (indent)
4602             s << INDENT_WITH_SPACES(indent);
4603         s << '<' << name << '>' << value;
4604         if (close)
4605             XMLElementEnd(s, 0, name);
4606     }
4607 }
4608 
4609 void
4610 XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true)
4611 {
4612     if (indent)
4613         s << INDENT_WITH_SPACES(indent);
4614 
4615     s << '<' << name << '>' << DECIMAL << value;
4616     if (close)
4617         XMLElementEnd(s, 0, name);
4618 }
4619 
4620 void
4621 XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL)
4622 {
4623     if (value)
4624     {
4625         if (default_value && strcmp(value, default_value) == 0)
4626             return; // No need to emit the attribute because it matches the default value
4627         s <<' ' << name << "=\"" << value << "\"";
4628     }
4629 }
4630 
4631 void
4632 XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value)
4633 {
4634     s <<' ' << name << "=\"" << DECIMAL << value << "\"";
4635 }
4636 
4637 void
4638 GenerateTargetXMLRegister (std::ostringstream &s,
4639                            const uint32_t reg_num,
4640                            nub_size_t num_reg_sets,
4641                            const DNBRegisterSetInfo *reg_set_info,
4642                            const register_map_entry_t &reg)
4643 {
4644     const char *default_lldb_encoding = "uint";
4645     const char *lldb_encoding = default_lldb_encoding;
4646     const char *gdb_group = "general";
4647     const char *default_gdb_type = "int";
4648     const char *gdb_type = default_gdb_type;
4649     const char *default_lldb_format = "hex";
4650     const char *lldb_format = default_lldb_format;
4651     const char *lldb_set = NULL;
4652 
4653     switch (reg.nub_info.type)
4654     {
4655         case Uint:      lldb_encoding = "uint"; break;
4656         case Sint:      lldb_encoding = "sint"; break;
4657         case IEEE754:   lldb_encoding = "ieee754";  if (reg.nub_info.set > 0) gdb_group = "float"; break;
4658         case Vector:    lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break;
4659     }
4660 
4661     switch (reg.nub_info.format)
4662     {
4663         case Binary:            lldb_format = "binary"; break;
4664         case Decimal:           lldb_format = "decimal"; break;
4665         case Hex:               lldb_format = "hex"; break;
4666         case Float:             gdb_type = "float"; lldb_format = "float"; break;
4667         case VectorOfSInt8:     gdb_type = "float"; lldb_format = "vector-sint8"; break;
4668         case VectorOfUInt8:     gdb_type = "float"; lldb_format = "vector-uint8"; break;
4669         case VectorOfSInt16:    gdb_type = "float"; lldb_format = "vector-sint16"; break;
4670         case VectorOfUInt16:    gdb_type = "float"; lldb_format = "vector-uint16"; break;
4671         case VectorOfSInt32:    gdb_type = "float"; lldb_format = "vector-sint32"; break;
4672         case VectorOfUInt32:    gdb_type = "float"; lldb_format = "vector-uint32"; break;
4673         case VectorOfFloat32:   gdb_type = "float"; lldb_format = "vector-float32"; break;
4674         case VectorOfUInt128:   gdb_type = "float"; lldb_format = "vector-uint128"; break;
4675     };
4676     if (reg_set_info && reg.nub_info.set < num_reg_sets)
4677         lldb_set = reg_set_info[reg.nub_info.set].name;
4678 
4679     uint32_t indent = 2;
4680 
4681     XMLElementStart(s, indent, "reg", true);
4682     XMLAttributeString(s, "name", reg.nub_info.name);
4683     XMLAttributeUnsignedDecimal(s, "regnum", reg_num);
4684     XMLAttributeUnsignedDecimal(s, "offset", reg.offset);
4685     XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8);
4686     XMLAttributeString(s, "group", gdb_group);
4687     XMLAttributeString(s, "type", gdb_type, default_gdb_type);
4688     XMLAttributeString (s, "altname", reg.nub_info.alt);
4689     XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding);
4690     XMLAttributeString(s, "format", lldb_format, default_lldb_format);
4691     XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set);
4692     if (reg.nub_info.reg_gcc != INVALID_NUB_REGNUM)
4693         XMLAttributeUnsignedDecimal(s, "gcc_regnum", reg.nub_info.reg_gcc);
4694     if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM)
4695         XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf);
4696 
4697     const char *lldb_generic = NULL;
4698     switch (reg.nub_info.reg_generic)
4699     {
4700         case GENERIC_REGNUM_FP:     lldb_generic = "fp"; break;
4701         case GENERIC_REGNUM_PC:     lldb_generic = "pc"; break;
4702         case GENERIC_REGNUM_SP:     lldb_generic = "sp"; break;
4703         case GENERIC_REGNUM_RA:     lldb_generic = "ra"; break;
4704         case GENERIC_REGNUM_FLAGS:  lldb_generic = "flags"; break;
4705         case GENERIC_REGNUM_ARG1:   lldb_generic = "arg1"; break;
4706         case GENERIC_REGNUM_ARG2:   lldb_generic = "arg2"; break;
4707         case GENERIC_REGNUM_ARG3:   lldb_generic = "arg3"; break;
4708         case GENERIC_REGNUM_ARG4:   lldb_generic = "arg4"; break;
4709         case GENERIC_REGNUM_ARG5:   lldb_generic = "arg5"; break;
4710         case GENERIC_REGNUM_ARG6:   lldb_generic = "arg6"; break;
4711         case GENERIC_REGNUM_ARG7:   lldb_generic = "arg7"; break;
4712         case GENERIC_REGNUM_ARG8:   lldb_generic = "arg8"; break;
4713         default: break;
4714     }
4715     XMLAttributeString(s, "generic", lldb_generic);
4716 
4717 
4718     bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty();
4719     if (!empty)
4720     {
4721         if (!reg.value_regnums.empty())
4722         {
4723             std::ostringstream regnums;
4724             bool first = true;
4725             regnums << DECIMAL;
4726             for (auto regnum : reg.value_regnums)
4727             {
4728                 if (!first)
4729                     regnums << ',';
4730                 regnums << regnum;
4731                 first = false;
4732             }
4733             XMLAttributeString(s, "value_regnums", regnums.str().c_str());
4734         }
4735 
4736         if (!reg.invalidate_regnums.empty())
4737         {
4738             std::ostringstream regnums;
4739             bool first = true;
4740             regnums << DECIMAL;
4741             for (auto regnum : reg.invalidate_regnums)
4742             {
4743                 if (!first)
4744                     regnums << ',';
4745                 regnums << regnum;
4746                 first = false;
4747             }
4748             XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str());
4749         }
4750     }
4751     XMLElementStartEndAttributes(s, true);
4752 }
4753 
4754 void
4755 GenerateTargetXMLRegisters (std::ostringstream &s)
4756 {
4757     nub_size_t num_reg_sets = 0;
4758     const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
4759 
4760 
4761     uint32_t cputype = DNBGetRegisterCPUType();
4762     if (cputype)
4763     {
4764         XMLElementStart(s, 0, "feature", true);
4765         std::ostringstream name_strm;
4766         name_strm << "com.apple.debugserver." << GetArchName (cputype, 0);
4767         XMLAttributeString(s, "name", name_strm.str().c_str());
4768         XMLElementStartEndAttributes(s, false);
4769         for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num)
4770 //        for (const auto &reg: g_dynamic_register_map)
4771         {
4772             GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]);
4773         }
4774         XMLElementEnd(s, 0, "feature");
4775 
4776         if (num_reg_sets > 0)
4777         {
4778             XMLElementStart(s, 0, "groups", false);
4779             for (uint32_t set=1; set<num_reg_sets; ++set)
4780             {
4781                 XMLElementStart(s, 2, "group", true);
4782                 XMLAttributeUnsignedDecimal(s, "id", set);
4783                 XMLAttributeString(s, "name", reg_sets[set].name);
4784                 XMLElementStartEndAttributes(s, true);
4785             }
4786             XMLElementEnd(s, 0, "groups");
4787         }
4788     }
4789 }
4790 
4791 static const char *g_target_xml_header = R"(<?xml version="1.0"?>
4792 <target version="1.0">)";
4793 
4794 static const char *g_target_xml_footer = "</target>";
4795 
4796 static std::string g_target_xml;
4797 
4798 void
4799 UpdateTargetXML ()
4800 {
4801     std::ostringstream s;
4802     s << g_target_xml_header << std::endl;
4803 
4804     // Set the architecture
4805     //s << "<architecture>" << arch "</architecture>" << std::endl;
4806 
4807     // Set the OSABI
4808     //s << "<osabi>abi-name</osabi>"
4809 
4810     GenerateTargetXMLRegisters(s);
4811 
4812     s << g_target_xml_footer << std::endl;
4813 
4814     // Save the XML output in case it gets retrieved in chunks
4815     g_target_xml = s.str();
4816 }
4817 
4818 rnb_err_t
4819 RNBRemote::HandlePacket_qXfer (const char *command)
4820 {
4821     const char *p = command;
4822     p += strlen ("qXfer:");
4823     const char *sep = strchr(p, ':');
4824     if (sep)
4825     {
4826         std::string object(p, sep - p);     // "auxv", "backtrace", "features", etc
4827         p = sep + 1;
4828         sep = strchr(p, ':');
4829         if (sep)
4830         {
4831             std::string rw(p, sep - p);    // "read" or "write"
4832             p = sep + 1;
4833             sep = strchr(p, ':');
4834             if (sep)
4835             {
4836                 std::string annex(p, sep - p);    // "read" or "write"
4837 
4838                 p = sep + 1;
4839                 sep = strchr(p, ',');
4840                 if (sep)
4841                 {
4842                     std::string offset_str(p, sep - p); // read the length as a string
4843                     p = sep + 1;
4844                     std::string length_str(p); // read the offset as a string
4845                     char *end = nullptr;
4846                     const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset
4847                     if (*end == '\0')
4848                     {
4849                         const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length
4850                         if (*end == '\0')
4851                         {
4852                             if (object == "features"  &&
4853                                 rw     == "read"      &&
4854                                 annex  == "target.xml")
4855                             {
4856                                 std::ostringstream xml_out;
4857 
4858                                 if (offset == 0)
4859                                 {
4860                                     InitializeRegisters (true);
4861 
4862                                     UpdateTargetXML();
4863                                     if (g_target_xml.empty())
4864                                         return SendPacket("E83");
4865 
4866                                     if (length > g_target_xml.size())
4867                                     {
4868                                         xml_out << 'l'; // No more data
4869                                         xml_out << binary_encode_string(g_target_xml);
4870                                     }
4871                                     else
4872                                     {
4873                                         xml_out << 'm'; // More data needs to be read with a subsequent call
4874                                         xml_out << binary_encode_string(std::string(g_target_xml, offset, length));
4875                                     }
4876                                 }
4877                                 else
4878                                 {
4879                                     // Retrieving target XML in chunks
4880                                     if (offset < g_target_xml.size())
4881                                     {
4882                                         std::string chunk(g_target_xml, offset, length);
4883                                         if (chunk.size() < length)
4884                                             xml_out << 'l'; // No more data
4885                                         else
4886                                             xml_out << 'm'; // More data needs to be read with a subsequent call
4887                                         xml_out << binary_encode_string(chunk.data());
4888                                     }
4889                                 }
4890                                 return SendPacket(xml_out.str());
4891                             }
4892                             // Well formed, put not supported
4893                             return HandlePacket_UNIMPLEMENTED (command);
4894                         }
4895                     }
4896                 }
4897             }
4898             else
4899             {
4900                 SendPacket ("E85");
4901             }
4902         }
4903         else
4904         {
4905             SendPacket ("E86");
4906         }
4907     }
4908     return SendPacket ("E82");
4909 }
4910 
4911 
4912 rnb_err_t
4913 RNBRemote::HandlePacket_qGDBServerVersion (const char *p)
4914 {
4915     std::ostringstream strm;
4916 
4917 #if defined(DEBUGSERVER_PROGRAM_NAME)
4918     strm << "name:" DEBUGSERVER_PROGRAM_NAME ";";
4919 #else
4920     strm << "name:debugserver;";
4921 #endif
4922     strm << "version:" << DEBUGSERVER_VERSION_STR << ";";
4923 
4924     return SendPacket (strm.str());
4925 }
4926 
4927 // A helper function that retrieves a single integer value from
4928 // a one-level-deep JSON dictionary of key-value pairs.  e.g.
4929 // jThreadExtendedInfo:{"plo_pthread_tsd_base_address_offset":0,"plo_pthread_tsd_base_offset":224,"plo_pthread_tsd_entry_size":8,"thread":144305}]
4930 //
4931 uint64_t
4932 get_integer_value_for_key_name_from_json (const char *key, const char *json_string)
4933 {
4934     uint64_t retval = INVALID_NUB_ADDRESS;
4935     std::string key_with_quotes = "\"";
4936     key_with_quotes += key;
4937     key_with_quotes += "\"";
4938     const char *c = strstr (json_string, key_with_quotes.c_str());
4939     if (c)
4940     {
4941         c += key_with_quotes.size();
4942 
4943         while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
4944             c++;
4945 
4946         if (*c == ':')
4947         {
4948             c++;
4949 
4950             while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r'))
4951                 c++;
4952 
4953             errno = 0;
4954             retval = strtoul (c, NULL, 10);
4955             if (errno != 0)
4956             {
4957                 retval = INVALID_NUB_ADDRESS;
4958             }
4959         }
4960     }
4961     return retval;
4962 
4963 }
4964 
4965 rnb_err_t
4966 RNBRemote::HandlePacket_jThreadsInfo (const char *p)
4967 {
4968     JSONGenerator::Array threads_array;
4969 
4970     std::ostringstream json;
4971     std::ostringstream reply_strm;
4972     // If we haven't run the process yet, return an error.
4973     if (m_ctx.HasValidProcessID())
4974     {
4975         nub_process_t pid = m_ctx.ProcessID();
4976 
4977         nub_size_t numthreads = DNBProcessGetNumThreads (pid);
4978         for (nub_size_t i = 0; i < numthreads; ++i)
4979         {
4980             nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i);
4981 
4982             struct DNBThreadStopInfo tid_stop_info;
4983 
4984             JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary());
4985 
4986             thread_dict_sp->AddIntegerItem("tid", tid);
4987 
4988             std::string reason_value("none");
4989             if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
4990             {
4991                 switch (tid_stop_info.reason)
4992                 {
4993                     case eStopTypeInvalid:
4994                         break;
4995                     case eStopTypeSignal:
4996                         if (tid_stop_info.details.signal.signo != 0)
4997                             reason_value = "signal";
4998                         break;
4999                     case eStopTypeException:
5000                         if (tid_stop_info.details.exception.type != 0)
5001                             reason_value = "exception";
5002                         break;
5003                     case eStopTypeExec:
5004                         reason_value = "exec";
5005                         break;
5006                 }
5007                 if (tid_stop_info.reason == eStopTypeSignal)
5008                 {
5009                     thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo);
5010                 }
5011                 else if (tid_stop_info.reason == eStopTypeException && tid_stop_info.details.exception.type != 0)
5012                 {
5013                     thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type);
5014                     JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array());
5015                     for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i)
5016                     {
5017                         medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i])));
5018                     }
5019                     thread_dict_sp->AddItem("medata", medata_array_sp);
5020                 }
5021             }
5022 
5023             thread_dict_sp->AddStringItem("reason", reason_value);
5024 
5025             const char *thread_name = DNBThreadGetName (pid, tid);
5026             if (thread_name && thread_name[0])
5027                 thread_dict_sp->AddStringItem("name", thread_name);
5028 
5029 
5030             thread_identifier_info_data_t thread_ident_info;
5031             if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
5032             {
5033                 if (thread_ident_info.dispatch_qaddr != 0)
5034                 {
5035                     thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr);
5036 
5037                     const DispatchQueueOffsets *dispatch_queue_offsets = GetDispatchQueueOffsets();
5038                     if (dispatch_queue_offsets)
5039                     {
5040                         std::string queue_name;
5041                         uint64_t queue_width = 0;
5042                         uint64_t queue_serialnum = 0;
5043                         dispatch_queue_offsets->GetThreadQueueInfo(pid, thread_ident_info.dispatch_qaddr, queue_name, queue_width, queue_serialnum);
5044                         if (!queue_name.empty())
5045                             thread_dict_sp->AddStringItem("qname", queue_name);
5046                         if (queue_width == 1)
5047                             thread_dict_sp->AddStringItem("qkind", "serial");
5048                         else if (queue_width > 1)
5049                             thread_dict_sp->AddStringItem("qkind", "concurrent");
5050                         if (queue_serialnum > 0)
5051                             thread_dict_sp->AddIntegerItem("qserial", queue_serialnum);
5052                     }
5053                 }
5054             }
5055             DNBRegisterValue reg_value;
5056 
5057             if (g_reg_entries != NULL)
5058             {
5059                 JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary());
5060 
5061                 for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
5062                 {
5063                     // Expedite all registers in the first register set that aren't
5064                     // contained in other registers
5065                     if (g_reg_entries[reg].nub_info.set == 1 &&
5066                         g_reg_entries[reg].nub_info.value_regs == NULL)
5067                     {
5068                         if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
5069                             continue;
5070 
5071                         std::ostringstream reg_num;
5072                         reg_num << std::dec << g_reg_entries[reg].gdb_regnum;
5073                         // Encode native byte ordered bytes as hex ascii
5074                         registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size);
5075                     }
5076                 }
5077                 thread_dict_sp->AddItem("registers", registers_dict_sp);
5078             }
5079 
5080             // Add expedited stack memory so stack backtracing doesn't need to read anything from the
5081             // frame pointer chain.
5082             StackMemoryMap stack_mmap;
5083             ReadStackMemory (pid, tid, stack_mmap);
5084             if (!stack_mmap.empty())
5085             {
5086                 JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array());
5087 
5088                 for (const auto &stack_memory : stack_mmap)
5089                 {
5090                     JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary());
5091                     stack_memory_sp->AddIntegerItem("address", stack_memory.first);
5092                     stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length);
5093                     memory_array_sp->AddItem(stack_memory_sp);
5094                 }
5095                 thread_dict_sp->AddItem("memory", memory_array_sp);
5096             }
5097             threads_array.AddItem(thread_dict_sp);
5098         }
5099 
5100         std::ostringstream strm;
5101         threads_array.Dump (strm);
5102         std::string binary_packet = binary_encode_string (strm.str());
5103         if (!binary_packet.empty())
5104             return SendPacket (binary_packet.c_str());
5105     }
5106     return SendPacket ("E85");
5107 
5108 }
5109 
5110 rnb_err_t
5111 RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
5112 {
5113     nub_process_t pid;
5114     std::ostringstream json;
5115     // If we haven't run the process yet, return an error.
5116     if (!m_ctx.HasValidProcessID())
5117     {
5118         return SendPacket ("E81");
5119     }
5120 
5121     pid = m_ctx.ProcessID();
5122 
5123     const char thread_extended_info_str[] = { "jThreadExtendedInfo:{" };
5124     if (strncmp (p, thread_extended_info_str, sizeof (thread_extended_info_str) - 1) == 0)
5125     {
5126         p += strlen (thread_extended_info_str);
5127 
5128         uint64_t tid = get_integer_value_for_key_name_from_json ("thread", p);
5129         uint64_t plo_pthread_tsd_base_address_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_address_offset", p);
5130         uint64_t plo_pthread_tsd_base_offset = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_base_offset", p);
5131         uint64_t plo_pthread_tsd_entry_size = get_integer_value_for_key_name_from_json ("plo_pthread_tsd_entry_size", p);
5132         uint64_t dti_qos_class_index = get_integer_value_for_key_name_from_json ("dti_qos_class_index", p);
5133         // Commented out the two variables below as they are not being used
5134 //        uint64_t dti_queue_index = get_integer_value_for_key_name_from_json ("dti_queue_index", p);
5135 //        uint64_t dti_voucher_index = get_integer_value_for_key_name_from_json ("dti_voucher_index", p);
5136 
5137         if (tid != INVALID_NUB_ADDRESS)
5138         {
5139             nub_addr_t pthread_t_value = DNBGetPThreadT (pid, tid);
5140 
5141             uint64_t tsd_address = INVALID_NUB_ADDRESS;
5142             if (plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS
5143                 && plo_pthread_tsd_base_offset != INVALID_NUB_ADDRESS
5144                 && plo_pthread_tsd_entry_size != INVALID_NUB_ADDRESS)
5145             {
5146                 tsd_address = DNBGetTSDAddressForThread (pid, tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size);
5147             }
5148 
5149             bool timed_out = false;
5150             Genealogy::ThreadActivitySP thread_activity_sp;
5151 
5152             // If the pthread_t value is invalid, or if we were able to fetch the thread's TSD base
5153             // and got an invalid value back, then we have a thread in early startup or shutdown and
5154             // it's possible that gathering the genealogy information for this thread go badly.
5155             // Ideally fetching this info for a thread in these odd states shouldn't matter - but
5156             // we've seen some problems with these new SPI and threads in edge-casey states.
5157 
5158             double genealogy_fetch_time = 0;
5159             if (pthread_t_value != INVALID_NUB_ADDRESS && tsd_address != INVALID_NUB_ADDRESS)
5160             {
5161                 DNBTimer timer(false);
5162                 thread_activity_sp = DNBGetGenealogyInfoForThread (pid, tid, timed_out);
5163                 genealogy_fetch_time = timer.ElapsedMicroSeconds(false) / 1000000.0;
5164             }
5165 
5166             std::unordered_set<uint32_t> process_info_indexes; // an array of the process info #'s seen
5167 
5168             json << "{";
5169 
5170             bool need_to_print_comma = false;
5171 
5172             if (thread_activity_sp && timed_out == false)
5173             {
5174                 const Genealogy::Activity *activity = &thread_activity_sp->current_activity;
5175                 bool need_vouchers_comma_sep = false;
5176                 json << "\"activity_query_timed_out\":false,";
5177                 if (genealogy_fetch_time != 0)
5178                 {
5179                     //  If we append the floating point value with << we'll get it in scientific
5180                     //  notation.
5181                     char floating_point_ascii_buffer[64];
5182                     floating_point_ascii_buffer[0] = '\0';
5183                     snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time);
5184                     if (strlen (floating_point_ascii_buffer) > 0)
5185                     {
5186                         if (need_to_print_comma)
5187                             json << ",";
5188                         need_to_print_comma = true;
5189                         json << "\"activity_query_duration\":" << floating_point_ascii_buffer;
5190                     }
5191                 }
5192                 if (activity->activity_id != 0)
5193                 {
5194                     if (need_to_print_comma)
5195                         json << ",";
5196                     need_to_print_comma = true;
5197                     need_vouchers_comma_sep = true;
5198                     json << "\"activity\":{";
5199                     json <<    "\"start\":" << activity->activity_start << ",";
5200                     json <<    "\"id\":" << activity->activity_id << ",";
5201                     json <<    "\"parent_id\":" << activity->parent_id << ",";
5202                     json <<    "\"name\":\"" << json_string_quote_metachars (activity->activity_name) << "\",";
5203                     json <<    "\"reason\":\"" << json_string_quote_metachars (activity->reason) << "\"";
5204                     json << "}";
5205                 }
5206                 if (thread_activity_sp->messages.size() > 0)
5207                 {
5208                     need_to_print_comma = true;
5209                     if (need_vouchers_comma_sep)
5210                         json << ",";
5211                     need_vouchers_comma_sep = true;
5212                     json << "\"trace_messages\":[";
5213                     bool printed_one_message = false;
5214                     for (auto iter = thread_activity_sp->messages.begin() ; iter != thread_activity_sp->messages.end(); ++iter)
5215                     {
5216                         if (printed_one_message)
5217                             json << ",";
5218                         else
5219                             printed_one_message = true;
5220                         json << "{";
5221                         json <<   "\"timestamp\":" << iter->timestamp << ",";
5222                         json <<   "\"activity_id\":" << iter->activity_id << ",";
5223                         json <<   "\"trace_id\":" << iter->trace_id << ",";
5224                         json <<   "\"thread\":" << iter->thread << ",";
5225                         json <<   "\"type\":" << (int) iter->type << ",";
5226                         json <<   "\"process_info_index\":" << iter->process_info_index << ",";
5227                         process_info_indexes.insert (iter->process_info_index);
5228                         json <<   "\"message\":\"" << json_string_quote_metachars (iter->message) << "\"";
5229                         json << "}";
5230                     }
5231                     json << "]";
5232                 }
5233                 if (thread_activity_sp->breadcrumbs.size() == 1)
5234                 {
5235                     need_to_print_comma = true;
5236                     if (need_vouchers_comma_sep)
5237                         json << ",";
5238                     need_vouchers_comma_sep = true;
5239                     json << "\"breadcrumb\":{";
5240                     for (auto iter = thread_activity_sp->breadcrumbs.begin() ; iter != thread_activity_sp->breadcrumbs.end(); ++iter)
5241                     {
5242                         json <<   "\"breadcrumb_id\":" << iter->breadcrumb_id << ",";
5243                         json <<   "\"activity_id\":" << iter->activity_id << ",";
5244                         json <<   "\"timestamp\":" << iter->timestamp << ",";
5245                         json <<   "\"name\":\"" << json_string_quote_metachars (iter->name) << "\"";
5246                     }
5247                     json << "}";
5248                 }
5249                 if (process_info_indexes.size() > 0)
5250                 {
5251                     need_to_print_comma = true;
5252                     if (need_vouchers_comma_sep)
5253                         json << ",";
5254                     need_vouchers_comma_sep = true;
5255                     json << "\"process_infos\":[";
5256                     bool printed_one_process_info = false;
5257                     for (auto iter = process_info_indexes.begin(); iter != process_info_indexes.end(); ++iter)
5258                     {
5259                         if (printed_one_process_info)
5260                             json << ",";
5261                         else
5262                             printed_one_process_info = true;
5263                         Genealogy::ProcessExecutableInfoSP image_info_sp;
5264                         uint32_t idx = *iter;
5265                         image_info_sp = DNBGetGenealogyImageInfo (pid, idx);
5266                         json << "{";
5267                         char uuid_buf[37];
5268                         uuid_unparse_upper (image_info_sp->image_uuid, uuid_buf);
5269                         json <<   "\"process_info_index\":" << idx << ",";
5270                         json <<  "\"image_path\":\"" << json_string_quote_metachars (image_info_sp->image_path) << "\",";
5271                         json <<  "\"image_uuid\":\"" << uuid_buf <<"\"";
5272                         json << "}";
5273                     }
5274                     json << "]";
5275                 }
5276             }
5277             else
5278             {
5279                 if (timed_out)
5280                 {
5281                     if (need_to_print_comma)
5282                         json << ",";
5283                     need_to_print_comma = true;
5284                     json << "\"activity_query_timed_out\":true";
5285                     if (genealogy_fetch_time != 0)
5286                     {
5287                         //  If we append the floating point value with << we'll get it in scientific
5288                         //  notation.
5289                         char floating_point_ascii_buffer[64];
5290                         floating_point_ascii_buffer[0] = '\0';
5291                         snprintf (floating_point_ascii_buffer, sizeof (floating_point_ascii_buffer), "%f", genealogy_fetch_time);
5292                         if (strlen (floating_point_ascii_buffer) > 0)
5293                         {
5294                             json << ",";
5295                             json << "\"activity_query_duration\":" << floating_point_ascii_buffer;
5296                         }
5297                     }
5298                 }
5299             }
5300 
5301             if (tsd_address != INVALID_NUB_ADDRESS)
5302             {
5303                 if (need_to_print_comma)
5304                     json << ",";
5305                 need_to_print_comma = true;
5306                 json << "\"tsd_address\":" << tsd_address;
5307 
5308                 if (dti_qos_class_index != 0 && dti_qos_class_index != UINT64_MAX)
5309                 {
5310                     ThreadInfo::QoS requested_qos = DNBGetRequestedQoSForThread (pid, tid, tsd_address, dti_qos_class_index);
5311                     if (requested_qos.IsValid())
5312                     {
5313                         if (need_to_print_comma)
5314                             json << ",";
5315                         need_to_print_comma = true;
5316                         json << "\"requested_qos\":{";
5317                         json <<    "\"enum_value\":" << requested_qos.enum_value << ",";
5318                         json <<    "\"constant_name\":\"" << json_string_quote_metachars (requested_qos.constant_name) << "\",";
5319                         json <<    "\"printable_name\":\"" << json_string_quote_metachars (requested_qos.printable_name) << "\"";
5320                         json << "}";
5321                     }
5322                 }
5323             }
5324 
5325             if (pthread_t_value != INVALID_NUB_ADDRESS)
5326             {
5327                 if (need_to_print_comma)
5328                     json << ",";
5329                 need_to_print_comma = true;
5330                 json << "\"pthread_t\":" << pthread_t_value;
5331             }
5332 
5333             nub_addr_t dispatch_queue_t_value = DNBGetDispatchQueueT (pid, tid);
5334             if (dispatch_queue_t_value != INVALID_NUB_ADDRESS)
5335             {
5336                 if (need_to_print_comma)
5337                     json << ",";
5338                 need_to_print_comma = true;
5339                 json << "\"dispatch_queue_t\":" << dispatch_queue_t_value;
5340             }
5341 
5342             json << "}";
5343             std::string json_quoted = binary_encode_string (json.str());
5344             return SendPacket (json_quoted);
5345         }
5346     }
5347     return SendPacket ("OK");
5348 }
5349 
5350 rnb_err_t
5351 RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p)
5352 {
5353     nub_process_t pid;
5354     // If we haven't run the process yet, return an error.
5355     if (!m_ctx.HasValidProcessID())
5356     {
5357         return SendPacket ("E83");
5358     }
5359 
5360     pid = m_ctx.ProcessID();
5361 
5362     const char get_loaded_dynamic_libraries_infos_str[] = { "jGetLoadedDynamicLibrariesInfos:{" };
5363     if (strncmp (p, get_loaded_dynamic_libraries_infos_str, sizeof (get_loaded_dynamic_libraries_infos_str) - 1) == 0)
5364     {
5365         p += strlen (get_loaded_dynamic_libraries_infos_str);
5366 
5367         nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p);
5368         nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p);
5369 
5370         if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS)
5371         {
5372             JSONGenerator::ObjectSP json_sp;
5373 
5374             json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count);
5375 
5376             if (json_sp.get())
5377             {
5378                 std::ostringstream json_str;
5379                 json_sp->Dump (json_str);
5380                 if (json_str.str().size() > 0)
5381                 {
5382                     std::string json_str_quoted = binary_encode_string (json_str.str());
5383                     return SendPacket (json_str_quoted.c_str());
5384                 }
5385                 else
5386                 {
5387                     SendPacket ("E84");
5388                 }
5389             }
5390         }
5391     }
5392     return SendPacket ("OK");
5393 }
5394 
5395 rnb_err_t
5396 RNBRemote::HandlePacket_qSymbol (const char *command)
5397 {
5398     const char *p = command;
5399     p += strlen ("qSymbol:");
5400     const char *sep = strchr(p, ':');
5401 
5402     std::string symbol_name;
5403     std::string symbol_value_str;
5404     // Extract the symbol value if there is one
5405     if (sep > p)
5406         symbol_value_str.assign(p, sep - p);
5407     p = sep + 1;
5408 
5409     if (*p)
5410     {
5411         // We have a symbol name
5412         symbol_name = std::move(decode_hex_ascii_string(p));
5413         if (!symbol_value_str.empty())
5414         {
5415             nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16);
5416             if (symbol_name == "dispatch_queue_offsets")
5417                 m_dispatch_queue_offsets_addr = symbol_value;
5418         }
5419         ++m_qSymbol_index;
5420     }
5421     else
5422     {
5423         // No symbol name, set our symbol index to zero so we can
5424         // read any symbols that we need
5425         m_qSymbol_index = 0;
5426     }
5427 
5428     symbol_name.clear();
5429 
5430     if (m_qSymbol_index == 0)
5431     {
5432         if (m_dispatch_queue_offsets_addr == INVALID_NUB_ADDRESS)
5433             symbol_name = "dispatch_queue_offsets";
5434         else
5435             ++m_qSymbol_index;
5436     }
5437 
5438 //    // Lookup next symbol when we have one...
5439 //    if (m_qSymbol_index == 1)
5440 //    {
5441 //    }
5442 
5443 
5444     if (symbol_name.empty())
5445     {
5446         // Done with symbol lookups
5447         return SendPacket ("OK");
5448     }
5449     else
5450     {
5451         std::ostringstream reply;
5452         reply << "qSymbol:";
5453         for (size_t i = 0; i < symbol_name.size(); ++i)
5454             reply << RAWHEX8(symbol_name[i]);
5455         return SendPacket (reply.str().c_str());
5456     }
5457 }
5458 
5459 // Note that all numeric values returned by qProcessInfo are hex encoded,
5460 // including the pid and the cpu type.
5461 
5462 rnb_err_t
5463 RNBRemote::HandlePacket_qProcessInfo (const char *p)
5464 {
5465     nub_process_t pid;
5466     std::ostringstream rep;
5467 
5468     // If we haven't run the process yet, return an error.
5469     if (!m_ctx.HasValidProcessID())
5470         return SendPacket ("E68");
5471 
5472     pid = m_ctx.ProcessID();
5473 
5474     rep << "pid:" << std::hex << pid << ";";
5475 
5476     int procpid_mib[4];
5477     procpid_mib[0] = CTL_KERN;
5478     procpid_mib[1] = KERN_PROC;
5479     procpid_mib[2] = KERN_PROC_PID;
5480     procpid_mib[3] = pid;
5481     struct kinfo_proc proc_kinfo;
5482     size_t proc_kinfo_size = sizeof(struct kinfo_proc);
5483 
5484     if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
5485     {
5486         if (proc_kinfo_size > 0)
5487         {
5488             rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";";
5489             rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";";
5490             rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";";
5491             rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";";
5492             if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
5493                 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";";
5494         }
5495     }
5496 
5497     cpu_type_t cputype = DNBProcessGetCPUType (pid);
5498     if (cputype == 0)
5499     {
5500         DNBLog ("Unable to get the process cpu_type, making a best guess.");
5501         cputype = best_guess_cpu_type();
5502     }
5503 
5504     if (cputype != 0)
5505     {
5506         rep << "cputype:" << std::hex << cputype << ";";
5507     }
5508 
5509     bool host_cpu_is_64bit = false;
5510     uint32_t is64bit_capable;
5511     size_t is64bit_capable_len = sizeof (is64bit_capable);
5512     if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0)
5513         host_cpu_is_64bit = is64bit_capable != 0;
5514 
5515     uint32_t cpusubtype;
5516     size_t cpusubtype_len = sizeof(cpusubtype);
5517     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
5518     {
5519         // If a process is CPU_TYPE_X86, then ignore the cpusubtype that we detected
5520         // from the host and use CPU_SUBTYPE_I386_ALL because we don't want the
5521         // CPU_SUBTYPE_X86_ARCH1 or CPU_SUBTYPE_X86_64_H to be used as the cpu subtype
5522         // for i386...
5523         if (host_cpu_is_64bit)
5524         {
5525             if (cputype == CPU_TYPE_X86)
5526             {
5527                 cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
5528             }
5529             else if (cputype == CPU_TYPE_ARM)
5530             {
5531                 // We can query a process' cputype but we cannot query a process' cpusubtype.
5532                 // If the process has cputype CPU_TYPE_ARM, then it is an armv7 (32-bit process) and we
5533                 // need to override the host cpusubtype (which is in the CPU_SUBTYPE_ARM64 subtype namespace)
5534                 // with a reasonable CPU_SUBTYPE_ARMV7 subtype.
5535                 cpusubtype = 11; // CPU_SUBTYPE_ARM_V7S
5536             }
5537         }
5538         rep << "cpusubtype:" << std::hex << cpusubtype << ';';
5539     }
5540 
5541     // The OS in the triple should be "ios" or "macosx" which doesn't match our
5542     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
5543     // this for now.
5544     if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
5545         rep << "ostype:ios;";
5546     else
5547     {
5548         bool is_ios_simulator = false;
5549         if (cputype == CPU_TYPE_X86 || cputype == CPU_TYPE_X86_64)
5550         {
5551             // Check for iOS simulator binaries by getting the process argument
5552             // and environment and checking for SIMULATOR_UDID in the environment
5553             int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)pid };
5554 
5555             uint8_t arg_data[8192];
5556             size_t arg_data_size = sizeof(arg_data);
5557             if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
5558             {
5559                 DNBDataRef data (arg_data, arg_data_size, false);
5560                 DNBDataRef::offset_t offset = 0;
5561                 uint32_t argc = data.Get32 (&offset);
5562                 const char *cstr;
5563 
5564                 cstr = data.GetCStr (&offset);
5565                 if (cstr)
5566                 {
5567                     // Skip NULLs
5568                     while (1)
5569                     {
5570                         const char *p = data.PeekCStr(offset);
5571                         if ((p == NULL) || (*p != '\0'))
5572                             break;
5573                         ++offset;
5574                     }
5575                     // Now skip all arguments
5576                     for (uint32_t i = 0; i < argc; ++i)
5577                     {
5578                         data.GetCStr(&offset);
5579                     }
5580 
5581                     // Now iterate across all environment variables
5582                     while ((cstr = data.GetCStr(&offset)))
5583                     {
5584                         if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0)
5585                         {
5586                             is_ios_simulator = true;
5587                             break;
5588                         }
5589                         if (cstr[0] == '\0')
5590                             break;
5591 
5592                     }
5593                 }
5594             }
5595         }
5596         if (is_ios_simulator)
5597             rep << "ostype:ios;";
5598         else
5599             rep << "ostype:macosx;";
5600     }
5601 
5602     rep << "vendor:apple;";
5603 
5604 #if defined (__LITTLE_ENDIAN__)
5605     rep << "endian:little;";
5606 #elif defined (__BIG_ENDIAN__)
5607     rep << "endian:big;";
5608 #elif defined (__PDP_ENDIAN__)
5609     rep << "endian:pdp;";
5610 #endif
5611 
5612 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
5613     nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
5614     kern_return_t kr;
5615     x86_thread_state_t gp_regs;
5616     mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
5617     kr = thread_get_state (static_cast<thread_act_t>(thread),
5618                            x86_THREAD_STATE,
5619                            (thread_state_t) &gp_regs,
5620                            &gp_count);
5621     if (kr == KERN_SUCCESS)
5622     {
5623         if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
5624             rep << "ptrsize:8;";
5625         else
5626             rep << "ptrsize:4;";
5627     }
5628 #elif defined (__arm__)
5629     rep << "ptrsize:4;";
5630 #elif (defined (__arm64__) || defined (__aarch64__)) && defined (ARM_UNIFIED_THREAD_STATE)
5631     nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
5632     kern_return_t kr;
5633     arm_unified_thread_state_t gp_regs;
5634     mach_msg_type_number_t gp_count = ARM_UNIFIED_THREAD_STATE_COUNT;
5635     kr = thread_get_state (thread, ARM_UNIFIED_THREAD_STATE,
5636                            (thread_state_t) &gp_regs, &gp_count);
5637     if (kr == KERN_SUCCESS)
5638     {
5639         if (gp_regs.ash.flavor == ARM_THREAD_STATE64)
5640             rep << "ptrsize:8;";
5641         else
5642             rep << "ptrsize:4;";
5643     }
5644 #endif
5645 
5646     return SendPacket (rep.str());
5647 }
5648 
5649 const RNBRemote::DispatchQueueOffsets *
5650 RNBRemote::GetDispatchQueueOffsets()
5651 {
5652     if (!m_dispatch_queue_offsets.IsValid() && m_dispatch_queue_offsets_addr != INVALID_NUB_ADDRESS && m_ctx.HasValidProcessID())
5653     {
5654         nub_process_t pid = m_ctx.ProcessID();
5655         nub_size_t bytes_read = DNBProcessMemoryRead(pid, m_dispatch_queue_offsets_addr, sizeof(m_dispatch_queue_offsets), &m_dispatch_queue_offsets);
5656         if (bytes_read != sizeof(m_dispatch_queue_offsets))
5657             m_dispatch_queue_offsets.Clear();
5658     }
5659 
5660     if (m_dispatch_queue_offsets.IsValid())
5661         return &m_dispatch_queue_offsets;
5662     else
5663         return nullptr;
5664 }
5665 
5666 void
5667 RNBRemote::EnableCompressionNextSendPacket (compression_types type)
5668 {
5669     m_compression_mode = type;
5670     m_enable_compression_next_send_packet = true;
5671 }
5672 
5673 compression_types
5674 RNBRemote::GetCompressionType ()
5675 {
5676     // The first packet we send back to the debugger after a QEnableCompression request
5677     // should be uncompressed -- so we can indicate whether the compression was enabled
5678     // or not via OK / Enn returns.  After that, all packets sent will be using the
5679     // compression protocol.
5680 
5681     if (m_enable_compression_next_send_packet)
5682     {
5683         // One time, we send back "None" as our compression type
5684         m_enable_compression_next_send_packet = false;
5685         return compression_types::none;
5686     }
5687     return m_compression_mode;
5688 }
5689