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