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