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