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