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