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