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