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 #include "DNB.h"
24 #include "DNBLog.h"
25 #include "DNBThreadResumeActions.h"
26 #include "RNBContext.h"
27 #include "RNBServices.h"
28 #include "RNBSocket.h"
29 #include "Utility/StringExtractor.h"
30 
31 #include <iomanip>
32 #include <sstream>
33 #include <TargetConditionals.h> // for endianness predefines
34 
35 //----------------------------------------------------------------------
36 // std::iostream formatting macros
37 //----------------------------------------------------------------------
38 #define RAW_HEXBASE     std::setfill('0') << std::hex << std::right
39 #define HEXBASE         '0' << 'x' << RAW_HEXBASE
40 #define RAWHEX8(x)      RAW_HEXBASE << std::setw(2) << ((uint32_t)((uint8_t)x))
41 #define RAWHEX16        RAW_HEXBASE << std::setw(4)
42 #define RAWHEX32        RAW_HEXBASE << std::setw(8)
43 #define RAWHEX64        RAW_HEXBASE << std::setw(16)
44 #define HEX8(x)         HEXBASE << std::setw(2) << ((uint32_t)(x))
45 #define HEX16           HEXBASE << std::setw(4)
46 #define HEX32           HEXBASE << std::setw(8)
47 #define HEX64           HEXBASE << std::setw(16)
48 #define RAW_HEX(x)      RAW_HEXBASE << std::setw(sizeof(x)*2) << (x)
49 #define HEX(x)          HEXBASE << std::setw(sizeof(x)*2) << (x)
50 #define RAWHEX_SIZE(x, sz)  RAW_HEXBASE << std::setw((sz)) << (x)
51 #define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x)
52 #define STRING_WIDTH(w) std::setfill(' ') << std::setw(w)
53 #define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right
54 #define DECIMAL         std::dec << std::setfill(' ')
55 #define DECIMAL_WIDTH(w) DECIMAL << std::setw(w)
56 #define FLOAT(n, d)     std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed
57 #define INDENT_WITH_SPACES(iword_idx)   std::setfill(' ') << std::setw((iword_idx)) << ""
58 #define INDENT_WITH_TABS(iword_idx)     std::setfill('\t') << std::setw((iword_idx)) << ""
59 // Class to handle communications via gdb remote protocol.
60 
61 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
62 
63 RNBRemote::RNBRemote () :
64     m_ctx (),
65     m_comm (),
66     m_continue_thread(-1),
67     m_thread(-1),
68     m_mutex(),
69     m_packets_recvd(0),
70     m_packets(),
71     m_rx_packets(),
72     m_rx_partial_data(),
73     m_rx_pthread(0),
74     m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
75     m_extended_mode(false),
76     m_noack_mode(false),
77     m_thread_suffix_supported (false),
78     m_list_threads_in_stop_reply (false)
79 {
80     DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
81     CreatePacketTable ();
82 }
83 
84 
85 RNBRemote::~RNBRemote()
86 {
87     DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
88     StopReadRemoteDataThread();
89 }
90 
91 void
92 RNBRemote::CreatePacketTable  ()
93 {
94     // Step required to add new packets:
95     // 1 - Add new enumeration to RNBRemote::PacketEnum
96     // 2 - Create a the RNBRemote::HandlePacket_ function if a new function is needed
97     // 3 - Register the Packet definition with any needed callbacks in this function
98     //          - If no response is needed for a command, then use NULL for the normal callback
99     //          - If the packet is not supported while the target is running, use NULL for the async callback
100     // 4 - If the packet is a standard packet (starts with a '$' character
101     //      followed by the payload and then '#' and checksum, then you are done
102     //      else go on to step 5
103     // 5 - if the packet is a fixed length packet:
104     //      - modify the switch statement for the first character in the payload
105     //        in RNBRemote::CommDataReceived so it doesn't reject the new packet
106     //        type as invalid
107     //      - modify the switch statement for the first character in the payload
108     //        in RNBRemote::GetPacketPayload and make sure the payload of the packet
109     //        is returned correctly
110 
111     std::vector <Packet> &t = m_packets;
112     t.push_back (Packet (ack,                           NULL,                                   NULL, "+", "ACK"));
113     t.push_back (Packet (nack,                          NULL,                                   NULL, "-", "!ACK"));
114     t.push_back (Packet (read_memory,                   &RNBRemote::HandlePacket_m,             NULL, "m", "Read memory"));
115     t.push_back (Packet (read_register,                 &RNBRemote::HandlePacket_p,             NULL, "p", "Read one register"));
116     t.push_back (Packet (read_general_regs,             &RNBRemote::HandlePacket_g,             NULL, "g", "Read registers"));
117     t.push_back (Packet (write_memory,                  &RNBRemote::HandlePacket_M,             NULL, "M", "Write memory"));
118     t.push_back (Packet (write_register,                &RNBRemote::HandlePacket_P,             NULL, "P", "Write one register"));
119     t.push_back (Packet (write_general_regs,            &RNBRemote::HandlePacket_G,             NULL, "G", "Write registers"));
120     t.push_back (Packet (insert_mem_bp,                 &RNBRemote::HandlePacket_z,             NULL, "Z0", "Insert memory breakpoint"));
121     t.push_back (Packet (remove_mem_bp,                 &RNBRemote::HandlePacket_z,             NULL, "z0", "Remove memory breakpoint"));
122     t.push_back (Packet (single_step,                   &RNBRemote::HandlePacket_s,             NULL, "s", "Single step"));
123     t.push_back (Packet (cont,                          &RNBRemote::HandlePacket_c,             NULL, "c", "continue"));
124     t.push_back (Packet (single_step_with_sig,          &RNBRemote::HandlePacket_S,             NULL, "S", "Single step with signal"));
125     t.push_back (Packet (set_thread,                    &RNBRemote::HandlePacket_H,             NULL, "H", "Set thread"));
126     t.push_back (Packet (halt,                          &RNBRemote::HandlePacket_last_signal,   &RNBRemote::HandlePacket_stop_process, "\x03", "^C"));
127 //  t.push_back (Packet (use_extended_mode,             &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode"));
128     t.push_back (Packet (why_halted,                    &RNBRemote::HandlePacket_last_signal,   NULL, "?", "Why did target halt"));
129     t.push_back (Packet (set_argv,                      &RNBRemote::HandlePacket_A,             NULL, "A", "Set argv"));
130 //  t.push_back (Packet (set_bp,                        &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear breakpoint"));
131     t.push_back (Packet (continue_with_sig,             &RNBRemote::HandlePacket_C,             NULL, "C", "Continue with signal"));
132     t.push_back (Packet (detach,                        &RNBRemote::HandlePacket_D,             NULL, "D", "Detach gdb from remote system"));
133 //  t.push_back (Packet (step_inferior_one_cycle,       &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one clock cycle"));
134 //  t.push_back (Packet (signal_and_step_inf_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then step one clock cyle"));
135     t.push_back (Packet (kill,                          &RNBRemote::HandlePacket_k,             NULL, "k", "Kill"));
136 //  t.push_back (Packet (restart,                       &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior"));
137 //  t.push_back (Packet (search_mem_backwards,          &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards"));
138     t.push_back (Packet (thread_alive_p,                &RNBRemote::HandlePacket_T,             NULL, "T", "Is thread alive"));
139     t.push_back (Packet (vattach,                       &RNBRemote::HandlePacket_v,             NULL, "vAttach", "Attach to a new process"));
140     t.push_back (Packet (vattachwait,                   &RNBRemote::HandlePacket_v,             NULL, "vAttachWait", "Wait for a process to start up then attach to it"));
141     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"));
142     t.push_back (Packet (vattachname,                   &RNBRemote::HandlePacket_v,             NULL, "vAttachName", "Attach to an existing process by name"));
143     t.push_back (Packet (vcont_list_actions,            &RNBRemote::HandlePacket_v,             NULL, "vCont;", "Verbose resume with thread actions"));
144     t.push_back (Packet (vcont_list_actions,            &RNBRemote::HandlePacket_v,             NULL, "vCont?", "List valid continue-with-thread-actions actions"));
145     // The X packet doesn't currently work. If/when it does, remove the line above and uncomment out the line below
146 //  t.push_back (Packet (write_data_to_memory,          &RNBRemote::HandlePacket_X,             NULL, "X", "Write data to memory"));
147 //  t.push_back (Packet (insert_hardware_bp,            &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware breakpoint"));
148 //  t.push_back (Packet (remove_hardware_bp,            &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware breakpoint"));
149     t.push_back (Packet (insert_write_watch_bp,         &RNBRemote::HandlePacket_z,             NULL, "Z2", "Insert write watchpoint"));
150     t.push_back (Packet (remove_write_watch_bp,         &RNBRemote::HandlePacket_z,             NULL, "z2", "Remove write watchpoint"));
151     t.push_back (Packet (insert_read_watch_bp,          &RNBRemote::HandlePacket_z,             NULL, "Z3", "Insert read watchpoint"));
152     t.push_back (Packet (remove_read_watch_bp,          &RNBRemote::HandlePacket_z,             NULL, "z3", "Remove read watchpoint"));
153     t.push_back (Packet (insert_access_watch_bp,        &RNBRemote::HandlePacket_z,             NULL, "Z4", "Insert access watchpoint"));
154     t.push_back (Packet (remove_access_watch_bp,        &RNBRemote::HandlePacket_z,             NULL, "z4", "Remove access watchpoint"));
155     t.push_back (Packet (query_monitor,                 &RNBRemote::HandlePacket_qRcmd,          NULL, "qRcmd", "Monitor command"));
156     t.push_back (Packet (query_current_thread_id,       &RNBRemote::HandlePacket_qC,            NULL, "qC", "Query current thread ID"));
157     t.push_back (Packet (query_get_pid,                 &RNBRemote::HandlePacket_qGetPid,       NULL, "qGetPid", "Query process id"));
158     t.push_back (Packet (query_thread_ids_first,        &RNBRemote::HandlePacket_qThreadInfo,   NULL, "qfThreadInfo", "Get list of active threads (first req)"));
159     t.push_back (Packet (query_thread_ids_subsequent,   &RNBRemote::HandlePacket_qThreadInfo,   NULL, "qsThreadInfo", "Get list of active threads (subsequent req)"));
160     // APPLE LOCAL: qThreadStopInfo
161     // syntax: qThreadStopInfoTTTT
162     //  TTTT is hex thread ID
163     t.push_back (Packet (query_thread_stop_info,        &RNBRemote::HandlePacket_qThreadStopInfo,   NULL, "qThreadStopInfo", "Get detailed info on why the specified thread stopped"));
164     t.push_back (Packet (query_thread_extra_info,       &RNBRemote::HandlePacket_qThreadExtraInfo,NULL, "qThreadExtraInfo", "Get printable status of a thread"));
165 //  t.push_back (Packet (query_image_offsets,           &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qOffsets", "Report offset of loaded program"));
166     t.push_back (Packet (query_launch_success,          &RNBRemote::HandlePacket_qLaunchSuccess,NULL, "qLaunchSuccess", "Report the success or failure of the launch attempt"));
167     t.push_back (Packet (query_register_info,           &RNBRemote::HandlePacket_qRegisterInfo, NULL, "qRegisterInfo", "Dynamically discover remote register context information."));
168     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"));
169     t.push_back (Packet (query_step_packet_supported,   &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported."));
170     t.push_back (Packet (query_vattachorwait_supported, &RNBRemote::HandlePacket_qVAttachOrWaitSupported,NULL, "qVAttachOrWaitSupported", "Replys with OK if the 'vAttachOrWait' packet is supported."));
171     t.push_back (Packet (query_sync_thread_state_supported, &RNBRemote::HandlePacket_qSyncThreadStateSupported,NULL, "qSyncThreadStateSupported", "Replys with OK if the 'QSyncThreadState:' packet is supported."));
172     t.push_back (Packet (query_host_info,               &RNBRemote::HandlePacket_qHostInfo,     NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
173     t.push_back (Packet (query_gdb_server_version,      &RNBRemote::HandlePacket_qGDBServerVersion,       NULL, "qGDBServerVersion", "Replies with multiple 'key:value;' tuples appended to each other."));
174     t.push_back (Packet (query_process_info,            &RNBRemote::HandlePacket_qProcessInfo,     NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
175 //  t.push_back (Packet (query_symbol_lookup,           &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups"));
176     t.push_back (Packet (start_noack_mode,              &RNBRemote::HandlePacket_QStartNoAckMode        , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
177     t.push_back (Packet (prefix_reg_packets_with_tid,   &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
178     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"));
179     t.push_back (Packet (set_max_packet_size,           &RNBRemote::HandlePacket_QSetMaxPacketSize      , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
180     t.push_back (Packet (set_max_payload_size,          &RNBRemote::HandlePacket_QSetMaxPayloadSize     , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
181     t.push_back (Packet (set_environment_variable,      &RNBRemote::HandlePacket_QEnvironment           , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
182     t.push_back (Packet (set_environment_variable_hex,  &RNBRemote::HandlePacket_QEnvironmentHexEncoded , NULL, "QEnvironmentHexEncoded:", "Add an environment variable to the inferior's environment"));
183     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."));
184     t.push_back (Packet (set_disable_aslr,              &RNBRemote::HandlePacket_QSetDisableASLR        , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
185     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"));
186     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"));
187     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"));
188     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"));
189     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."));
190     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."));
191 //  t.push_back (Packet (pass_signals_to_inferior,      &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
192     t.push_back (Packet (allocate_memory,               &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
193     t.push_back (Packet (deallocate_memory,             &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
194     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."));
195     t.push_back (Packet (restore_register_state,        &RNBRemote::HandlePacket_RestoreRegisterState, NULL, "QRestoreRegisterState:", "Restore the register state given a save ID previosly returned from a call to QSaveRegisterState."));
196     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"));
197     t.push_back (Packet (get_profile_data,              &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target."));
198     t.push_back (Packet (set_enable_profiling,          &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "Enable or disable the profiling of current target."));
199     t.push_back (Packet (watchpoint_support_info,       &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints"));
200     t.push_back (Packet (speed_test,                    &RNBRemote::HandlePacket_qSpeedTest, NULL, "qSpeedTest:", "Test the maximum speed at which packet can be sent/received."));
201 }
202 
203 
204 void
205 RNBRemote::FlushSTDIO ()
206 {
207     if (m_ctx.HasValidProcessID())
208     {
209         nub_process_t pid = m_ctx.ProcessID();
210         char buf[256];
211         nub_size_t count;
212         do
213         {
214             count = DNBProcessGetAvailableSTDOUT(pid, buf, sizeof(buf));
215             if (count > 0)
216             {
217                 SendSTDOUTPacket (buf, count);
218             }
219         } while (count > 0);
220 
221         do
222         {
223             count = DNBProcessGetAvailableSTDERR(pid, buf, sizeof(buf));
224             if (count > 0)
225             {
226                 SendSTDERRPacket (buf, count);
227             }
228         } while (count > 0);
229     }
230 }
231 
232 void
233 RNBRemote::SendAsyncProfileData ()
234 {
235     if (m_ctx.HasValidProcessID())
236     {
237         nub_process_t pid = m_ctx.ProcessID();
238         char buf[1024];
239         nub_size_t count;
240         do
241         {
242             count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf));
243             if (count > 0)
244             {
245                 SendAsyncProfileDataPacket (buf, count);
246             }
247         } while (count > 0);
248     }
249 }
250 
251 rnb_err_t
252 RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer)
253 {
254     std::ostringstream packet_sstrm;
255     // Append the header cstr if there was one
256     if (header && header[0])
257         packet_sstrm << header;
258     nub_size_t i;
259     const uint8_t *ubuf8 = (const uint8_t *)buf;
260     for (i=0; i<buf_len; i++)
261     {
262         packet_sstrm << RAWHEX8(ubuf8[i]);
263     }
264     // Append the footer cstr if there was one
265     if (footer && footer[0])
266         packet_sstrm << footer;
267 
268     return SendPacket(packet_sstrm.str());
269 }
270 
271 rnb_err_t
272 RNBRemote::SendSTDOUTPacket (char *buf, nub_size_t buf_size)
273 {
274     if (buf_size == 0)
275         return rnb_success;
276     return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
277 }
278 
279 rnb_err_t
280 RNBRemote::SendSTDERRPacket (char *buf, nub_size_t buf_size)
281 {
282     if (buf_size == 0)
283         return rnb_success;
284     return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
285 }
286 
287 // This makes use of asynchronous bit 'A' in the gdb remote protocol.
288 rnb_err_t
289 RNBRemote::SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size)
290 {
291     if (buf_size == 0)
292         return rnb_success;
293 
294     std::string packet("A");
295     packet.append(buf, buf_size);
296     return SendPacket(packet);
297 }
298 
299 rnb_err_t
300 RNBRemote::SendPacket (const std::string &s)
301 {
302     DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s (%s) called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, s.c_str());
303     std::string sendpacket = "$" + s + "#";
304     int cksum = 0;
305     char hexbuf[5];
306 
307     if (m_noack_mode)
308     {
309         sendpacket += "00";
310     }
311     else
312     {
313         for (int i = 0; i != s.size(); ++i)
314             cksum += s[i];
315         snprintf (hexbuf, sizeof hexbuf, "%02x", cksum & 0xff);
316         sendpacket += hexbuf;
317     }
318 
319     rnb_err_t err = m_comm.Write (sendpacket.c_str(), sendpacket.size());
320     if (err != rnb_success)
321         return err;
322 
323     if (m_noack_mode)
324         return rnb_success;
325 
326     std::string reply;
327     RNBRemote::Packet packet;
328     err = GetPacket (reply, packet, true);
329 
330     if (err != rnb_success)
331     {
332         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());
333         return err;
334     }
335 
336     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());
337 
338     if (packet.type == ack)
339         return rnb_success;
340 
341     // Should we try to resend the packet at this layer?
342     //  if (packet.command == nack)
343     return rnb_err;
344 }
345 
346 /* Get a packet via gdb remote protocol.
347  Strip off the prefix/suffix, verify the checksum to make sure
348  a valid packet was received, send an ACK if they match.  */
349 
350 rnb_err_t
351 RNBRemote::GetPacketPayload (std::string &return_packet)
352 {
353     //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
354 
355     PThreadMutex::Locker locker(m_mutex);
356     if (m_rx_packets.empty())
357     {
358         // Only reset the remote command available event if we have no more packets
359         m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available );
360         //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s error: no packets available...", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
361         return rnb_err;
362     }
363 
364     //DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s has %u queued packets", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, m_rx_packets.size());
365     return_packet.swap(m_rx_packets.front());
366     m_rx_packets.pop_front();
367     locker.Reset(); // Release our lock on the mutex
368 
369     if (m_rx_packets.empty())
370     {
371         // Reset the remote command available event if we have no more packets
372         m_ctx.Events().ResetEvents ( RNBContext::event_read_packet_available );
373     }
374 
375     //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s: '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
376 
377     switch (return_packet[0])
378     {
379         case '+':
380         case '-':
381         case '\x03':
382             break;
383 
384         case '$':
385         {
386             int packet_checksum = 0;
387             if (!m_noack_mode)
388             {
389                 for (int i = return_packet.size() - 2; i < return_packet.size(); ++i)
390                 {
391                     char checksum_char = tolower (return_packet[i]);
392                     if (!isxdigit (checksum_char))
393                     {
394                         m_comm.Write ("-", 1);
395                         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());
396                         return rnb_err;
397                     }
398                 }
399                 packet_checksum = strtol (&return_packet[return_packet.size() - 2], NULL, 16);
400             }
401 
402             return_packet.erase(0,1);           // Strip the leading '$'
403             return_packet.erase(return_packet.size() - 3);// Strip the #XX checksum
404 
405             if (!m_noack_mode)
406             {
407                 // Compute the checksum
408                 int computed_checksum = 0;
409                 for (std::string::iterator it = return_packet.begin ();
410                      it != return_packet.end ();
411                      ++it)
412                 {
413                     computed_checksum += *it;
414                 }
415 
416                 if (packet_checksum == (computed_checksum & 0xff))
417                 {
418                     //DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s'", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
419                     m_comm.Write ("+", 1);
420                 }
421                 else
422                 {
423                     DNBLogThreadedIf (LOG_RNB_MEDIUM, "%8u RNBRemote::%s sending ACK for '%s' (error: packet checksum mismatch  (0x%2.2x != 0x%2.2x))",
424                                       (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true),
425                                       __FUNCTION__,
426                                       return_packet.c_str(),
427                                       packet_checksum,
428                                       computed_checksum);
429                     m_comm.Write ("-", 1);
430                     return rnb_err;
431                 }
432             }
433         }
434         break;
435 
436         default:
437             DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s tossing unexpected packet???? %s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, return_packet.c_str());
438             if (!m_noack_mode)
439                 m_comm.Write ("-", 1);
440             return rnb_err;
441     }
442 
443     return rnb_success;
444 }
445 
446 rnb_err_t
447 RNBRemote::HandlePacket_UNIMPLEMENTED (const char* p)
448 {
449     DNBLogThreadedIf (LOG_RNB_MAX, "%8u RNBRemote::%s(\"%s\")", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p ? p : "NULL");
450     return SendPacket ("");
451 }
452 
453 rnb_err_t
454 RNBRemote::HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description)
455 {
456     DNBLogThreadedIf (LOG_RNB_PACKETS, "%8u %s:%i ILLFORMED: '%s' (%s)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), file, line, __FUNCTION__, p);
457     return SendPacket ("E03");
458 }
459 
460 rnb_err_t
461 RNBRemote::GetPacket (std::string &packet_payload, RNBRemote::Packet& packet_info, bool wait)
462 {
463     std::string payload;
464     rnb_err_t err = GetPacketPayload (payload);
465     if (err != rnb_success)
466     {
467         PThreadEvent& events = m_ctx.Events();
468         nub_event_t set_events = events.GetEventBits();
469         // TODO: add timeout version of GetPacket?? We would then need to pass
470         // that timeout value along to DNBProcessTimedWaitForEvent.
471         if (!wait || ((set_events & RNBContext::event_read_thread_running) == 0))
472             return err;
473 
474         const nub_event_t events_to_wait_for = RNBContext::event_read_packet_available | RNBContext::event_read_thread_exiting;
475 
476         while ((set_events = events.WaitForSetEvents(events_to_wait_for)) != 0)
477         {
478             if (set_events & RNBContext::event_read_packet_available)
479             {
480                 // Try the queue again now that we got an event
481                 err = GetPacketPayload (payload);
482                 if (err == rnb_success)
483                     break;
484             }
485 
486             if (set_events & RNBContext::event_read_thread_exiting)
487                 err = rnb_not_connected;
488 
489             if (err == rnb_not_connected)
490                 return err;
491 
492         } while (err == rnb_err);
493 
494         if (set_events == 0)
495             err = rnb_not_connected;
496     }
497 
498     if (err == rnb_success)
499     {
500         Packet::iterator it;
501         for (it = m_packets.begin (); it != m_packets.end (); ++it)
502         {
503             if (payload.compare (0, it->abbrev.size(), it->abbrev) == 0)
504                 break;
505         }
506 
507         // A packet we don't have an entry for. This can happen when we
508         // get a packet that we don't know about or support. We just reply
509         // accordingly and go on.
510         if (it == m_packets.end ())
511         {
512             DNBLogThreadedIf (LOG_RNB_PACKETS, "unimplemented packet: '%s'", payload.c_str());
513             HandlePacket_UNIMPLEMENTED(payload.c_str());
514             return rnb_err;
515         }
516         else
517         {
518             packet_info = *it;
519             packet_payload = payload;
520         }
521     }
522     return err;
523 }
524 
525 rnb_err_t
526 RNBRemote::HandleAsyncPacket(PacketEnum *type)
527 {
528     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
529     static DNBTimer g_packetTimer(true);
530     rnb_err_t err = rnb_err;
531     std::string packet_data;
532     RNBRemote::Packet packet_info;
533     err = GetPacket (packet_data, packet_info, false);
534 
535     if (err == rnb_success)
536     {
537         if (!packet_data.empty() && isprint(packet_data[0]))
538             DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (\"%s\");", packet_data.c_str());
539         else
540             DNBLogThreadedIf (LOG_RNB_REMOTE | LOG_RNB_PACKETS, "HandleAsyncPacket (%s);", packet_info.printable_name.c_str());
541 
542         HandlePacketCallback packet_callback = packet_info.async;
543         if (packet_callback != NULL)
544         {
545             if (type != NULL)
546                 *type = packet_info.type;
547             return (this->*packet_callback)(packet_data.c_str());
548         }
549     }
550 
551     return err;
552 }
553 
554 rnb_err_t
555 RNBRemote::HandleReceivedPacket(PacketEnum *type)
556 {
557     static DNBTimer g_packetTimer(true);
558 
559     //  DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
560     rnb_err_t err = rnb_err;
561     std::string packet_data;
562     RNBRemote::Packet packet_info;
563     err = GetPacket (packet_data, packet_info, false);
564 
565     if (err == rnb_success)
566     {
567         DNBLogThreadedIf (LOG_RNB_REMOTE, "HandleReceivedPacket (\"%s\");", packet_data.c_str());
568         HandlePacketCallback packet_callback = packet_info.normal;
569         if (packet_callback != NULL)
570         {
571             if (type != NULL)
572                 *type = packet_info.type;
573             return (this->*packet_callback)(packet_data.c_str());
574         }
575         else
576         {
577             // Do not fall through to end of this function, if we have valid
578             // packet_info and it has a NULL callback, then we need to respect
579             // that it may not want any response or anything to be done.
580             return err;
581         }
582     }
583     return rnb_err;
584 }
585 
586 void
587 RNBRemote::CommDataReceived(const std::string& new_data)
588 {
589     //  DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
590     {
591         // Put the packet data into the buffer in a thread safe fashion
592         PThreadMutex::Locker locker(m_mutex);
593 
594         std::string data;
595         // See if we have any left over data from a previous call to this
596         // function?
597         if (!m_rx_partial_data.empty())
598         {
599             // We do, so lets start with that data
600             data.swap(m_rx_partial_data);
601         }
602         // Append the new incoming data
603         data += new_data;
604 
605         // Parse up the packets into gdb remote packets
606         uint32_t idx = 0;
607         const size_t data_size = data.size();
608 
609         while (idx < data_size)
610         {
611             // end_idx must be one past the last valid packet byte. Start
612             // it off with an invalid value that is the same as the current
613             // index.
614             size_t end_idx = idx;
615 
616             switch (data[idx])
617             {
618                 case '+':       // Look for ack
619                 case '-':       // Look for cancel
620                 case '\x03':    // ^C to halt target
621                     end_idx = idx + 1;  // The command is one byte long...
622                     break;
623 
624                 case '$':
625                     // Look for a standard gdb packet?
626                     end_idx = data.find('#',  idx + 1);
627                     if (end_idx == std::string::npos || end_idx + 3 > data_size)
628                     {
629                         end_idx = std::string::npos;
630                     }
631                     else
632                     {
633                         // Add two for the checksum bytes and 1 to point to the
634                         // byte just past the end of this packet
635                         end_idx += 3;
636                     }
637                     break;
638 
639                 default:
640                     break;
641             }
642 
643             if (end_idx == std::string::npos)
644             {
645                 // Not all data may be here for the packet yet, save it for
646                 // next time through this function.
647                 m_rx_partial_data += data.substr(idx);
648                 //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());
649                 idx = end_idx;
650             }
651             else
652                 if (idx < end_idx)
653                 {
654                     m_packets_recvd++;
655                     // Hack to get rid of initial '+' ACK???
656                     if (m_packets_recvd == 1 && (end_idx == idx + 1) && data[idx] == '+')
657                     {
658                         //DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s throwing first ACK away....[%u, npos): '+'",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, idx);
659                     }
660                     else
661                     {
662                         // We have a valid packet...
663                         m_rx_packets.push_back(data.substr(idx, end_idx - idx));
664                         DNBLogThreadedIf (LOG_RNB_PACKETS, "getpkt: %s", m_rx_packets.back().c_str());
665                     }
666                     idx = end_idx;
667                 }
668                 else
669                 {
670                     DNBLogThreadedIf (LOG_RNB_MAX, "%8d RNBRemote::%s tossing junk byte at %c",(uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, data[idx]);
671                     idx = idx + 1;
672                 }
673         }
674     }
675 
676     if (!m_rx_packets.empty())
677     {
678         // Let the main thread know we have received a packet
679 
680         //DNBLogThreadedIf (LOG_RNB_EVENTS, "%8d RNBRemote::%s   called events.SetEvent(RNBContext::event_read_packet_available)", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
681         PThreadEvent& events = m_ctx.Events();
682         events.SetEvents (RNBContext::event_read_packet_available);
683     }
684 }
685 
686 rnb_err_t
687 RNBRemote::GetCommData ()
688 {
689     //  DNBLogThreadedIf (LOG_RNB_REMOTE, "%8d RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
690     std::string comm_data;
691     rnb_err_t err = m_comm.Read (comm_data);
692     if (err == rnb_success)
693     {
694         if (!comm_data.empty())
695             CommDataReceived (comm_data);
696     }
697     return err;
698 }
699 
700 void
701 RNBRemote::StartReadRemoteDataThread()
702 {
703     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
704     PThreadEvent& events = m_ctx.Events();
705     if ((events.GetEventBits() & RNBContext::event_read_thread_running) == 0)
706     {
707         events.ResetEvents (RNBContext::event_read_thread_exiting);
708         int err = ::pthread_create (&m_rx_pthread, NULL, ThreadFunctionReadRemoteData, this);
709         if (err == 0)
710         {
711             // Our thread was successfully kicked off, wait for it to
712             // set the started event so we can safely continue
713             events.WaitForSetEvents (RNBContext::event_read_thread_running);
714         }
715         else
716         {
717             events.ResetEvents (RNBContext::event_read_thread_running);
718             events.SetEvents (RNBContext::event_read_thread_exiting);
719         }
720     }
721 }
722 
723 void
724 RNBRemote::StopReadRemoteDataThread()
725 {
726     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s called", (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__);
727     PThreadEvent& events = m_ctx.Events();
728     if ((events.GetEventBits() & RNBContext::event_read_thread_running) == RNBContext::event_read_thread_running)
729     {
730         m_comm.Disconnect(true);
731         struct timespec timeout_abstime;
732         DNBTimer::OffsetTimeOfDay(&timeout_abstime, 2, 0);
733 
734         // Wait for 2 seconds for the remote data thread to exit
735         if (events.WaitForSetEvents(RNBContext::event_read_thread_exiting, &timeout_abstime) == 0)
736         {
737             // Kill the remote data thread???
738         }
739     }
740 }
741 
742 
743 void*
744 RNBRemote::ThreadFunctionReadRemoteData(void *arg)
745 {
746     // Keep a shared pointer reference so this doesn't go away on us before the thread is killed.
747     DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread starting...", __FUNCTION__, arg);
748     RNBRemoteSP remoteSP(g_remoteSP);
749     if (remoteSP.get() != NULL)
750     {
751         RNBRemote* remote = remoteSP.get();
752         PThreadEvent& events = remote->Context().Events();
753         events.SetEvents (RNBContext::event_read_thread_running);
754         // START: main receive remote command thread loop
755         bool done = false;
756         while (!done)
757         {
758             rnb_err_t err = remote->GetCommData();
759 
760             switch (err)
761             {
762                 case rnb_success:
763                     break;
764 
765                 default:
766                 case rnb_err:
767                     DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err);
768                     done = true;
769                     break;
770 
771                 case rnb_not_connected:
772                     DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned not connected...");
773                     done = true;
774                     break;
775             }
776         }
777         // START: main receive remote command thread loop
778         events.ResetEvents (RNBContext::event_read_thread_running);
779         events.SetEvents (RNBContext::event_read_thread_exiting);
780     }
781     DNBLogThreadedIf(LOG_RNB_REMOTE, "RNBRemote::%s (%p): thread exiting...", __FUNCTION__, arg);
782     return NULL;
783 }
784 
785 
786 // If we fail to get back a valid CPU type for the remote process,
787 // make a best guess for the CPU type based on the currently running
788 // debugserver binary -- the debugger may not handle the case of an
789 // un-specified process CPU type correctly.
790 
791 static cpu_type_t
792 best_guess_cpu_type ()
793 {
794 #if defined (__arm__)
795     return CPU_TYPE_ARM;
796 #elif defined (__i386__) || defined (__x86_64__)
797     if (sizeof (char*) == 8)
798     {
799         return CPU_TYPE_X86_64;
800     }
801     else
802     {
803         return CPU_TYPE_I386;
804     }
805 #endif
806     return 0;
807 }
808 
809 
810 /* Read the bytes in STR which are GDB Remote Protocol binary encoded bytes
811  (8-bit bytes).
812  This encoding uses 0x7d ('}') as an escape character for 0x7d ('}'),
813  0x23 ('#'), and 0x24 ('$').
814  LEN is the number of bytes to be processed.  If a character is escaped,
815  it is 2 characters for LEN.  A LEN of -1 means encode-until-nul-byte
816  (end of string).  */
817 
818 std::vector<uint8_t>
819 decode_binary_data (const char *str, size_t len)
820 {
821     std::vector<uint8_t> bytes;
822     if (len == 0)
823     {
824         return bytes;
825     }
826     if (len == -1)
827         len = strlen (str);
828 
829     while (len--)
830     {
831         unsigned char c = *str;
832         if (c == 0x7d && len > 0)
833         {
834             len--;
835             str++;
836             c ^= 0x20;
837         }
838         bytes.push_back (c);
839     }
840     return bytes;
841 }
842 
843 typedef struct register_map_entry
844 {
845     uint32_t        gdb_regnum; // gdb register number
846     uint32_t        offset;     // Offset in bytes into the register context data with no padding between register values
847     DNBRegisterInfo nub_info;   // debugnub register info
848     std::vector<uint32_t> value_regnums;
849     std::vector<uint32_t> invalidate_regnums;
850 } register_map_entry_t;
851 
852 
853 
854 // If the notion of registers differs from what is handed out by the
855 // architecture, then flavors can be defined here.
856 
857 static const uint32_t MAX_REGISTER_BYTE_SIZE = 16;
858 static const uint8_t k_zero_bytes[MAX_REGISTER_BYTE_SIZE] = {0};
859 static std::vector<register_map_entry_t> g_dynamic_register_map;
860 static register_map_entry_t *g_reg_entries = NULL;
861 static size_t g_num_reg_entries = 0;
862 
863 void
864 RNBRemote::Initialize()
865 {
866     DNBInitialize();
867 }
868 
869 
870 bool
871 RNBRemote::InitializeRegisters (bool force)
872 {
873     pid_t pid = m_ctx.ProcessID();
874     if (pid == INVALID_NUB_PROCESS)
875         return false;
876 
877     DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface", __FUNCTION__);
878     // Discover the registers by querying the DNB interface and letting it
879     // state the registers that it would like to export. This allows the
880     // registers to be discovered using multiple qRegisterInfo calls to get
881     // all register information after the architecture for the process is
882     // determined.
883     if (force)
884     {
885         g_dynamic_register_map.clear();
886         g_reg_entries = NULL;
887         g_num_reg_entries = 0;
888     }
889 
890     if (g_dynamic_register_map.empty())
891     {
892         nub_size_t num_reg_sets = 0;
893         const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
894 
895         assert (num_reg_sets > 0 && reg_sets != NULL);
896 
897         uint32_t regnum = 0;
898         uint32_t reg_data_offset = 0;
899         typedef std::map<std::string, uint32_t> NameToRegNum;
900         NameToRegNum name_to_regnum;
901         for (nub_size_t set = 0; set < num_reg_sets; ++set)
902         {
903             if (reg_sets[set].registers == NULL)
904                 continue;
905 
906             for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
907             {
908                 register_map_entry_t reg_entry = {
909                     regnum++,                           // register number starts at zero and goes up with no gaps
910                     reg_data_offset,                    // Offset into register context data, no gaps between registers
911                     reg_sets[set].registers[reg]        // DNBRegisterInfo
912                 };
913 
914                 name_to_regnum[reg_entry.nub_info.name] = reg_entry.gdb_regnum;
915 
916                 if (reg_entry.nub_info.value_regs == NULL)
917                 {
918                     reg_data_offset += reg_entry.nub_info.size;
919                 }
920 
921                 g_dynamic_register_map.push_back (reg_entry);
922             }
923         }
924 
925         // Now we must find any regsiters whose values are in other registers and fix up
926         // the offsets since we removed all gaps...
927         for (auto &reg_entry: g_dynamic_register_map)
928         {
929             if (reg_entry.nub_info.value_regs)
930             {
931                 uint32_t new_offset = UINT32_MAX;
932                 for (size_t i=0; reg_entry.nub_info.value_regs[i] != NULL; ++i)
933                 {
934                     const char *name = reg_entry.nub_info.value_regs[i];
935                     auto pos = name_to_regnum.find(name);
936                     if (pos != name_to_regnum.end())
937                     {
938                         regnum = pos->second;
939                         reg_entry.value_regnums.push_back(regnum);
940                         if (regnum < g_dynamic_register_map.size())
941                         {
942                             // The offset for value_regs registers is the offset within the register with the lowest offset
943                             const uint32_t reg_offset = g_dynamic_register_map[regnum].offset + reg_entry.nub_info.offset;
944                             if (new_offset > reg_offset)
945                                 new_offset = reg_offset;
946                         }
947                     }
948                 }
949 
950                 if (new_offset != UINT32_MAX)
951                 {
952                     reg_entry.offset = new_offset;
953                 }
954                 else
955                 {
956                     DNBLogThreaded("no offset was calculated entry for register %s", reg_entry.nub_info.name);
957                     reg_entry.offset = UINT32_MAX;
958                 }
959             }
960 
961             if (reg_entry.nub_info.update_regs)
962             {
963                 for (size_t i=0; reg_entry.nub_info.update_regs[i] != NULL; ++i)
964                 {
965                     const char *name = reg_entry.nub_info.update_regs[i];
966                     auto pos = name_to_regnum.find(name);
967                     if (pos != name_to_regnum.end())
968                     {
969                         regnum = pos->second;
970                         reg_entry.invalidate_regnums.push_back(regnum);
971                     }
972                 }
973             }
974         }
975 
976 
977 //        for (auto &reg_entry: g_dynamic_register_map)
978 //        {
979 //            DNBLogThreaded("%4i: size = %3u, pseudo = %i, name = %s",
980 //                           reg_entry.offset,
981 //                           reg_entry.nub_info.size,
982 //                           reg_entry.nub_info.value_regs != NULL,
983 //                           reg_entry.nub_info.name);
984 //        }
985 
986         g_reg_entries = g_dynamic_register_map.data();
987         g_num_reg_entries = g_dynamic_register_map.size();
988     }
989     return true;
990 }
991 
992 /* The inferior has stopped executing; send a packet
993  to gdb to let it know.  */
994 
995 void
996 RNBRemote::NotifyThatProcessStopped (void)
997 {
998     RNBRemote::HandlePacket_last_signal (NULL);
999     return;
1000 }
1001 
1002 
1003 /* 'A arglen,argnum,arg,...'
1004  Update the inferior context CTX with the program name and arg
1005  list.
1006  The documentation for this packet is underwhelming but my best reading
1007  of this is that it is a series of (len, position #, arg)'s, one for
1008  each argument with "arg" hex encoded (two 0-9a-f chars?).
1009  Why we need BOTH a "len" and a hex encoded "arg" is beyond me - either
1010  is sufficient to get around the "," position separator escape issue.
1011 
1012  e.g. our best guess for a valid 'A' packet for "gdb -q a.out" is
1013 
1014  6,0,676462,4,1,2d71,10,2,612e6f7574
1015 
1016  Note that "argnum" and "arglen" are numbers in base 10.  Again, that's
1017  not documented either way but I'm assuming it's so.  */
1018 
1019 rnb_err_t
1020 RNBRemote::HandlePacket_A (const char *p)
1021 {
1022     if (p == NULL || *p == '\0')
1023     {
1024         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Null packet for 'A' pkt");
1025     }
1026     p++;
1027     if (*p == '\0' || !isdigit (*p))
1028     {
1029         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not specified on 'A' pkt");
1030     }
1031 
1032     /* I promise I don't modify it anywhere in this function.  strtoul()'s
1033      2nd arg has to be non-const which makes it problematic to step
1034      through the string easily.  */
1035     char *buf = const_cast<char *>(p);
1036 
1037     RNBContext& ctx = Context();
1038 
1039     while (*buf != '\0')
1040     {
1041         int arglen, argnum;
1042         std::string arg;
1043         char *c;
1044 
1045         errno = 0;
1046         arglen = strtoul (buf, &c, 10);
1047         if (errno != 0 && arglen == 0)
1048         {
1049             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not a number on 'A' pkt");
1050         }
1051         if (*c != ',')
1052         {
1053             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
1054         }
1055         buf = c + 1;
1056 
1057         errno = 0;
1058         argnum = strtoul (buf, &c, 10);
1059         if (errno != 0 && argnum == 0)
1060         {
1061             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "argnum not a number on 'A' pkt");
1062         }
1063         if (*c != ',')
1064         {
1065             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "arglen not followed by comma on 'A' pkt");
1066         }
1067         buf = c + 1;
1068 
1069         c = buf;
1070         buf = buf + arglen;
1071         while (c < buf && *c != '\0' && c + 1 < buf && *(c + 1) != '\0')
1072         {
1073             char smallbuf[3];
1074             smallbuf[0] = *c;
1075             smallbuf[1] = *(c + 1);
1076             smallbuf[2] = '\0';
1077 
1078             errno = 0;
1079             int ch = strtoul (smallbuf, NULL, 16);
1080             if (errno != 0 && ch == 0)
1081             {
1082                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'A' pkt");
1083             }
1084 
1085             arg.push_back(ch);
1086             c += 2;
1087         }
1088 
1089         ctx.PushArgument (arg.c_str());
1090         if (*buf == ',')
1091             buf++;
1092     }
1093     SendPacket ("OK");
1094 
1095     return rnb_success;
1096 }
1097 
1098 /* 'H c t'
1099  Set the thread for subsequent actions; 'c' for step/continue ops,
1100  'g' for other ops.  -1 means all threads, 0 means any thread.  */
1101 
1102 rnb_err_t
1103 RNBRemote::HandlePacket_H (const char *p)
1104 {
1105     p++;  // skip 'H'
1106     if (*p != 'c' && *p != 'g')
1107     {
1108         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing 'c' or 'g' type in H packet");
1109     }
1110 
1111     if (!m_ctx.HasValidProcessID())
1112     {
1113         // We allow gdb to connect to a server that hasn't started running
1114         // the target yet.  gdb still wants to ask questions about it and
1115         // freaks out if it gets an error.  So just return OK here.
1116     }
1117 
1118     errno = 0;
1119     nub_thread_t tid = strtoul (p + 1, NULL, 16);
1120     if (errno != 0 && tid == 0)
1121     {
1122         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in H packet");
1123     }
1124     if (*p == 'c')
1125         SetContinueThread (tid);
1126     if (*p == 'g')
1127         SetCurrentThread (tid);
1128 
1129     return SendPacket ("OK");
1130 }
1131 
1132 
1133 rnb_err_t
1134 RNBRemote::HandlePacket_qLaunchSuccess (const char *p)
1135 {
1136     if (m_ctx.HasValidProcessID() || m_ctx.LaunchStatus().Error() == 0)
1137         return SendPacket("OK");
1138     std::ostringstream ret_str;
1139     std::string status_str;
1140     ret_str << "E" << m_ctx.LaunchStatusAsString(status_str);
1141 
1142     return SendPacket (ret_str.str());
1143 }
1144 
1145 rnb_err_t
1146 RNBRemote::HandlePacket_qShlibInfoAddr (const char *p)
1147 {
1148     if (m_ctx.HasValidProcessID())
1149     {
1150         nub_addr_t shlib_info_addr = DNBProcessGetSharedLibraryInfoAddress(m_ctx.ProcessID());
1151         if (shlib_info_addr != INVALID_NUB_ADDRESS)
1152         {
1153             std::ostringstream ostrm;
1154             ostrm << RAW_HEXBASE << shlib_info_addr;
1155             return SendPacket (ostrm.str ());
1156         }
1157     }
1158     return SendPacket ("E44");
1159 }
1160 
1161 rnb_err_t
1162 RNBRemote::HandlePacket_qStepPacketSupported (const char *p)
1163 {
1164     // Normally the "s" packet is mandatory, yet in gdb when using ARM, they
1165     // get around the need for this packet by implementing software single
1166     // stepping from gdb. Current versions of debugserver do support the "s"
1167     // packet, yet some older versions do not. We need a way to tell if this
1168     // packet is supported so we can disable software single stepping in gdb
1169     // for remote targets (so the "s" packet will get used).
1170     return SendPacket("OK");
1171 }
1172 
1173 rnb_err_t
1174 RNBRemote::HandlePacket_qSyncThreadStateSupported (const char *p)
1175 {
1176     // We support attachOrWait meaning attach if the process exists, otherwise wait to attach.
1177     return SendPacket("OK");
1178 }
1179 
1180 rnb_err_t
1181 RNBRemote::HandlePacket_qVAttachOrWaitSupported (const char *p)
1182 {
1183     // We support attachOrWait meaning attach if the process exists, otherwise wait to attach.
1184     return SendPacket("OK");
1185 }
1186 
1187 rnb_err_t
1188 RNBRemote::HandlePacket_qThreadStopInfo (const char *p)
1189 {
1190     p += strlen ("qThreadStopInfo");
1191     nub_thread_t tid = strtoul(p, 0, 16);
1192     return SendStopReplyPacketForThread (tid);
1193 }
1194 
1195 rnb_err_t
1196 RNBRemote::HandlePacket_qThreadInfo (const char *p)
1197 {
1198     // We allow gdb to connect to a server that hasn't started running
1199     // the target yet.  gdb still wants to ask questions about it and
1200     // freaks out if it gets an error.  So just return OK here.
1201     nub_process_t pid = m_ctx.ProcessID();
1202     if (pid == INVALID_NUB_PROCESS)
1203         return SendPacket ("OK");
1204 
1205     // Only "qfThreadInfo" and "qsThreadInfo" get into this function so
1206     // we only need to check the second byte to tell which is which
1207     if (p[1] == 'f')
1208     {
1209         nub_size_t numthreads = DNBProcessGetNumThreads (pid);
1210         std::ostringstream ostrm;
1211         ostrm << "m";
1212         bool first = true;
1213         for (nub_size_t i = 0; i < numthreads; ++i)
1214         {
1215             if (first)
1216                 first = false;
1217             else
1218                 ostrm << ",";
1219             nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
1220             ostrm << std::hex << th;
1221         }
1222         return SendPacket (ostrm.str ());
1223     }
1224     else
1225     {
1226         return SendPacket ("l");
1227     }
1228 }
1229 
1230 rnb_err_t
1231 RNBRemote::HandlePacket_qThreadExtraInfo (const char *p)
1232 {
1233     // We allow gdb to connect to a server that hasn't started running
1234     // the target yet.  gdb still wants to ask questions about it and
1235     // freaks out if it gets an error.  So just return OK here.
1236     nub_process_t pid = m_ctx.ProcessID();
1237     if (pid == INVALID_NUB_PROCESS)
1238         return SendPacket ("OK");
1239 
1240     /* This is supposed to return a string like 'Runnable' or
1241      'Blocked on Mutex'.
1242      The returned string is formatted like the "A" packet - a
1243      sequence of letters encoded in as 2-hex-chars-per-letter.  */
1244     p += strlen ("qThreadExtraInfo");
1245     if (*p++ != ',')
1246         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Illformed qThreadExtraInfo packet");
1247     errno = 0;
1248     nub_thread_t tid = strtoul (p, NULL, 16);
1249     if (errno != 0 && tid == 0)
1250     {
1251         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in qThreadExtraInfo packet");
1252     }
1253 
1254     const char * threadInfo = DNBThreadGetInfo(pid, tid);
1255     if (threadInfo != NULL && threadInfo[0])
1256     {
1257         return SendHexEncodedBytePacket(NULL, threadInfo, strlen(threadInfo), NULL);
1258     }
1259     else
1260     {
1261         // "OK" == 4f6b
1262         // Return "OK" as a ASCII hex byte stream if things go wrong
1263         return SendPacket ("4f6b");
1264     }
1265 
1266     return SendPacket ("");
1267 }
1268 
1269 
1270 const char *k_space_delimiters = " \t";
1271 static void
1272 skip_spaces (std::string &line)
1273 {
1274     if (!line.empty())
1275     {
1276         size_t space_pos = line.find_first_not_of (k_space_delimiters);
1277         if (space_pos > 0)
1278             line.erase(0, space_pos);
1279     }
1280 }
1281 
1282 static std::string
1283 get_identifier (std::string &line)
1284 {
1285     std::string word;
1286     skip_spaces (line);
1287     const size_t line_size = line.size();
1288     size_t end_pos;
1289     for (end_pos = 0; end_pos < line_size; ++end_pos)
1290     {
1291         if (end_pos == 0)
1292         {
1293             if (isalpha(line[end_pos]) || line[end_pos] == '_')
1294                 continue;
1295         }
1296         else if (isalnum(line[end_pos]) || line[end_pos] == '_')
1297             continue;
1298         break;
1299     }
1300     word.assign (line, 0, end_pos);
1301     line.erase(0, end_pos);
1302     return word;
1303 }
1304 
1305 static std::string
1306 get_operator (std::string &line)
1307 {
1308     std::string op;
1309     skip_spaces (line);
1310     if (!line.empty())
1311     {
1312         if (line[0] == '=')
1313         {
1314             op = '=';
1315             line.erase(0,1);
1316         }
1317     }
1318     return op;
1319 }
1320 
1321 static std::string
1322 get_value (std::string &line)
1323 {
1324     std::string value;
1325     skip_spaces (line);
1326     if (!line.empty())
1327     {
1328         value.swap(line);
1329     }
1330     return value;
1331 }
1332 
1333 extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
1334 extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
1335 
1336 rnb_err_t
1337 RNBRemote::HandlePacket_qRcmd (const char *p)
1338 {
1339     const char *c = p + strlen("qRcmd,");
1340     std::string line;
1341     while (c[0] && c[1])
1342     {
1343         char smallbuf[3] = { c[0], c[1], '\0' };
1344         errno = 0;
1345         int ch = strtoul (smallbuf, NULL, 16);
1346         if (errno != 0 && ch == 0)
1347             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet");
1348         line.push_back(ch);
1349         c += 2;
1350     }
1351     if (*c == '\0')
1352     {
1353         std::string command = get_identifier(line);
1354         if (command.compare("set") == 0)
1355         {
1356             std::string variable = get_identifier (line);
1357             std::string op = get_operator (line);
1358             std::string value = get_value (line);
1359             if (variable.compare("logfile") == 0)
1360             {
1361                 FILE *log_file = fopen(value.c_str(), "w");
1362                 if (log_file)
1363                 {
1364                     DNBLogSetLogCallback(FileLogCallback, log_file);
1365                     return SendPacket ("OK");
1366                 }
1367                 return SendPacket ("E71");
1368             }
1369             else if (variable.compare("logmask") == 0)
1370             {
1371                 char *end;
1372                 errno = 0;
1373                 uint32_t logmask = strtoul (value.c_str(), &end, 0);
1374                 if (errno == 0 && end && *end == '\0')
1375                 {
1376                     DNBLogSetLogMask (logmask);
1377                     if (!DNBLogGetLogCallback())
1378                         DNBLogSetLogCallback(ASLLogCallback, NULL);
1379                     return SendPacket ("OK");
1380                 }
1381                 errno = 0;
1382                 logmask = strtoul (value.c_str(), &end, 16);
1383                 if (errno == 0 && end && *end == '\0')
1384                 {
1385                     DNBLogSetLogMask (logmask);
1386                     return SendPacket ("OK");
1387                 }
1388                 return SendPacket ("E72");
1389             }
1390             return SendPacket ("E70");
1391         }
1392         return SendPacket ("E69");
1393     }
1394     return SendPacket ("E73");
1395 }
1396 
1397 rnb_err_t
1398 RNBRemote::HandlePacket_qC (const char *p)
1399 {
1400     nub_process_t pid;
1401     std::ostringstream rep;
1402     // If we haven't run the process yet, we tell the debugger the
1403     // pid is 0.  That way it can know to tell use to run later on.
1404     if (m_ctx.HasValidProcessID())
1405         pid = m_ctx.ProcessID();
1406     else
1407         pid = 0;
1408     rep << "QC" << std::hex << pid;
1409     return SendPacket (rep.str());
1410 }
1411 
1412 rnb_err_t
1413 RNBRemote::HandlePacket_qGetPid (const char *p)
1414 {
1415     nub_process_t pid;
1416     std::ostringstream rep;
1417     // If we haven't run the process yet, we tell the debugger the
1418     // pid is 0.  That way it can know to tell use to run later on.
1419     if (m_ctx.HasValidProcessID())
1420         pid = m_ctx.ProcessID();
1421     else
1422         pid = 0;
1423     rep << std::hex << pid;
1424     return SendPacket (rep.str());
1425 }
1426 
1427 rnb_err_t
1428 RNBRemote::HandlePacket_qRegisterInfo (const char *p)
1429 {
1430     if (g_num_reg_entries == 0)
1431         InitializeRegisters ();
1432 
1433     p += strlen ("qRegisterInfo");
1434 
1435     nub_size_t num_reg_sets = 0;
1436     const DNBRegisterSetInfo *reg_set_info = DNBGetRegisterSetInfo (&num_reg_sets);
1437     uint32_t reg_num = strtoul(p, 0, 16);
1438 
1439     if (reg_num < g_num_reg_entries)
1440     {
1441         const register_map_entry_t *reg_entry = &g_reg_entries[reg_num];
1442         std::ostringstream ostrm;
1443         if (reg_entry->nub_info.name)
1444             ostrm << "name:" << reg_entry->nub_info.name << ';';
1445         if (reg_entry->nub_info.alt)
1446             ostrm << "alt-name:" << reg_entry->nub_info.alt << ';';
1447 
1448         ostrm << "bitsize:" << std::dec << reg_entry->nub_info.size * 8 << ';';
1449         ostrm << "offset:" << std::dec << reg_entry->offset << ';';
1450 
1451         switch (reg_entry->nub_info.type)
1452         {
1453             case Uint:      ostrm << "encoding:uint;"; break;
1454             case Sint:      ostrm << "encoding:sint;"; break;
1455             case IEEE754:   ostrm << "encoding:ieee754;"; break;
1456             case Vector:    ostrm << "encoding:vector;"; break;
1457         }
1458 
1459         switch (reg_entry->nub_info.format)
1460         {
1461             case Binary:            ostrm << "format:binary;"; break;
1462             case Decimal:           ostrm << "format:decimal;"; break;
1463             case Hex:               ostrm << "format:hex;"; break;
1464             case Float:             ostrm << "format:float;"; break;
1465             case VectorOfSInt8:     ostrm << "format:vector-sint8;"; break;
1466             case VectorOfUInt8:     ostrm << "format:vector-uint8;"; break;
1467             case VectorOfSInt16:    ostrm << "format:vector-sint16;"; break;
1468             case VectorOfUInt16:    ostrm << "format:vector-uint16;"; break;
1469             case VectorOfSInt32:    ostrm << "format:vector-sint32;"; break;
1470             case VectorOfUInt32:    ostrm << "format:vector-uint32;"; break;
1471             case VectorOfFloat32:   ostrm << "format:vector-float32;"; break;
1472             case VectorOfUInt128:   ostrm << "format:vector-uint128;"; break;
1473         };
1474 
1475         if (reg_set_info && reg_entry->nub_info.set < num_reg_sets)
1476             ostrm << "set:" << reg_set_info[reg_entry->nub_info.set].name << ';';
1477 
1478         if (reg_entry->nub_info.reg_gcc != INVALID_NUB_REGNUM)
1479             ostrm << "gcc:" << std::dec << reg_entry->nub_info.reg_gcc << ';';
1480 
1481         if (reg_entry->nub_info.reg_dwarf != INVALID_NUB_REGNUM)
1482             ostrm << "dwarf:" << std::dec << reg_entry->nub_info.reg_dwarf << ';';
1483 
1484         switch (reg_entry->nub_info.reg_generic)
1485         {
1486             case GENERIC_REGNUM_FP:     ostrm << "generic:fp;"; break;
1487             case GENERIC_REGNUM_PC:     ostrm << "generic:pc;"; break;
1488             case GENERIC_REGNUM_SP:     ostrm << "generic:sp;"; break;
1489             case GENERIC_REGNUM_RA:     ostrm << "generic:ra;"; break;
1490             case GENERIC_REGNUM_FLAGS:  ostrm << "generic:flags;"; break;
1491             case GENERIC_REGNUM_ARG1:   ostrm << "generic:arg1;"; break;
1492             case GENERIC_REGNUM_ARG2:   ostrm << "generic:arg2;"; break;
1493             case GENERIC_REGNUM_ARG3:   ostrm << "generic:arg3;"; break;
1494             case GENERIC_REGNUM_ARG4:   ostrm << "generic:arg4;"; break;
1495             case GENERIC_REGNUM_ARG5:   ostrm << "generic:arg5;"; break;
1496             case GENERIC_REGNUM_ARG6:   ostrm << "generic:arg6;"; break;
1497             case GENERIC_REGNUM_ARG7:   ostrm << "generic:arg7;"; break;
1498             case GENERIC_REGNUM_ARG8:   ostrm << "generic:arg8;"; break;
1499             default: break;
1500         }
1501 
1502         if (!reg_entry->value_regnums.empty())
1503         {
1504             ostrm << "container-regs:";
1505             for (size_t i=0, n=reg_entry->value_regnums.size(); i < n; ++i)
1506             {
1507                 if (i > 0)
1508                     ostrm << ',';
1509                 ostrm << RAW_HEXBASE << reg_entry->value_regnums[i];
1510             }
1511             ostrm << ';';
1512         }
1513 
1514         if (!reg_entry->invalidate_regnums.empty())
1515         {
1516             ostrm << "invalidate-regs:";
1517             for (size_t i=0, n=reg_entry->invalidate_regnums.size(); i < n; ++i)
1518             {
1519                 if (i > 0)
1520                     ostrm << ',';
1521                 ostrm << RAW_HEXBASE << reg_entry->invalidate_regnums[i];
1522             }
1523             ostrm << ';';
1524         }
1525 
1526         return SendPacket (ostrm.str ());
1527     }
1528     return SendPacket ("E45");
1529 }
1530 
1531 
1532 /* This expects a packet formatted like
1533 
1534  QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
1535 
1536  with the "QSetLogging:" already removed from the start.  Maybe in the
1537  future this packet will include other keyvalue pairs like
1538 
1539  QSetLogging:bitmask=LOG_ALL;mode=asl;
1540  */
1541 
1542 rnb_err_t
1543 set_logging (const char *p)
1544 {
1545     int bitmask = 0;
1546     while (p && *p != '\0')
1547     {
1548         if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0)
1549         {
1550             p += sizeof ("bitmask=") - 1;
1551             while (p && *p != '\0' && *p != ';')
1552             {
1553                 if (*p == '|')
1554                     p++;
1555 
1556 // to regenerate the LOG_ entries (not including the LOG_RNB entries)
1557 // $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'`
1558 // do
1559 //   echo "                else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)"
1560 //   echo "                {"
1561 //   echo "                    p += sizeof (\"$logname\") - 1;"
1562 //   echo "                    bitmask |= $logname;"
1563 //   echo "                }"
1564 // done
1565                 if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
1566                 {
1567                     p += sizeof ("LOG_VERBOSE") - 1;
1568                     bitmask |= LOG_VERBOSE;
1569                 }
1570                 else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0)
1571                 {
1572                     p += sizeof ("LOG_PROCESS") - 1;
1573                     bitmask |= LOG_PROCESS;
1574                 }
1575                 else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0)
1576                 {
1577                     p += sizeof ("LOG_THREAD") - 1;
1578                     bitmask |= LOG_THREAD;
1579                 }
1580                 else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0)
1581                 {
1582                     p += sizeof ("LOG_EXCEPTIONS") - 1;
1583                     bitmask |= LOG_EXCEPTIONS;
1584                 }
1585                 else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0)
1586                 {
1587                     p += sizeof ("LOG_SHLIB") - 1;
1588                     bitmask |= LOG_SHLIB;
1589                 }
1590                 else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0)
1591                 {
1592                     p += sizeof ("LOG_MEMORY") - 1;
1593                     bitmask |= LOG_MEMORY;
1594                 }
1595                 else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0)
1596                 {
1597                     p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1;
1598                     bitmask |= LOG_MEMORY_DATA_SHORT;
1599                 }
1600                 else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0)
1601                 {
1602                     p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
1603                     bitmask |= LOG_MEMORY_DATA_LONG;
1604                 }
1605                 else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0)
1606                 {
1607                     p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1;
1608                     bitmask |= LOG_MEMORY_PROTECTIONS;
1609                 }
1610                 else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
1611                 {
1612                     p += sizeof ("LOG_BREAKPOINTS") - 1;
1613                     bitmask |= LOG_BREAKPOINTS;
1614                 }
1615                 else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
1616                 {
1617                     p += sizeof ("LOG_EVENTS") - 1;
1618                     bitmask |= LOG_EVENTS;
1619                 }
1620                 else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0)
1621                 {
1622                     p += sizeof ("LOG_WATCHPOINTS") - 1;
1623                     bitmask |= LOG_WATCHPOINTS;
1624                 }
1625                 else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0)
1626                 {
1627                     p += sizeof ("LOG_STEP") - 1;
1628                     bitmask |= LOG_STEP;
1629                 }
1630                 else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0)
1631                 {
1632                     p += sizeof ("LOG_TASK") - 1;
1633                     bitmask |= LOG_TASK;
1634                 }
1635                 else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
1636                 {
1637                     p += sizeof ("LOG_ALL") - 1;
1638                     bitmask |= LOG_ALL;
1639                 }
1640                 else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
1641                 {
1642                     p += sizeof ("LOG_DEFAULT") - 1;
1643                     bitmask |= LOG_DEFAULT;
1644                 }
1645 // end of auto-generated entries
1646 
1647                 else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
1648                 {
1649                     p += sizeof ("LOG_NONE") - 1;
1650                     bitmask = 0;
1651                 }
1652                 else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0)
1653                 {
1654                     p += sizeof ("LOG_RNB_MINIMAL") - 1;
1655                     bitmask |= LOG_RNB_MINIMAL;
1656                 }
1657                 else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0)
1658                 {
1659                     p += sizeof ("LOG_RNB_MEDIUM") - 1;
1660                     bitmask |= LOG_RNB_MEDIUM;
1661                 }
1662                 else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0)
1663                 {
1664                     p += sizeof ("LOG_RNB_MAX") - 1;
1665                     bitmask |= LOG_RNB_MAX;
1666                 }
1667                 else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0)
1668                 {
1669                     p += sizeof ("LOG_RNB_COMM") - 1;
1670                     bitmask |= LOG_RNB_COMM;
1671                 }
1672                 else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0)
1673                 {
1674                     p += sizeof ("LOG_RNB_REMOTE") - 1;
1675                     bitmask |= LOG_RNB_REMOTE;
1676                 }
1677                 else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0)
1678                 {
1679                     p += sizeof ("LOG_RNB_EVENTS") - 1;
1680                     bitmask |= LOG_RNB_EVENTS;
1681                 }
1682                 else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0)
1683                 {
1684                     p += sizeof ("LOG_RNB_PROC") - 1;
1685                     bitmask |= LOG_RNB_PROC;
1686                 }
1687                 else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0)
1688                 {
1689                     p += sizeof ("LOG_RNB_PACKETS") - 1;
1690                     bitmask |= LOG_RNB_PACKETS;
1691                 }
1692                 else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0)
1693                 {
1694                     p += sizeof ("LOG_RNB_ALL") - 1;
1695                     bitmask |= LOG_RNB_ALL;
1696                 }
1697                 else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0)
1698                 {
1699                     p += sizeof ("LOG_RNB_DEFAULT") - 1;
1700                     bitmask |= LOG_RNB_DEFAULT;
1701                 }
1702                 else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0)
1703                 {
1704                     p += sizeof ("LOG_RNB_NONE") - 1;
1705                     bitmask = 0;
1706                 }
1707                 else
1708                 {
1709                     /* Unrecognized logging bit; ignore it.  */
1710                     const char *c = strchr (p, '|');
1711                     if (c)
1712                     {
1713                         p = c;
1714                     }
1715                     else
1716                     {
1717                         c = strchr (p, ';');
1718                         if (c)
1719                         {
1720                             p = c;
1721                         }
1722                         else
1723                         {
1724                             // Improperly terminated word; just go to end of str
1725                             p = strchr (p, '\0');
1726                         }
1727                     }
1728                 }
1729             }
1730             // Did we get a properly formatted logging bitmask?
1731             if (p && *p == ';')
1732             {
1733                 // Enable DNB logging
1734                 DNBLogSetLogCallback(ASLLogCallback, NULL);
1735                 DNBLogSetLogMask (bitmask);
1736                 p++;
1737             }
1738         }
1739         // We're not going to support logging to a file for now.  All logging
1740         // goes through ASL.
1741 #if 0
1742         else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
1743         {
1744             p += sizeof ("mode=") - 1;
1745             if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
1746             {
1747                 DNBLogToASL ();
1748                 p += sizeof ("asl;") - 1;
1749             }
1750             else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
1751             {
1752                 DNBLogToFile ();
1753                 p += sizeof ("file;") - 1;
1754             }
1755             else
1756             {
1757                 // Ignore unknown argument
1758                 const char *c = strchr (p, ';');
1759                 if (c)
1760                     p = c + 1;
1761                 else
1762                     p = strchr (p, '\0');
1763             }
1764         }
1765         else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
1766         {
1767             p += sizeof ("filename=") - 1;
1768             const char *c = strchr (p, ';');
1769             if (c == NULL)
1770             {
1771                 c = strchr (p, '\0');
1772                 continue;
1773             }
1774             char *fn = (char *) alloca (c - p + 1);
1775             strncpy (fn, p, c - p);
1776             fn[c - p] = '\0';
1777 
1778             // A file name of "asl" is special and is another way to indicate
1779             // that logging should be done via ASL, not by file.
1780             if (strcmp (fn, "asl") == 0)
1781             {
1782                 DNBLogToASL ();
1783             }
1784             else
1785             {
1786                 FILE *f = fopen (fn, "w");
1787                 if (f)
1788                 {
1789                     DNBLogSetLogFile (f);
1790                     DNBEnableLogging (f, DNBLogGetLogMask ());
1791                     DNBLogToFile ();
1792                 }
1793             }
1794             p = c + 1;
1795         }
1796 #endif /* #if 0 to enforce ASL logging only.  */
1797         else
1798         {
1799             // Ignore unknown argument
1800             const char *c = strchr (p, ';');
1801             if (c)
1802                 p = c + 1;
1803             else
1804                 p = strchr (p, '\0');
1805         }
1806     }
1807 
1808     return rnb_success;
1809 }
1810 
1811 rnb_err_t
1812 RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
1813 {
1814     m_thread_suffix_supported = true;
1815     return SendPacket ("OK");
1816 }
1817 
1818 rnb_err_t
1819 RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
1820 {
1821     // Send the OK packet first so the correct checksum is appended...
1822     rnb_err_t result = SendPacket ("OK");
1823     m_noack_mode = true;
1824     return result;
1825 }
1826 
1827 
1828 rnb_err_t
1829 RNBRemote::HandlePacket_QSetLogging (const char *p)
1830 {
1831     p += sizeof ("QSetLogging:") - 1;
1832     rnb_err_t result = set_logging (p);
1833     if (result == rnb_success)
1834         return SendPacket ("OK");
1835     else
1836         return SendPacket ("E35");
1837 }
1838 
1839 rnb_err_t
1840 RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
1841 {
1842     extern int g_disable_aslr;
1843     p += sizeof ("QSetDisableASLR:") - 1;
1844     switch (*p)
1845     {
1846     case '0': g_disable_aslr = 0; break;
1847     case '1': g_disable_aslr = 1; break;
1848     default:
1849         return SendPacket ("E56");
1850     }
1851     return SendPacket ("OK");
1852 }
1853 
1854 rnb_err_t
1855 RNBRemote::HandlePacket_QSetSTDIO (const char *p)
1856 {
1857     // Only set stdin/out/err if we don't already have a process
1858     if (!m_ctx.HasValidProcessID())
1859     {
1860         bool success = false;
1861         // Check the seventh character since the packet will be one of:
1862         // QSetSTDIN
1863         // QSetSTDOUT
1864         // QSetSTDERR
1865         StringExtractor packet(p);
1866         packet.SetFilePos (7);
1867         char ch = packet.GetChar();
1868         while (packet.GetChar() != ':')
1869             /* Do nothing. */;
1870 
1871         switch (ch)
1872         {
1873             case 'I': // STDIN
1874                 packet.GetHexByteString (m_ctx.GetSTDIN());
1875                 success = !m_ctx.GetSTDIN().empty();
1876                 break;
1877 
1878             case 'O': // STDOUT
1879                 packet.GetHexByteString (m_ctx.GetSTDOUT());
1880                 success = !m_ctx.GetSTDOUT().empty();
1881                 break;
1882 
1883             case 'E': // STDERR
1884                 packet.GetHexByteString (m_ctx.GetSTDERR());
1885                 success = !m_ctx.GetSTDERR().empty();
1886                 break;
1887 
1888             default:
1889                 break;
1890         }
1891         if (success)
1892             return SendPacket ("OK");
1893         return SendPacket ("E57");
1894     }
1895     return SendPacket ("E58");
1896 }
1897 
1898 rnb_err_t
1899 RNBRemote::HandlePacket_QSetWorkingDir (const char *p)
1900 {
1901     // Only set the working directory if we don't already have a process
1902     if (!m_ctx.HasValidProcessID())
1903     {
1904         StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);
1905         if (packet.GetHexByteString (m_ctx.GetWorkingDir()))
1906         {
1907             struct stat working_dir_stat;
1908             if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1)
1909             {
1910                 m_ctx.GetWorkingDir().clear();
1911                 return SendPacket ("E61");    // Working directory doesn't exist...
1912             }
1913             else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR)
1914             {
1915                 return SendPacket ("OK");
1916             }
1917             else
1918             {
1919                 m_ctx.GetWorkingDir().clear();
1920                 return SendPacket ("E62");    // Working directory isn't a directory...
1921             }
1922         }
1923         return SendPacket ("E59");  // Invalid path
1924     }
1925     return SendPacket ("E60"); // Already had a process, too late to set working dir
1926 }
1927 
1928 rnb_err_t
1929 RNBRemote::HandlePacket_QSyncThreadState (const char *p)
1930 {
1931     if (!m_ctx.HasValidProcessID())
1932     {
1933         // We allow gdb to connect to a server that hasn't started running
1934         // the target yet.  gdb still wants to ask questions about it and
1935         // freaks out if it gets an error.  So just return OK here.
1936         return SendPacket ("OK");
1937     }
1938 
1939     errno = 0;
1940     p += strlen("QSyncThreadState:");
1941     nub_thread_t tid = strtoul (p, NULL, 16);
1942     if (errno != 0 && tid == 0)
1943     {
1944         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet");
1945     }
1946     if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid))
1947         return SendPacket("OK");
1948     else
1949         return SendPacket ("E61");
1950 }
1951 
1952 rnb_err_t
1953 RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p)
1954 {
1955     // If this packet is received, it allows us to send an extra key/value
1956     // pair in the stop reply packets where we will list all of the thread IDs
1957     // separated by commas:
1958     //
1959     //  "threads:10a,10b,10c;"
1960     //
1961     // This will get included in the stop reply packet as something like:
1962     //
1963     //  "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;"
1964     //
1965     // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and
1966     // speed things up a bit.
1967     //
1968     // Send the OK packet first so the correct checksum is appended...
1969     rnb_err_t result = SendPacket ("OK");
1970     m_list_threads_in_stop_reply = true;
1971     return result;
1972 }
1973 
1974 
1975 rnb_err_t
1976 RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
1977 {
1978     /* The number of characters in a packet payload that gdb is
1979      prepared to accept.  The packet-start char, packet-end char,
1980      2 checksum chars and terminating null character are not included
1981      in this size.  */
1982     p += sizeof ("QSetMaxPayloadSize:") - 1;
1983     errno = 0;
1984     uint32_t size = strtoul (p, NULL, 16);
1985     if (errno != 0 && size == 0)
1986     {
1987         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
1988     }
1989     m_max_payload_size = size;
1990     return SendPacket ("OK");
1991 }
1992 
1993 rnb_err_t
1994 RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
1995 {
1996     /* This tells us the largest packet that gdb can handle.
1997      i.e. the size of gdb's packet-reading buffer.
1998      QSetMaxPayloadSize is preferred because it is less ambiguous.  */
1999     p += sizeof ("QSetMaxPacketSize:") - 1;
2000     errno = 0;
2001     uint32_t size = strtoul (p, NULL, 16);
2002     if (errno != 0 && size == 0)
2003     {
2004         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
2005     }
2006     m_max_payload_size = size - 5;
2007     return SendPacket ("OK");
2008 }
2009 
2010 
2011 
2012 
2013 rnb_err_t
2014 RNBRemote::HandlePacket_QEnvironment (const char *p)
2015 {
2016     /* This sets the environment for the target program.  The packet is of the form:
2017 
2018      QEnvironment:VARIABLE=VALUE
2019 
2020      */
2021 
2022     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
2023                       (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2024 
2025     p += sizeof ("QEnvironment:") - 1;
2026     RNBContext& ctx = Context();
2027 
2028     ctx.PushEnvironment (p);
2029     return SendPacket ("OK");
2030 }
2031 
2032 rnb_err_t
2033 RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p)
2034 {
2035     /* This sets the environment for the target program.  The packet is of the form:
2036 
2037         QEnvironmentHexEncoded:VARIABLE=VALUE
2038 
2039         The VARIABLE=VALUE part is sent hex-encoded so chracters like '#' with special
2040         meaning in the remote protocol won't break it.
2041     */
2042 
2043     DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"",
2044         (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2045 
2046     p += sizeof ("QEnvironmentHexEncoded:") - 1;
2047 
2048     std::string arg;
2049     const char *c;
2050     c = p;
2051     while (*c != '\0')
2052       {
2053         if (*(c + 1) == '\0')
2054         {
2055             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2056         }
2057         char smallbuf[3];
2058         smallbuf[0] = *c;
2059         smallbuf[1] = *(c + 1);
2060         smallbuf[2] = '\0';
2061         errno = 0;
2062         int ch = strtoul (smallbuf, NULL, 16);
2063         if (errno != 0 && ch == 0)
2064           {
2065             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2066           }
2067         arg.push_back(ch);
2068         c += 2;
2069       }
2070 
2071     RNBContext& ctx = Context();
2072     if (arg.length() > 0)
2073       ctx.PushEnvironment (arg.c_str());
2074 
2075     return SendPacket ("OK");
2076 }
2077 
2078 
2079 rnb_err_t
2080 RNBRemote::HandlePacket_QLaunchArch (const char *p)
2081 {
2082     p += sizeof ("QLaunchArch:") - 1;
2083     if (DNBSetArchitecture(p))
2084         return SendPacket ("OK");
2085     return SendPacket ("E63");
2086 }
2087 
2088 void
2089 append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap)
2090 {
2091     int i;
2092     if (swap)
2093     {
2094         for (i = buf_size-1; i >= 0; i--)
2095             ostrm << RAWHEX8(buf[i]);
2096     }
2097     else
2098     {
2099         for (i = 0; i < buf_size; i++)
2100             ostrm << RAWHEX8(buf[i]);
2101     }
2102 }
2103 
2104 
2105 void
2106 register_value_in_hex_fixed_width (std::ostream& ostrm,
2107                                    nub_process_t pid,
2108                                    nub_thread_t tid,
2109                                    const register_map_entry_t* reg,
2110                                    const DNBRegisterValue *reg_value_ptr)
2111 {
2112     if (reg != NULL)
2113     {
2114         DNBRegisterValue reg_value;
2115         if (reg_value_ptr == NULL)
2116         {
2117             if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &reg_value))
2118                 reg_value_ptr = &reg_value;
2119         }
2120 
2121         if (reg_value_ptr)
2122         {
2123             append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->nub_info.size, false);
2124         }
2125         else
2126         {
2127             // If we fail to read a regiser value, check if it has a default
2128             // fail value. If it does, return this instead in case some of
2129             // the registers are not available on the current system.
2130             if (reg->nub_info.size > 0)
2131             {
2132                 std::basic_string<uint8_t> zeros(reg->nub_info.size, '\0');
2133                 append_hex_value (ostrm, zeros.data(), zeros.size(), false);
2134             }
2135         }
2136     }
2137 }
2138 
2139 
2140 void
2141 gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
2142                                                 nub_process_t pid,
2143                                                 nub_thread_t tid,
2144                                                 const register_map_entry_t* reg,
2145                                                 const DNBRegisterValue *reg_value_ptr)
2146 {
2147     // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
2148     // gdb register number, and VVVVVVVV is the correct number of hex bytes
2149     // as ASCII for the register value.
2150     if (reg != NULL)
2151     {
2152         ostrm << RAWHEX8(reg->gdb_regnum) << ':';
2153         register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr);
2154         ostrm << ';';
2155     }
2156 }
2157 
2158 rnb_err_t
2159 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
2160 {
2161     const nub_process_t pid = m_ctx.ProcessID();
2162     if (pid == INVALID_NUB_PROCESS)
2163         return SendPacket("E50");
2164 
2165     struct DNBThreadStopInfo tid_stop_info;
2166 
2167     /* Fill the remaining space in this packet with as many registers
2168      as we can stuff in there.  */
2169 
2170     if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
2171     {
2172         const bool did_exec = tid_stop_info.reason == eStopTypeExec;
2173         if (did_exec)
2174             RNBRemote::InitializeRegisters(true);
2175 
2176         std::ostringstream ostrm;
2177         // Output the T packet with the thread
2178         ostrm << 'T';
2179         int signum = tid_stop_info.details.signal.signo;
2180         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);
2181 
2182         // Translate any mach exceptions to gdb versions, unless they are
2183         // common exceptions like a breakpoint or a soft signal.
2184         switch (tid_stop_info.details.exception.type)
2185         {
2186             default:                    signum = 0; break;
2187             case EXC_BREAKPOINT:        signum = SIGTRAP; break;
2188             case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2189             case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2190             case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2191             case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2192             case EXC_SOFTWARE:
2193                 if (tid_stop_info.details.exception.data_count == 2 &&
2194                     tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2195                     signum = tid_stop_info.details.exception.data[1];
2196                 else
2197                     signum = TARGET_EXC_SOFTWARE;
2198                 break;
2199         }
2200 
2201         ostrm << RAWHEX8(signum & 0xff);
2202 
2203         ostrm << std::hex << "thread:" << tid << ';';
2204 
2205         const char *thread_name = DNBThreadGetName (pid, tid);
2206         if (thread_name && thread_name[0])
2207         {
2208             size_t thread_name_len = strlen(thread_name);
2209 
2210             if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2211                 ostrm << std::hex << "name:" << thread_name << ';';
2212             else
2213             {
2214                 // the thread name contains special chars, send as hex bytes
2215                 ostrm << std::hex << "hexname:";
2216                 uint8_t *u_thread_name = (uint8_t *)thread_name;
2217                 for (int i = 0; i < thread_name_len; i++)
2218                     ostrm << RAWHEX8(u_thread_name[i]);
2219                 ostrm << ';';
2220             }
2221         }
2222 
2223         thread_identifier_info_data_t thread_ident_info;
2224         if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
2225         {
2226             if (thread_ident_info.dispatch_qaddr != 0)
2227                 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
2228         }
2229 
2230         // If a 'QListThreadsInStopReply' was sent to enable this feature, we
2231         // will send all thread IDs back in the "threads" key whose value is
2232         // a listc of hex thread IDs separated by commas:
2233         //  "threads:10a,10b,10c;"
2234         // This will save the debugger from having to send a pair of qfThreadInfo
2235         // and qsThreadInfo packets, but it also might take a lot of room in the
2236         // stop reply packet, so it must be enabled only on systems where there
2237         // are no limits on packet lengths.
2238 
2239         if (m_list_threads_in_stop_reply)
2240         {
2241             const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
2242             if (numthreads > 0)
2243             {
2244                 ostrm << std::hex << "threads:";
2245                 for (nub_size_t i = 0; i < numthreads; ++i)
2246                 {
2247                     nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
2248                     if (i > 0)
2249                         ostrm << ',';
2250                     ostrm << std::hex << th;
2251                 }
2252                 ostrm << ';';
2253             }
2254         }
2255 
2256         if (g_num_reg_entries == 0)
2257             InitializeRegisters ();
2258 
2259         if (g_reg_entries != NULL)
2260         {
2261             DNBRegisterValue reg_value;
2262             for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2263             {
2264                 // Expedite all registers in the first register set that aren't
2265                 // contained in other registers
2266                 if (g_reg_entries[reg].nub_info.set == 1 &&
2267                     g_reg_entries[reg].nub_info.value_regs == NULL)
2268                 {
2269                     if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
2270                         continue;
2271 
2272                     gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], &reg_value);
2273                 }
2274             }
2275         }
2276 
2277         if (did_exec)
2278         {
2279             ostrm << "reason:exec;";
2280         }
2281         else if (tid_stop_info.details.exception.type)
2282         {
2283             ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";";
2284             ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";";
2285             for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
2286                 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";";
2287         }
2288         return SendPacket (ostrm.str ());
2289     }
2290     return SendPacket("E51");
2291 }
2292 
2293 /* '?'
2294  The stop reply packet - tell gdb what the status of the inferior is.
2295  Often called the questionmark_packet.  */
2296 
2297 rnb_err_t
2298 RNBRemote::HandlePacket_last_signal (const char *unused)
2299 {
2300     if (!m_ctx.HasValidProcessID())
2301     {
2302         // Inferior is not yet specified/running
2303         return SendPacket ("E02");
2304     }
2305 
2306     nub_process_t pid = m_ctx.ProcessID();
2307     nub_state_t pid_state = DNBProcessGetState (pid);
2308 
2309     switch (pid_state)
2310     {
2311         case eStateAttaching:
2312         case eStateLaunching:
2313         case eStateRunning:
2314         case eStateStepping:
2315         case eStateDetached:
2316             return rnb_success;  // Ignore
2317 
2318         case eStateSuspended:
2319         case eStateStopped:
2320         case eStateCrashed:
2321             {
2322                 nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2323                 // Make sure we set the current thread so g and p packets return
2324                 // the data the gdb will expect.
2325                 SetCurrentThread (tid);
2326 
2327                 SendStopReplyPacketForThread (tid);
2328             }
2329             break;
2330 
2331         case eStateInvalid:
2332         case eStateUnloaded:
2333         case eStateExited:
2334             {
2335                 char pid_exited_packet[16] = "";
2336                 int pid_status = 0;
2337                 // Process exited with exit status
2338                 if (!DNBProcessGetExitStatus(pid, &pid_status))
2339                     pid_status = 0;
2340 
2341                 if (pid_status)
2342                 {
2343                     if (WIFEXITED (pid_status))
2344                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2345                     else if (WIFSIGNALED (pid_status))
2346                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2347                     else if (WIFSTOPPED (pid_status))
2348                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2349                 }
2350 
2351                 // If we have an empty exit packet, lets fill one in to be safe.
2352                 if (!pid_exited_packet[0])
2353                 {
2354                     strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2355                     pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2356                 }
2357 
2358                 return SendPacket (pid_exited_packet);
2359             }
2360             break;
2361     }
2362     return rnb_success;
2363 }
2364 
2365 rnb_err_t
2366 RNBRemote::HandlePacket_M (const char *p)
2367 {
2368     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2369     {
2370         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2371     }
2372 
2373     char *c;
2374     p++;
2375     errno = 0;
2376     nub_addr_t addr = strtoull (p, &c, 16);
2377     if (errno != 0 && addr == 0)
2378     {
2379         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2380     }
2381     if (*c != ',')
2382     {
2383         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2384     }
2385 
2386     /* Advance 'p' to the length part of the packet.  */
2387     p += (c - p) + 1;
2388 
2389     errno = 0;
2390     uint32_t length = strtoul (p, &c, 16);
2391     if (errno != 0 && length == 0)
2392     {
2393         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2394     }
2395     if (length == 0)
2396     {
2397         return SendPacket ("OK");
2398     }
2399 
2400     if (*c != ':')
2401     {
2402         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2403     }
2404     /* Advance 'p' to the data part of the packet.  */
2405     p += (c - p) + 1;
2406 
2407     int datalen = strlen (p);
2408     if (datalen & 0x1)
2409     {
2410         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2411     }
2412     if (datalen == 0)
2413     {
2414         return SendPacket ("OK");
2415     }
2416 
2417     uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2418     uint8_t *i = buf;
2419 
2420     while (*p != '\0' && *(p + 1) != '\0')
2421     {
2422         char hexbuf[3];
2423         hexbuf[0] = *p;
2424         hexbuf[1] = *(p + 1);
2425         hexbuf[2] = '\0';
2426         errno = 0;
2427         uint8_t byte = strtoul (hexbuf, NULL, 16);
2428         if (errno != 0 && byte == 0)
2429         {
2430             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2431         }
2432         *i++ = byte;
2433         p += 2;
2434     }
2435 
2436     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2437     if (wrote != length)
2438         return SendPacket ("E09");
2439     else
2440         return SendPacket ("OK");
2441 }
2442 
2443 
2444 rnb_err_t
2445 RNBRemote::HandlePacket_m (const char *p)
2446 {
2447     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2448     {
2449         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
2450     }
2451 
2452     char *c;
2453     p++;
2454     errno = 0;
2455     nub_addr_t addr = strtoull (p, &c, 16);
2456     if (errno != 0 && addr == 0)
2457     {
2458         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
2459     }
2460     if (*c != ',')
2461     {
2462         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
2463     }
2464 
2465     /* Advance 'p' to the length part of the packet.  */
2466     p += (c - p) + 1;
2467 
2468     errno = 0;
2469     uint32_t length = strtoul (p, NULL, 16);
2470     if (errno != 0 && length == 0)
2471     {
2472         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2473     }
2474     if (length == 0)
2475     {
2476         return SendPacket ("");
2477     }
2478 
2479     std::string buf(length, '\0');
2480     if (buf.empty())
2481     {
2482         return SendPacket ("E78");
2483     }
2484     int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, buf.size(), &buf[0]);
2485     if (bytes_read == 0)
2486     {
2487         return SendPacket ("E08");
2488     }
2489 
2490     // "The reply may contain fewer bytes than requested if the server was able
2491     //  to read only part of the region of memory."
2492     length = bytes_read;
2493 
2494     std::ostringstream ostrm;
2495     for (int i = 0; i < length; i++)
2496         ostrm << RAWHEX8(buf[i]);
2497     return SendPacket (ostrm.str ());
2498 }
2499 
2500 rnb_err_t
2501 RNBRemote::HandlePacket_X (const char *p)
2502 {
2503     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2504     {
2505         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
2506     }
2507 
2508     char *c;
2509     p++;
2510     errno = 0;
2511     nub_addr_t addr = strtoull (p, &c, 16);
2512     if (errno != 0 && addr == 0)
2513     {
2514         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
2515     }
2516     if (*c != ',')
2517     {
2518         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
2519     }
2520 
2521     /* Advance 'p' to the length part of the packet.  */
2522     p += (c - p) + 1;
2523 
2524     errno = 0;
2525     int length = strtoul (p, NULL, 16);
2526     if (errno != 0 && length == 0)
2527     {
2528         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2529     }
2530 
2531     // I think gdb sends a zero length write request to test whether this
2532     // packet is accepted.
2533     if (length == 0)
2534     {
2535         return SendPacket ("OK");
2536     }
2537 
2538     std::vector<uint8_t> data = decode_binary_data (c, -1);
2539     std::vector<uint8_t>::const_iterator it;
2540     uint8_t *buf = (uint8_t *) alloca (data.size ());
2541     uint8_t *i = buf;
2542     for (it = data.begin (); it != data.end (); ++it)
2543     {
2544         *i++ = *it;
2545     }
2546 
2547     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
2548     if (wrote != data.size ())
2549         return SendPacket ("E08");
2550     return SendPacket ("OK");
2551 }
2552 
2553 /* 'g' -- read registers
2554  Get the contents of the registers for the current thread,
2555  send them to gdb.
2556  Should the setting of the Hg packet determine which thread's registers
2557  are returned?  */
2558 
2559 rnb_err_t
2560 RNBRemote::HandlePacket_g (const char *p)
2561 {
2562     std::ostringstream ostrm;
2563     if (!m_ctx.HasValidProcessID())
2564     {
2565         return SendPacket ("E11");
2566     }
2567 
2568     if (g_num_reg_entries == 0)
2569         InitializeRegisters ();
2570 
2571     nub_process_t pid = m_ctx.ProcessID ();
2572     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
2573     if (tid == INVALID_NUB_THREAD)
2574         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2575 
2576     // Get the register context size first by calling with NULL buffer
2577     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2578     if (reg_ctx_size)
2579     {
2580         // Now allocate enough space for the entire register context
2581         std::vector<uint8_t> reg_ctx;
2582         reg_ctx.resize(reg_ctx_size);
2583         // Now read the register context
2584         reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
2585         if (reg_ctx_size)
2586         {
2587             append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
2588             return SendPacket (ostrm.str ());
2589         }
2590     }
2591     return SendPacket ("E74");
2592 }
2593 
2594 /* 'G XXX...' -- write registers
2595  How is the thread for these specified, beyond "the current thread"?
2596  Does gdb actually use the Hg packet to set this?  */
2597 
2598 rnb_err_t
2599 RNBRemote::HandlePacket_G (const char *p)
2600 {
2601     if (!m_ctx.HasValidProcessID())
2602     {
2603         return SendPacket ("E11");
2604     }
2605 
2606     if (g_num_reg_entries == 0)
2607         InitializeRegisters ();
2608 
2609     StringExtractor packet(p);
2610     packet.SetFilePos(1); // Skip the 'G'
2611 
2612     nub_process_t pid = m_ctx.ProcessID();
2613     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2614     if (tid == INVALID_NUB_THREAD)
2615         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2616 
2617     // Get the register context size first by calling with NULL buffer
2618     nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2619     if (reg_ctx_size)
2620     {
2621         // Now allocate enough space for the entire register context
2622         std::vector<uint8_t> reg_ctx;
2623         reg_ctx.resize(reg_ctx_size);
2624 
2625         const nub_size_t bytes_extracted = packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc);
2626         if (bytes_extracted == reg_ctx.size())
2627         {
2628             // Now write the register context
2629             reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
2630             if (reg_ctx_size == reg_ctx.size())
2631                 return SendPacket ("OK");
2632             else
2633                 return SendPacket ("E55");
2634         }
2635         else
2636         {
2637             DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size);
2638             return SendPacket ("E64");
2639         }
2640     }
2641     return SendPacket ("E65");
2642 }
2643 
2644 static bool
2645 RNBRemoteShouldCancelCallback (void *not_used)
2646 {
2647     RNBRemoteSP remoteSP(g_remoteSP);
2648     if (remoteSP.get() != NULL)
2649     {
2650         RNBRemote* remote = remoteSP.get();
2651         if (remote->Comm().IsConnected())
2652             return false;
2653         else
2654             return true;
2655     }
2656     return true;
2657 }
2658 
2659 
2660 // FORMAT: _MXXXXXX,PPP
2661 //      XXXXXX: big endian hex chars
2662 //      PPP: permissions can be any combo of r w x chars
2663 //
2664 // RESPONSE: XXXXXX
2665 //      XXXXXX: hex address of the newly allocated memory
2666 //      EXX: error code
2667 //
2668 // EXAMPLES:
2669 //      _M123000,rw
2670 //      _M123000,rwx
2671 //      _M123000,xw
2672 
2673 rnb_err_t
2674 RNBRemote::HandlePacket_AllocateMemory (const char *p)
2675 {
2676     StringExtractor packet (p);
2677     packet.SetFilePos(2); // Skip the "_M"
2678 
2679     nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
2680     if (size != 0)
2681     {
2682         if (packet.GetChar() == ',')
2683         {
2684             uint32_t permissions = 0;
2685             char ch;
2686             bool success = true;
2687             while (success && (ch = packet.GetChar()) != '\0')
2688             {
2689                 switch (ch)
2690                 {
2691                 case 'r':   permissions |= eMemoryPermissionsReadable; break;
2692                 case 'w':   permissions |= eMemoryPermissionsWritable; break;
2693                 case 'x':   permissions |= eMemoryPermissionsExecutable; break;
2694                 default:    success = false; break;
2695                 }
2696             }
2697 
2698             if (success)
2699             {
2700                 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
2701                 if (addr != INVALID_NUB_ADDRESS)
2702                 {
2703                     std::ostringstream ostrm;
2704                     ostrm << RAW_HEXBASE << addr;
2705                     return SendPacket (ostrm.str ());
2706                 }
2707             }
2708         }
2709     }
2710     return SendPacket ("E53");
2711 }
2712 
2713 // FORMAT: _mXXXXXX
2714 //      XXXXXX: address that was previosly allocated
2715 //
2716 // RESPONSE: XXXXXX
2717 //      OK: address was deallocated
2718 //      EXX: error code
2719 //
2720 // EXAMPLES:
2721 //      _m123000
2722 
2723 rnb_err_t
2724 RNBRemote::HandlePacket_DeallocateMemory (const char *p)
2725 {
2726     StringExtractor packet (p);
2727     packet.SetFilePos(2); // Skip the "_m"
2728     nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
2729 
2730     if (addr != INVALID_NUB_ADDRESS)
2731     {
2732         if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
2733             return SendPacket ("OK");
2734     }
2735     return SendPacket ("E54");
2736 }
2737 
2738 
2739 // FORMAT: QSaveRegisterState;thread:TTTT;  (when thread suffix is supported)
2740 // FORMAT: QSaveRegisterState               (when thread suffix is NOT supported)
2741 //      TTTT: thread ID in hex
2742 //
2743 // RESPONSE:
2744 //      SAVEID: Where SAVEID is a decimal number that represents the save ID
2745 //              that can be passed back into a "QRestoreRegisterState" packet
2746 //      EXX: error code
2747 //
2748 // EXAMPLES:
2749 //      QSaveRegisterState;thread:1E34;     (when thread suffix is supported)
2750 //      QSaveRegisterState                  (when thread suffix is NOT supported)
2751 
2752 rnb_err_t
2753 RNBRemote::HandlePacket_SaveRegisterState (const char *p)
2754 {
2755     nub_process_t pid = m_ctx.ProcessID ();
2756     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2757     if (tid == INVALID_NUB_THREAD)
2758     {
2759         if (m_thread_suffix_supported)
2760             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
2761         else
2762             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
2763     }
2764 
2765     // Get the register context size first by calling with NULL buffer
2766     const uint32_t save_id = DNBThreadSaveRegisterState(pid, tid);
2767     if (save_id != 0)
2768     {
2769         char response[64];
2770         snprintf (response, sizeof(response), "%u", save_id);
2771         return SendPacket (response);
2772     }
2773     else
2774     {
2775         return SendPacket ("E75");
2776     }
2777 }
2778 // FORMAT: QRestoreRegisterState:SAVEID;thread:TTTT;  (when thread suffix is supported)
2779 // FORMAT: QRestoreRegisterState:SAVEID               (when thread suffix is NOT supported)
2780 //      TTTT: thread ID in hex
2781 //      SAVEID: a decimal number that represents the save ID that was
2782 //              returned from a call to "QSaveRegisterState"
2783 //
2784 // RESPONSE:
2785 //      OK: successfully restored registers for the specified thread
2786 //      EXX: error code
2787 //
2788 // EXAMPLES:
2789 //      QRestoreRegisterState:1;thread:1E34;     (when thread suffix is supported)
2790 //      QRestoreRegisterState:1                  (when thread suffix is NOT supported)
2791 
2792 rnb_err_t
2793 RNBRemote::HandlePacket_RestoreRegisterState (const char *p)
2794 {
2795     nub_process_t pid = m_ctx.ProcessID ();
2796     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2797     if (tid == INVALID_NUB_THREAD)
2798     {
2799         if (m_thread_suffix_supported)
2800             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in QSaveRegisterState packet");
2801         else
2802             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");
2803     }
2804 
2805     StringExtractor packet (p);
2806     packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:"
2807     const uint32_t save_id = packet.GetU32(0);
2808 
2809     if (save_id != 0)
2810     {
2811         // Get the register context size first by calling with NULL buffer
2812         if (DNBThreadRestoreRegisterState(pid, tid, save_id))
2813             return SendPacket ("OK");
2814         else
2815             return SendPacket ("E77");
2816     }
2817     return SendPacket ("E76");
2818 }
2819 
2820 static bool
2821 GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name)
2822 {
2823     bool return_val = true;
2824     while (*p != '\0')
2825     {
2826         char smallbuf[3];
2827         smallbuf[0] = *p;
2828         smallbuf[1] = *(p + 1);
2829         smallbuf[2] = '\0';
2830 
2831         errno = 0;
2832         int ch = strtoul (smallbuf, NULL, 16);
2833         if (errno != 0 && ch == 0)
2834         {
2835             return_val = false;
2836             break;
2837         }
2838 
2839         attach_name.push_back(ch);
2840         p += 2;
2841     }
2842     return return_val;
2843 }
2844 
2845 /*
2846  vAttach;pid
2847 
2848  Attach to a new process with the specified process ID. pid is a hexadecimal integer
2849  identifying the process. If the stub is currently controlling a process, it is
2850  killed. The attached process is stopped.This packet is only available in extended
2851  mode (see extended mode).
2852 
2853  Reply:
2854  "ENN"                      for an error
2855  "Any Stop Reply Packet"     for success
2856  */
2857 
2858 rnb_err_t
2859 RNBRemote::HandlePacket_v (const char *p)
2860 {
2861     if (strcmp (p, "vCont;c") == 0)
2862     {
2863         // Simple continue
2864         return RNBRemote::HandlePacket_c("c");
2865     }
2866     else if (strcmp (p, "vCont;s") == 0)
2867     {
2868         // Simple step
2869         return RNBRemote::HandlePacket_s("s");
2870     }
2871     else if (strstr (p, "vCont") == p)
2872     {
2873         typedef struct
2874         {
2875             nub_thread_t tid;
2876             char action;
2877             int signal;
2878         } vcont_action_t;
2879 
2880         DNBThreadResumeActions thread_actions;
2881         char *c = (char *)(p += strlen("vCont"));
2882         char *c_end = c + strlen(c);
2883         if (*c == '?')
2884             return SendPacket ("vCont;c;C;s;S");
2885 
2886         while (c < c_end && *c == ';')
2887         {
2888             ++c;    // Skip the semi-colon
2889             DNBThreadResumeAction thread_action;
2890             thread_action.tid = INVALID_NUB_THREAD;
2891             thread_action.state = eStateInvalid;
2892             thread_action.signal = 0;
2893             thread_action.addr = INVALID_NUB_ADDRESS;
2894 
2895             char action = *c++;
2896 
2897             switch (action)
2898             {
2899                 case 'C':
2900                     errno = 0;
2901                     thread_action.signal = strtoul (c, &c, 16);
2902                     if (errno != 0)
2903                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2904                     // Fall through to next case...
2905 
2906                 case 'c':
2907                     // Continue
2908                     thread_action.state = eStateRunning;
2909                     break;
2910 
2911                 case 'S':
2912                     errno = 0;
2913                     thread_action.signal = strtoul (c, &c, 16);
2914                     if (errno != 0)
2915                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2916                     // Fall through to next case...
2917 
2918                 case 's':
2919                     // Step
2920                     thread_action.state = eStateStepping;
2921                     break;
2922 
2923                 default:
2924                     HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
2925                     break;
2926             }
2927             if (*c == ':')
2928             {
2929                 errno = 0;
2930                 thread_action.tid = strtoul (++c, &c, 16);
2931                 if (errno != 0)
2932                     return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
2933             }
2934 
2935             thread_actions.Append (thread_action);
2936         }
2937 
2938         // If a default action for all other threads wasn't mentioned
2939         // then we should stop the threads
2940         thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
2941         DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
2942         return rnb_success;
2943     }
2944     else if (strstr (p, "vAttach") == p)
2945     {
2946         nub_process_t attach_pid = INVALID_NUB_PROCESS;
2947         char err_str[1024]={'\0'};
2948 
2949         if (strstr (p, "vAttachWait;") == p)
2950         {
2951             p += strlen("vAttachWait;");
2952             std::string attach_name;
2953             if (!GetProcessNameFrom_vAttach(p, attach_name))
2954             {
2955                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2956             }
2957             const bool ignore_existing = true;
2958             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2959 
2960         }
2961         else if (strstr (p, "vAttachOrWait;") == p)
2962         {
2963             p += strlen("vAttachOrWait;");
2964             std::string attach_name;
2965             if (!GetProcessNameFrom_vAttach(p, attach_name))
2966             {
2967                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt");
2968             }
2969             const bool ignore_existing = false;
2970             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2971         }
2972         else if (strstr (p, "vAttachName;") == p)
2973         {
2974             p += strlen("vAttachName;");
2975             std::string attach_name;
2976             if (!GetProcessNameFrom_vAttach(p, attach_name))
2977             {
2978                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
2979             }
2980 
2981             attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
2982 
2983         }
2984         else if (strstr (p, "vAttach;") == p)
2985         {
2986             p += strlen("vAttach;");
2987             char *end = NULL;
2988             attach_pid = strtoul (p, &end, 16);    // PID will be in hex, so use base 16 to decode
2989             if (p != end && *end == '\0')
2990             {
2991                 // Wait at most 30 second for attach
2992                 struct timespec attach_timeout_abstime;
2993                 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
2994                 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
2995             }
2996         }
2997         else
2998         {
2999             return HandlePacket_UNIMPLEMENTED(p);
3000         }
3001 
3002 
3003         if (attach_pid != INVALID_NUB_PROCESS)
3004         {
3005             if (m_ctx.ProcessID() != attach_pid)
3006                 m_ctx.SetProcessID(attach_pid);
3007             // Send a stop reply packet to indicate we successfully attached!
3008             NotifyThatProcessStopped ();
3009             return rnb_success;
3010         }
3011         else
3012         {
3013             m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
3014             if (err_str[0])
3015                 m_ctx.LaunchStatus().SetErrorString(err_str);
3016             else
3017                 m_ctx.LaunchStatus().SetErrorString("attach failed");
3018             SendPacket ("E01");  // E01 is our magic error value for attach failed.
3019             DNBLogError ("Attach failed: \"%s\".", err_str);
3020             return rnb_err;
3021         }
3022     }
3023 
3024     // All other failures come through here
3025     return HandlePacket_UNIMPLEMENTED(p);
3026 }
3027 
3028 /* 'T XX' -- status of thread
3029  Check if the specified thread is alive.
3030  The thread number is in hex?  */
3031 
3032 rnb_err_t
3033 RNBRemote::HandlePacket_T (const char *p)
3034 {
3035     p++;
3036     if (p == NULL || *p == '\0')
3037     {
3038         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
3039     }
3040     if (!m_ctx.HasValidProcessID())
3041     {
3042         return SendPacket ("E15");
3043     }
3044     errno = 0;
3045     nub_thread_t tid = strtoul (p, NULL, 16);
3046     if (errno != 0 && tid == 0)
3047     {
3048         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
3049     }
3050 
3051     nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
3052     if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
3053     {
3054         return SendPacket ("E16");
3055     }
3056 
3057     return SendPacket ("OK");
3058 }
3059 
3060 
3061 rnb_err_t
3062 RNBRemote::HandlePacket_z (const char *p)
3063 {
3064     if (p == NULL || *p == '\0')
3065         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
3066 
3067     if (!m_ctx.HasValidProcessID())
3068         return SendPacket ("E15");
3069 
3070     char packet_cmd = *p++;
3071     char break_type = *p++;
3072 
3073     if (*p++ != ',')
3074         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
3075 
3076     char *c = NULL;
3077     nub_process_t pid = m_ctx.ProcessID();
3078     errno = 0;
3079     nub_addr_t addr = strtoull (p, &c, 16);
3080     if (errno != 0 && addr == 0)
3081         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
3082     p = c;
3083     if (*p++ != ',')
3084         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
3085 
3086     errno = 0;
3087     uint32_t byte_size = strtoul (p, &c, 16);
3088     if (errno != 0 && byte_size == 0)
3089         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
3090 
3091     if (packet_cmd == 'Z')
3092     {
3093         // set
3094         switch (break_type)
3095         {
3096             case '0':   // set software breakpoint
3097             case '1':   // set hardware breakpoint
3098                 {
3099                     // gdb can send multiple Z packets for the same address and
3100                     // these calls must be ref counted.
3101                     bool hardware = (break_type == '1');
3102 
3103                     if (DNBBreakpointSet (pid, addr, byte_size, hardware))
3104                     {
3105                         // We successfully created a breakpoint, now lets full out
3106                         // a ref count structure with the breakID and add it to our
3107                         // map.
3108                         return SendPacket ("OK");
3109                     }
3110                     else
3111                     {
3112                         // We failed to set the software breakpoint
3113                         return SendPacket ("E09");
3114                     }
3115                 }
3116                 break;
3117 
3118             case '2':   // set write watchpoint
3119             case '3':   // set read watchpoint
3120             case '4':   // set access watchpoint
3121                 {
3122                     bool hardware = true;
3123                     uint32_t watch_flags = 0;
3124                     if (break_type == '2')
3125                         watch_flags = WATCH_TYPE_WRITE;
3126                     else if (break_type == '3')
3127                         watch_flags = WATCH_TYPE_READ;
3128                     else
3129                         watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
3130 
3131                     if (DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware))
3132                     {
3133                         return SendPacket ("OK");
3134                     }
3135                     else
3136                     {
3137                         // We failed to set the watchpoint
3138                         return SendPacket ("E09");
3139                     }
3140                 }
3141                 break;
3142 
3143             default:
3144                 break;
3145         }
3146     }
3147     else if (packet_cmd == 'z')
3148     {
3149         // remove
3150         switch (break_type)
3151         {
3152             case '0':   // remove software breakpoint
3153             case '1':   // remove hardware breakpoint
3154                 if (DNBBreakpointClear (pid, addr))
3155                 {
3156                     return SendPacket ("OK");
3157                 }
3158                 else
3159                 {
3160                     return SendPacket ("E08");
3161                 }
3162                 break;
3163 
3164             case '2':   // remove write watchpoint
3165             case '3':   // remove read watchpoint
3166             case '4':   // remove access watchpoint
3167                 if (DNBWatchpointClear (pid, addr))
3168                 {
3169                     return SendPacket ("OK");
3170                 }
3171                 else
3172                 {
3173                     return SendPacket ("E08");
3174                 }
3175                 break;
3176 
3177             default:
3178                 break;
3179         }
3180     }
3181     return HandlePacket_UNIMPLEMENTED(p);
3182 }
3183 
3184 // Extract the thread number from the thread suffix that might be appended to
3185 // thread specific packets. This will only be enabled if m_thread_suffix_supported
3186 // is true.
3187 nub_thread_t
3188 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
3189 {
3190     if (m_thread_suffix_supported)
3191     {
3192         nub_thread_t tid = INVALID_NUB_THREAD;
3193         if (p)
3194         {
3195             const char *tid_cstr = strstr (p, "thread:");
3196             if (tid_cstr)
3197             {
3198                 tid_cstr += strlen ("thread:");
3199                 tid = strtoul(tid_cstr, NULL, 16);
3200             }
3201         }
3202         return tid;
3203     }
3204     return GetCurrentThread();
3205 
3206 }
3207 
3208 /* 'p XX'
3209  print the contents of register X */
3210 
3211 rnb_err_t
3212 RNBRemote::HandlePacket_p (const char *p)
3213 {
3214     if (g_num_reg_entries == 0)
3215         InitializeRegisters ();
3216 
3217     if (p == NULL || *p == '\0')
3218     {
3219         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3220     }
3221     if (!m_ctx.HasValidProcessID())
3222     {
3223         return SendPacket ("E15");
3224     }
3225     nub_process_t pid = m_ctx.ProcessID();
3226     errno = 0;
3227     char *tid_cstr = NULL;
3228     uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
3229     if (errno != 0 && reg == 0)
3230     {
3231         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
3232     }
3233 
3234     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
3235     if (tid == INVALID_NUB_THREAD)
3236         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3237 
3238     const register_map_entry_t *reg_entry;
3239 
3240     if (reg < g_num_reg_entries)
3241         reg_entry = &g_reg_entries[reg];
3242     else
3243         reg_entry = NULL;
3244 
3245     std::ostringstream ostrm;
3246     if (reg_entry == NULL)
3247     {
3248         DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
3249         ostrm << "00000000";
3250     }
3251     else if (reg_entry->nub_info.reg == -1)
3252     {
3253         if (reg_entry->nub_info.size > 0)
3254         {
3255             std::basic_string<uint8_t> zeros(reg_entry->nub_info.size, '\0');
3256             append_hex_value(ostrm, zeros.data(), zeros.size(), false);
3257         }
3258     }
3259     else
3260     {
3261         register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL);
3262     }
3263     return SendPacket (ostrm.str());
3264 }
3265 
3266 /* 'Pnn=rrrrr'
3267  Set register number n to value r.
3268  n and r are hex strings.  */
3269 
3270 rnb_err_t
3271 RNBRemote::HandlePacket_P (const char *p)
3272 {
3273     if (g_num_reg_entries == 0)
3274         InitializeRegisters ();
3275 
3276     if (p == NULL || *p == '\0')
3277     {
3278         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
3279     }
3280     if (!m_ctx.HasValidProcessID())
3281     {
3282         return SendPacket ("E28");
3283     }
3284 
3285     nub_process_t pid = m_ctx.ProcessID();
3286 
3287     StringExtractor packet (p);
3288 
3289     const char cmd_char = packet.GetChar();
3290     // Register ID is always in big endian
3291     const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
3292     const char equal_char = packet.GetChar();
3293 
3294     if (cmd_char != 'P')
3295         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
3296 
3297     if (reg == UINT32_MAX)
3298         return SendPacket ("E29");
3299 
3300     if (equal_char != '=')
3301         return SendPacket ("E30");
3302 
3303     const register_map_entry_t *reg_entry;
3304 
3305     if (reg >= g_num_reg_entries)
3306         return SendPacket("E47");
3307 
3308     reg_entry = &g_reg_entries[reg];
3309 
3310     if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3311     {
3312         DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3313         return SendPacket("E48");
3314     }
3315 
3316     DNBRegisterValue reg_value;
3317     reg_value.info = reg_entry->nub_info;
3318     packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->nub_info.size, 0xcc);
3319 
3320     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3321     if (tid == INVALID_NUB_THREAD)
3322         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3323 
3324     if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3325     {
3326         return SendPacket ("E32");
3327     }
3328     return SendPacket ("OK");
3329 }
3330 
3331 /* 'c [addr]'
3332  Continue, optionally from a specified address. */
3333 
3334 rnb_err_t
3335 RNBRemote::HandlePacket_c (const char *p)
3336 {
3337     const nub_process_t pid = m_ctx.ProcessID();
3338 
3339     if (pid == INVALID_NUB_PROCESS)
3340         return SendPacket ("E23");
3341 
3342     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3343 
3344     if (*(p + 1) != '\0')
3345     {
3346         action.tid = GetContinueThread();
3347         errno = 0;
3348         action.addr = strtoull (p + 1, NULL, 16);
3349         if (errno != 0 && action.addr == 0)
3350             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
3351     }
3352 
3353     DNBThreadResumeActions thread_actions;
3354     thread_actions.Append(action);
3355     thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3356     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3357         return SendPacket ("E25");
3358     // Don't send an "OK" packet; response is the stopped/exited message.
3359     return rnb_success;
3360 }
3361 
3362 rnb_err_t
3363 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
3364 {
3365     /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code)
3366        for the memory region containing a given address and return that information.
3367 
3368        Users of this packet must be prepared for three results:
3369 
3370            Region information is returned
3371            Region information is unavailable for this address because the address is in unmapped memory
3372            Region lookup cannot be performed on this platform or process is not yet launched
3373            This packet isn't implemented
3374 
3375        Examples of use:
3376           qMemoryRegionInfo:3a55140
3377           start:3a50000,size:100000,permissions:rwx
3378 
3379           qMemoryRegionInfo:0
3380           error:address in unmapped region
3381 
3382           qMemoryRegionInfo:3a551140   (on a different platform)
3383           error:region lookup cannot be performed
3384 
3385           qMemoryRegionInfo
3386           OK                   // this packet is implemented by the remote nub
3387     */
3388 
3389     p += sizeof ("qMemoryRegionInfo") - 1;
3390     if (*p == '\0')
3391        return SendPacket ("OK");
3392     if (*p++ != ':')
3393        return SendPacket ("E67");
3394     if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
3395        p += 2;
3396 
3397     errno = 0;
3398     uint64_t address = strtoul (p, NULL, 16);
3399     if (errno != 0 && address == 0)
3400     {
3401         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
3402     }
3403 
3404     DNBRegionInfo region_info = { 0, 0, 0 };
3405     DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, &region_info);
3406     std::ostringstream ostrm;
3407 
3408         // start:3a50000,size:100000,permissions:rwx
3409     ostrm << "start:" << std::hex << region_info.addr << ';';
3410 
3411     if (region_info.size > 0)
3412         ostrm << "size:"  << std::hex << region_info.size << ';';
3413 
3414     if (region_info.permissions)
3415     {
3416         ostrm << "permissions:";
3417 
3418         if (region_info.permissions & eMemoryPermissionsReadable)
3419             ostrm << 'r';
3420         if (region_info.permissions & eMemoryPermissionsWritable)
3421             ostrm << 'w';
3422         if (region_info.permissions & eMemoryPermissionsExecutable)
3423             ostrm << 'x';
3424         ostrm << ';';
3425     }
3426     return SendPacket (ostrm.str());
3427 }
3428 
3429 // qGetProfileData;scan_type:0xYYYYYYY
3430 rnb_err_t
3431 RNBRemote::HandlePacket_GetProfileData (const char *p)
3432 {
3433     nub_process_t pid = m_ctx.ProcessID();
3434     if (pid == INVALID_NUB_PROCESS)
3435         return SendPacket ("OK");
3436 
3437     StringExtractor packet(p += sizeof ("qGetProfileData"));
3438     DNBProfileDataScanType scan_type = eProfileAll;
3439     std::string name;
3440     std::string value;
3441     while (packet.GetNameColonValue(name, value))
3442     {
3443         if (name.compare ("scan_type") == 0)
3444         {
3445             std::istringstream iss(value);
3446             uint32_t int_value = 0;
3447             if (iss >> std::hex >> int_value)
3448             {
3449                 scan_type = (DNBProfileDataScanType)int_value;
3450             }
3451         }
3452     }
3453 
3454     std::string data = DNBProcessGetProfileData(pid, scan_type);
3455     if (!data.empty())
3456     {
3457         return SendPacket (data.c_str());
3458     }
3459     else
3460     {
3461         return SendPacket ("OK");
3462     }
3463 }
3464 
3465 // QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY
3466 rnb_err_t
3467 RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
3468 {
3469     nub_process_t pid = m_ctx.ProcessID();
3470     if (pid == INVALID_NUB_PROCESS)
3471         return SendPacket ("OK");
3472 
3473     StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));
3474     bool enable = false;
3475     uint64_t interval_usec = 0;
3476     DNBProfileDataScanType scan_type = eProfileAll;
3477     std::string name;
3478     std::string value;
3479     while (packet.GetNameColonValue(name, value))
3480     {
3481         if (name.compare ("enable") == 0)
3482         {
3483             enable  = strtoul(value.c_str(), NULL, 10) > 0;
3484         }
3485         else if (name.compare ("interval_usec") == 0)
3486         {
3487             interval_usec  = strtoul(value.c_str(), NULL, 10);
3488         }
3489         else if (name.compare ("scan_type") == 0)
3490         {
3491             std::istringstream iss(value);
3492             uint32_t int_value = 0;
3493             if (iss >> std::hex >> int_value)
3494             {
3495                 scan_type = (DNBProfileDataScanType)int_value;
3496             }
3497         }
3498     }
3499 
3500     if (interval_usec == 0)
3501     {
3502         enable = 0;
3503     }
3504 
3505     DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type);
3506     return SendPacket ("OK");
3507 }
3508 
3509 
3510 rnb_err_t
3511 RNBRemote::HandlePacket_qSpeedTest (const char *p)
3512 {
3513     p += strlen ("qSpeedTest:response_size:");
3514     char *end = NULL;
3515     errno = 0;
3516     uint64_t response_size = ::strtoul (p, &end, 16);
3517     if (errno != 0)
3518         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Didn't find response_size value at right offset");
3519     else if (*end == ';')
3520     {
3521         static char g_data[4*1024*1024+16] = "data:";
3522         memset(g_data + 5, 'a', response_size);
3523         g_data[response_size + 5] = '\0';
3524         return SendPacket (g_data);
3525     }
3526     else
3527     {
3528         return SendPacket ("E79");
3529     }
3530 }
3531 
3532 rnb_err_t
3533 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p)
3534 {
3535     /* This packet simply returns the number of supported hardware watchpoints.
3536 
3537        Examples of use:
3538           qWatchpointSupportInfo:
3539           num:4
3540 
3541           qWatchpointSupportInfo
3542           OK                   // this packet is implemented by the remote nub
3543     */
3544 
3545     p += sizeof ("qWatchpointSupportInfo") - 1;
3546     if (*p == '\0')
3547        return SendPacket ("OK");
3548     if (*p++ != ':')
3549        return SendPacket ("E67");
3550 
3551     errno = 0;
3552     uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID());
3553     std::ostringstream ostrm;
3554 
3555     // size:4
3556     ostrm << "num:" << std::dec << num << ';';
3557     return SendPacket (ostrm.str());
3558 }
3559 
3560 /* 'C sig [;addr]'
3561  Resume with signal sig, optionally at address addr.  */
3562 
3563 rnb_err_t
3564 RNBRemote::HandlePacket_C (const char *p)
3565 {
3566     const nub_process_t pid = m_ctx.ProcessID();
3567 
3568     if (pid == INVALID_NUB_PROCESS)
3569         return SendPacket ("E36");
3570 
3571     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3572     int process_signo = -1;
3573     if (*(p + 1) != '\0')
3574     {
3575         action.tid = GetContinueThread();
3576         char *end = NULL;
3577         errno = 0;
3578         process_signo = strtoul (p + 1, &end, 16);
3579         if (errno != 0)
3580             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
3581         else if (*end == ';')
3582         {
3583             errno = 0;
3584             action.addr = strtoull (end + 1, NULL, 16);
3585             if (errno != 0 && action.addr == 0)
3586                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
3587         }
3588     }
3589 
3590     DNBThreadResumeActions thread_actions;
3591     thread_actions.Append (action);
3592     thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
3593     if (!DNBProcessSignal(pid, process_signo))
3594         return SendPacket ("E52");
3595     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3596         return SendPacket ("E38");
3597     /* Don't send an "OK" packet; response is the stopped/exited message.  */
3598     return rnb_success;
3599 }
3600 
3601 //----------------------------------------------------------------------
3602 // 'D' packet
3603 // Detach from gdb.
3604 //----------------------------------------------------------------------
3605 rnb_err_t
3606 RNBRemote::HandlePacket_D (const char *p)
3607 {
3608     SendPacket ("OK");
3609     if (m_ctx.HasValidProcessID())
3610         DNBProcessDetach(m_ctx.ProcessID());
3611     return rnb_success;
3612 }
3613 
3614 /* 'k'
3615  Kill the inferior process.  */
3616 
3617 rnb_err_t
3618 RNBRemote::HandlePacket_k (const char *p)
3619 {
3620     DNBLog ("Got a 'k' packet, killing the inferior process.");
3621     // No response to should be sent to the kill packet
3622     if (m_ctx.HasValidProcessID())
3623         DNBProcessKill (m_ctx.ProcessID());
3624     SendPacket ("W09");
3625     return rnb_success;
3626 }
3627 
3628 rnb_err_t
3629 RNBRemote::HandlePacket_stop_process (const char *p)
3630 {
3631 //#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt
3632 #if defined(TEST_EXIT_ON_INTERRUPT)
3633     rnb_err_t err = HandlePacket_k (p);
3634     m_comm.Disconnect(true);
3635     return err;
3636 #else
3637     DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
3638     //DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
3639     // Do not send any response packet! Wait for the stop reply packet to naturally happen
3640     return rnb_success;
3641 #endif
3642 }
3643 
3644 /* 's'
3645  Step the inferior process.  */
3646 
3647 rnb_err_t
3648 RNBRemote::HandlePacket_s (const char *p)
3649 {
3650     const nub_process_t pid = m_ctx.ProcessID();
3651     if (pid == INVALID_NUB_PROCESS)
3652         return SendPacket ("E32");
3653 
3654     // Hardware supported stepping not supported on arm
3655     nub_thread_t tid = GetContinueThread ();
3656     if (tid == 0 || tid == -1)
3657         tid = GetCurrentThread();
3658 
3659     if (tid == INVALID_NUB_THREAD)
3660         return SendPacket ("E33");
3661 
3662     DNBThreadResumeActions thread_actions;
3663     thread_actions.AppendAction(tid, eStateStepping);
3664 
3665     // Make all other threads stop when we are stepping
3666     thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3667     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3668         return SendPacket ("E49");
3669     // Don't send an "OK" packet; response is the stopped/exited message.
3670     return rnb_success;
3671 }
3672 
3673 /* 'S sig [;addr]'
3674  Step with signal sig, optionally at address addr.  */
3675 
3676 rnb_err_t
3677 RNBRemote::HandlePacket_S (const char *p)
3678 {
3679     const nub_process_t pid = m_ctx.ProcessID();
3680     if (pid == INVALID_NUB_PROCESS)
3681         return SendPacket ("E36");
3682 
3683     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
3684 
3685     if (*(p + 1) != '\0')
3686     {
3687         char *end = NULL;
3688         errno = 0;
3689         action.signal = strtoul (p + 1, &end, 16);
3690         if (errno != 0)
3691             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
3692         else if (*end == ';')
3693         {
3694             errno = 0;
3695             action.addr = strtoull (end + 1, NULL, 16);
3696             if (errno != 0 && action.addr == 0)
3697             {
3698                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
3699             }
3700         }
3701     }
3702 
3703     action.tid = GetContinueThread ();
3704     if (action.tid == 0 || action.tid == -1)
3705         return SendPacket ("E40");
3706 
3707     nub_state_t tstate = DNBThreadGetState (pid, action.tid);
3708     if (tstate == eStateInvalid || tstate == eStateExited)
3709         return SendPacket ("E37");
3710 
3711 
3712     DNBThreadResumeActions thread_actions;
3713     thread_actions.Append (action);
3714 
3715     // Make all other threads stop when we are stepping
3716     thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
3717     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3718         return SendPacket ("E39");
3719 
3720     // Don't send an "OK" packet; response is the stopped/exited message.
3721     return rnb_success;
3722 }
3723 
3724 rnb_err_t
3725 RNBRemote::HandlePacket_qHostInfo (const char *p)
3726 {
3727     std::ostringstream strm;
3728 
3729     uint32_t cputype, is_64_bit_capable;
3730     size_t len = sizeof(cputype);
3731     bool promoted_to_64 = false;
3732     if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
3733     {
3734         len = sizeof (is_64_bit_capable);
3735         if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
3736         {
3737             if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
3738             {
3739                 promoted_to_64 = true;
3740                 cputype |= CPU_ARCH_ABI64;
3741             }
3742         }
3743 
3744         strm << "cputype:" << std::dec << cputype << ';';
3745     }
3746 
3747     uint32_t cpusubtype;
3748     len = sizeof(cpusubtype);
3749     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
3750     {
3751         if (promoted_to_64 &&
3752             cputype == CPU_TYPE_X86_64 &&
3753             cpusubtype == CPU_SUBTYPE_486)
3754             cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3755 
3756         strm << "cpusubtype:" << std::dec << cpusubtype << ';';
3757     }
3758 
3759     // The OS in the triple should be "ios" or "macosx" which doesn't match our
3760     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
3761     // this for now.
3762     if (cputype == CPU_TYPE_ARM)
3763     {
3764         strm << "ostype:ios;";
3765         // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
3766         strm << "watchpoint_exceptions_received:before;";
3767     }
3768     else
3769     {
3770         strm << "ostype:macosx;";
3771         strm << "watchpoint_exceptions_received:after;";
3772     }
3773 //    char ostype[64];
3774 //    len = sizeof(ostype);
3775 //    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
3776 //    {
3777 //        len = strlen(ostype);
3778 //        std::transform (ostype, ostype + len, ostype, tolower);
3779 //        strm << "ostype:" << std::dec << ostype << ';';
3780 //    }
3781 
3782     strm << "vendor:apple;";
3783 
3784 #if defined (__LITTLE_ENDIAN__)
3785     strm << "endian:little;";
3786 #elif defined (__BIG_ENDIAN__)
3787     strm << "endian:big;";
3788 #elif defined (__PDP_ENDIAN__)
3789     strm << "endian:pdp;";
3790 #endif
3791 
3792     if (promoted_to_64)
3793         strm << "ptrsize:8;";
3794     else
3795         strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
3796     return SendPacket (strm.str());
3797 }
3798 
3799 rnb_err_t
3800 RNBRemote::HandlePacket_qGDBServerVersion (const char *p)
3801 {
3802     std::ostringstream strm;
3803 
3804     if (DEBUGSERVER_PROGRAM_NAME)
3805         strm << "name:" DEBUGSERVER_PROGRAM_NAME ";";
3806     else
3807         strm << "name:debugserver;";
3808     strm << "version:" << DEBUGSERVER_VERSION_STR << ";";
3809 
3810     return SendPacket (strm.str());
3811 }
3812 
3813 // Note that all numeric values returned by qProcessInfo are hex encoded,
3814 // including the pid and the cpu type.
3815 
3816 rnb_err_t
3817 RNBRemote::HandlePacket_qProcessInfo (const char *p)
3818 {
3819     nub_process_t pid;
3820     std::ostringstream rep;
3821 
3822     // If we haven't run the process yet, return an error.
3823     if (!m_ctx.HasValidProcessID())
3824         return SendPacket ("E68");
3825 
3826     pid = m_ctx.ProcessID();
3827 
3828     rep << "pid:" << std::hex << pid << ";";
3829 
3830     int procpid_mib[4];
3831     procpid_mib[0] = CTL_KERN;
3832     procpid_mib[1] = KERN_PROC;
3833     procpid_mib[2] = KERN_PROC_PID;
3834     procpid_mib[3] = pid;
3835     struct kinfo_proc proc_kinfo;
3836     size_t proc_kinfo_size = sizeof(struct kinfo_proc);
3837 
3838     if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
3839     {
3840         if (proc_kinfo_size > 0)
3841         {
3842             rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";";
3843             rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";";
3844             rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";";
3845             rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";";
3846             if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
3847                 rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";";
3848         }
3849     }
3850 
3851     cpu_type_t cputype = DNBProcessGetCPUType (pid);
3852     if (cputype == 0)
3853     {
3854         DNBLog ("Unable to get the process cpu_type, making a best guess.");
3855         cputype = best_guess_cpu_type();
3856     }
3857 
3858     if (cputype != 0)
3859     {
3860         rep << "cputype:" << std::hex << cputype << ";";
3861     }
3862 
3863     uint32_t cpusubtype;
3864     size_t cpusubtype_len = sizeof(cpusubtype);
3865     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
3866     {
3867         if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486)
3868         {
3869             cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3870         }
3871 
3872         rep << "cpusubtype:" << std::hex << cpusubtype << ';';
3873     }
3874 
3875     // The OS in the triple should be "ios" or "macosx" which doesn't match our
3876     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
3877     // this for now.
3878     if (cputype == CPU_TYPE_ARM)
3879         rep << "ostype:ios;";
3880     else
3881         rep << "ostype:macosx;";
3882 
3883     rep << "vendor:apple;";
3884 
3885 #if defined (__LITTLE_ENDIAN__)
3886     rep << "endian:little;";
3887 #elif defined (__BIG_ENDIAN__)
3888     rep << "endian:big;";
3889 #elif defined (__PDP_ENDIAN__)
3890     rep << "endian:pdp;";
3891 #endif
3892 
3893 #if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
3894     nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
3895     kern_return_t kr;
3896     x86_thread_state_t gp_regs;
3897     mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
3898     kr = thread_get_state (thread, x86_THREAD_STATE,
3899                            (thread_state_t) &gp_regs, &gp_count);
3900     if (kr == KERN_SUCCESS)
3901     {
3902         if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
3903             rep << "ptrsize:8;";
3904         else
3905             rep << "ptrsize:4;";
3906     }
3907 #elif defined (__arm__)
3908     rep << "ptrsize:4;";
3909 #endif
3910 
3911     return SendPacket (rep.str());
3912 }
3913 
3914