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