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 fucntion
101     //          - If no response is needed for a command, then use NULL for the normal callback
102     //          - If the packet is not supported while the target is running, use NULL for the async callback
103     // 4 - If the packet is a standard packet (starts with a '$' character
104     //      followed by the payload and then '#' and checksum, then you are done
105     //      else go on to step 5
106     // 5 - if the packet is a fixed length packet:
107     //      - modify the switch statement for the first character in the payload
108     //        in RNBRemote::CommDataReceived so it doesn't reject the new packet
109     //        type as invalid
110     //      - modify the switch statement for the first character in the payload
111     //        in RNBRemote::GetPacketPayload and make sure the payload of the packet
112     //        is returned correctly
113 
114     std::vector <Packet> &t = m_packets;
115     t.push_back (Packet (ack,                           NULL,                                   NULL, "+", "ACK"));
116     t.push_back (Packet (nack,                          NULL,                                   NULL, "-", "!ACK"));
117     t.push_back (Packet (read_memory,                   &RNBRemote::HandlePacket_m,             NULL, "m", "Read memory"));
118     t.push_back (Packet (read_register,                 &RNBRemote::HandlePacket_p,             NULL, "p", "Read one register"));
119     t.push_back (Packet (read_general_regs,             &RNBRemote::HandlePacket_g,             NULL, "g", "Read registers"));
120     t.push_back (Packet (write_memory,                  &RNBRemote::HandlePacket_M,             NULL, "M", "Write memory"));
121     t.push_back (Packet (write_register,                &RNBRemote::HandlePacket_P,             NULL, "P", "Write one register"));
122     t.push_back (Packet (write_general_regs,            &RNBRemote::HandlePacket_G,             NULL, "G", "Write registers"));
123     t.push_back (Packet (insert_mem_bp,                 &RNBRemote::HandlePacket_z,             NULL, "Z0", "Insert memory breakpoint"));
124     t.push_back (Packet (remove_mem_bp,                 &RNBRemote::HandlePacket_z,             NULL, "z0", "Remove memory breakpoint"));
125     t.push_back (Packet (single_step,                   &RNBRemote::HandlePacket_s,             NULL, "s", "Single step"));
126     t.push_back (Packet (cont,                          &RNBRemote::HandlePacket_c,             NULL, "c", "continue"));
127     t.push_back (Packet (single_step_with_sig,          &RNBRemote::HandlePacket_S,             NULL, "S", "Single step with signal"));
128     t.push_back (Packet (set_thread,                    &RNBRemote::HandlePacket_H,             NULL, "H", "Set thread"));
129     t.push_back (Packet (halt,                          &RNBRemote::HandlePacket_last_signal,   &RNBRemote::HandlePacket_stop_process, "\x03", "^C"));
130 //  t.push_back (Packet (use_extended_mode,             &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "!", "Use extended mode"));
131     t.push_back (Packet (why_halted,                    &RNBRemote::HandlePacket_last_signal,   NULL, "?", "Why did target halt"));
132     t.push_back (Packet (set_argv,                      &RNBRemote::HandlePacket_A,             NULL, "A", "Set argv"));
133 //  t.push_back (Packet (set_bp,                        &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "B", "Set/clear breakpoint"));
134     t.push_back (Packet (continue_with_sig,             &RNBRemote::HandlePacket_C,             NULL, "C", "Continue with signal"));
135     t.push_back (Packet (detach,                        &RNBRemote::HandlePacket_D,             NULL, "D", "Detach gdb from remote system"));
136 //  t.push_back (Packet (step_inferior_one_cycle,       &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "i", "Step inferior by one clock cycle"));
137 //  t.push_back (Packet (signal_and_step_inf_one_cycle, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "I", "Signal inferior, then step one clock cyle"));
138     t.push_back (Packet (kill,                          &RNBRemote::HandlePacket_k,             NULL, "k", "Kill"));
139 //  t.push_back (Packet (restart,                       &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "R", "Restart inferior"));
140 //  t.push_back (Packet (search_mem_backwards,          &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "t", "Search memory backwards"));
141     t.push_back (Packet (thread_alive_p,                &RNBRemote::HandlePacket_T,             NULL, "T", "Is thread alive"));
142     t.push_back (Packet (vattach,                       &RNBRemote::HandlePacket_v,             NULL, "vAttach", "Attach to a new process"));
143     t.push_back (Packet (vattachwait,                   &RNBRemote::HandlePacket_v,             NULL, "vAttachWait", "Wait for a process to start up then attach to it"));
144     t.push_back (Packet (vattachname,                   &RNBRemote::HandlePacket_v,             NULL, "vAttachName", "Attach to an existing process by name"));
145     t.push_back (Packet (vcont_list_actions,            &RNBRemote::HandlePacket_v,             NULL, "vCont;", "Verbose resume with thread actions"));
146     t.push_back (Packet (vcont_list_actions,            &RNBRemote::HandlePacket_v,             NULL, "vCont?", "List valid continue-with-thread-actions actions"));
147     // The X packet doesn't currently work. If/when it does, remove the line above and uncomment out the line below
148 //  t.push_back (Packet (write_data_to_memory,          &RNBRemote::HandlePacket_X,             NULL, "X", "Write data to memory"));
149 //  t.push_back (Packet (insert_hardware_bp,            &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "Z1", "Insert hardware breakpoint"));
150 //  t.push_back (Packet (remove_hardware_bp,            &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "z1", "Remove hardware breakpoint"));
151     t.push_back (Packet (insert_write_watch_bp,         &RNBRemote::HandlePacket_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 + 2 > 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 += 2 + 1;
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 == ';')
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 {
2033     if (reg != NULL)
2034     {
2035         DNBRegisterValue val;
2036         if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &val))
2037         {
2038             append_hex_value (ostrm, val.value.v_uint8, reg->gdb_size, false);
2039         }
2040         else
2041         {
2042             // If we fail to read a regiser value, check if it has a default
2043             // fail value. If it does, return this instead in case some of
2044             // the registers are not available on the current system.
2045             if (reg->gdb_size > 0)
2046             {
2047                 if (reg->fail_value != NULL)
2048                 {
2049                     append_hex_value (ostrm, reg->fail_value, reg->gdb_size, false);
2050                 }
2051                 else
2052                 {
2053                     std::basic_string<uint8_t> zeros(reg->gdb_size, '\0');
2054                     append_hex_value (ostrm, zeros.data(), zeros.size(), false);
2055                 }
2056             }
2057         }
2058     }
2059 }
2060 
2061 
2062 void
2063 gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
2064                                                 nub_process_t pid,
2065                                                 nub_thread_t tid,
2066                                                 const register_map_entry_t* reg)
2067 {
2068     // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
2069     // gdb register number, and VVVVVVVV is the correct number of hex bytes
2070     // as ASCII for the register value.
2071     if (reg != NULL)
2072     {
2073         ostrm << RAWHEX8(reg->gdb_regnum) << ':';
2074         register_value_in_hex_fixed_width (ostrm, pid, tid, reg);
2075         ostrm << ';';
2076     }
2077 }
2078 
2079 rnb_err_t
2080 RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
2081 {
2082     const nub_process_t pid = m_ctx.ProcessID();
2083     if (pid == INVALID_NUB_PROCESS)
2084         return SendPacket("E50");
2085 
2086     struct DNBThreadStopInfo tid_stop_info;
2087 
2088     /* Fill the remaining space in this packet with as many registers
2089      as we can stuff in there.  */
2090 
2091     if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
2092     {
2093         std::ostringstream ostrm;
2094         // Output the T packet with the thread
2095         ostrm << 'T';
2096         int signum = tid_stop_info.details.signal.signo;
2097         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);
2098 
2099         // Translate any mach exceptions to gdb versions, unless they are
2100         // common exceptions like a breakpoint or a soft signal.
2101         switch (tid_stop_info.details.exception.type)
2102         {
2103             default:                    signum = 0; break;
2104             case EXC_BREAKPOINT:        signum = SIGTRAP; break;
2105             case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2106             case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2107             case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2108             case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2109             case EXC_SOFTWARE:
2110                 if (tid_stop_info.details.exception.data_count == 2 &&
2111                     tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2112                     signum = tid_stop_info.details.exception.data[1];
2113                 else
2114                     signum = TARGET_EXC_SOFTWARE;
2115                 break;
2116         }
2117 
2118         ostrm << RAWHEX8(signum & 0xff);
2119 
2120         ostrm << std::hex << "thread:" << tid << ';';
2121 
2122         const char *thread_name = DNBThreadGetName (pid, tid);
2123         if (thread_name && thread_name[0])
2124         {
2125             size_t thread_name_len = strlen(thread_name);
2126 
2127             if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2128                 ostrm << std::hex << "name:" << thread_name << ';';
2129             else
2130             {
2131                 // the thread name contains special chars, send as hex bytes
2132                 ostrm << std::hex << "hexname:";
2133                 uint8_t *u_thread_name = (uint8_t *)thread_name;
2134                 for (int i = 0; i < thread_name_len; i++)
2135                     ostrm << RAWHEX8(u_thread_name[i]);
2136                 ostrm << ';';
2137             }
2138         }
2139 
2140         thread_identifier_info_data_t thread_ident_info;
2141         if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
2142         {
2143             if (thread_ident_info.dispatch_qaddr != 0)
2144                 ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
2145         }
2146 
2147         // If a 'QListThreadsInStopReply' was sent to enable this feature, we
2148         // will send all thread IDs back in the "threads" key whose value is
2149         // a listc of hex thread IDs separated by commas:
2150         //  "threads:10a,10b,10c;"
2151         // This will save the debugger from having to send a pair of qfThreadInfo
2152         // and qsThreadInfo packets, but it also might take a lot of room in the
2153         // stop reply packet, so it must be enabled only on systems where there
2154         // are no limits on packet lengths.
2155 
2156         if (m_list_threads_in_stop_reply)
2157         {
2158             const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
2159             if (numthreads > 0)
2160             {
2161                 ostrm << std::hex << "threads:";
2162                 for (nub_size_t i = 0; i < numthreads; ++i)
2163                 {
2164                     nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
2165                     if (i > 0)
2166                         ostrm << ',';
2167                     ostrm << std::hex << th;
2168                 }
2169                 ostrm << ';';
2170             }
2171         }
2172 
2173         if (g_num_reg_entries == 0)
2174             InitializeRegisters ();
2175 
2176         DNBRegisterValue reg_value;
2177         for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2178         {
2179             if (g_reg_entries[reg].expedite)
2180             {
2181                 if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
2182                     continue;
2183 
2184                 gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg]);
2185             }
2186         }
2187 
2188         if (tid_stop_info.details.exception.type)
2189         {
2190             ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";";
2191             ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";";
2192             for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
2193                 ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";";
2194         }
2195         return SendPacket (ostrm.str ());
2196     }
2197     return SendPacket("E51");
2198 }
2199 
2200 /* '?'
2201  The stop reply packet - tell gdb what the status of the inferior is.
2202  Often called the questionmark_packet.  */
2203 
2204 rnb_err_t
2205 RNBRemote::HandlePacket_last_signal (const char *unused)
2206 {
2207     if (!m_ctx.HasValidProcessID())
2208     {
2209         // Inferior is not yet specified/running
2210         return SendPacket ("E02");
2211     }
2212 
2213     nub_process_t pid = m_ctx.ProcessID();
2214     nub_state_t pid_state = DNBProcessGetState (pid);
2215 
2216     switch (pid_state)
2217     {
2218         case eStateAttaching:
2219         case eStateLaunching:
2220         case eStateRunning:
2221         case eStateStepping:
2222         case eStateDetached:
2223             return rnb_success;  // Ignore
2224 
2225         case eStateSuspended:
2226         case eStateStopped:
2227         case eStateCrashed:
2228             {
2229                 nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2230                 // Make sure we set the current thread so g and p packets return
2231                 // the data the gdb will expect.
2232                 SetCurrentThread (tid);
2233 
2234                 SendStopReplyPacketForThread (tid);
2235             }
2236             break;
2237 
2238         case eStateInvalid:
2239         case eStateUnloaded:
2240         case eStateExited:
2241             {
2242                 char pid_exited_packet[16] = "";
2243                 int pid_status = 0;
2244                 // Process exited with exit status
2245                 if (!DNBProcessGetExitStatus(pid, &pid_status))
2246                     pid_status = 0;
2247 
2248                 if (pid_status)
2249                 {
2250                     if (WIFEXITED (pid_status))
2251                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2252                     else if (WIFSIGNALED (pid_status))
2253                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2254                     else if (WIFSTOPPED (pid_status))
2255                         snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2256                 }
2257 
2258                 // If we have an empty exit packet, lets fill one in to be safe.
2259                 if (!pid_exited_packet[0])
2260                 {
2261                     strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2262                     pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2263                 }
2264 
2265                 return SendPacket (pid_exited_packet);
2266             }
2267             break;
2268     }
2269     return rnb_success;
2270 }
2271 
2272 rnb_err_t
2273 RNBRemote::HandlePacket_M (const char *p)
2274 {
2275     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2276     {
2277         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2278     }
2279 
2280     char *c;
2281     p++;
2282     errno = 0;
2283     nub_addr_t addr = strtoull (p, &c, 16);
2284     if (errno != 0 && addr == 0)
2285     {
2286         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2287     }
2288     if (*c != ',')
2289     {
2290         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2291     }
2292 
2293     /* Advance 'p' to the length part of the packet.  */
2294     p += (c - p) + 1;
2295 
2296     errno = 0;
2297     uint32_t length = strtoul (p, &c, 16);
2298     if (errno != 0 && length == 0)
2299     {
2300         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2301     }
2302     if (length == 0)
2303     {
2304         return SendPacket ("OK");
2305     }
2306 
2307     if (*c != ':')
2308     {
2309         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2310     }
2311     /* Advance 'p' to the data part of the packet.  */
2312     p += (c - p) + 1;
2313 
2314     int datalen = strlen (p);
2315     if (datalen & 0x1)
2316     {
2317         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2318     }
2319     if (datalen == 0)
2320     {
2321         return SendPacket ("OK");
2322     }
2323 
2324     uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2325     uint8_t *i = buf;
2326 
2327     while (*p != '\0' && *(p + 1) != '\0')
2328     {
2329         char hexbuf[3];
2330         hexbuf[0] = *p;
2331         hexbuf[1] = *(p + 1);
2332         hexbuf[2] = '\0';
2333         errno = 0;
2334         uint8_t byte = strtoul (hexbuf, NULL, 16);
2335         if (errno != 0 && byte == 0)
2336         {
2337             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2338         }
2339         *i++ = byte;
2340         p += 2;
2341     }
2342 
2343     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2344     if (wrote != length)
2345         return SendPacket ("E09");
2346     else
2347         return SendPacket ("OK");
2348 }
2349 
2350 
2351 rnb_err_t
2352 RNBRemote::HandlePacket_m (const char *p)
2353 {
2354     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2355     {
2356         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
2357     }
2358 
2359     char *c;
2360     p++;
2361     errno = 0;
2362     nub_addr_t addr = strtoull (p, &c, 16);
2363     if (errno != 0 && addr == 0)
2364     {
2365         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
2366     }
2367     if (*c != ',')
2368     {
2369         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
2370     }
2371 
2372     /* Advance 'p' to the length part of the packet.  */
2373     p += (c - p) + 1;
2374 
2375     errno = 0;
2376     uint32_t length = strtoul (p, NULL, 16);
2377     if (errno != 0 && length == 0)
2378     {
2379         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2380     }
2381     if (length == 0)
2382     {
2383         return SendPacket ("");
2384     }
2385 
2386     uint8_t buf[length];
2387     int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf);
2388     if (bytes_read == 0)
2389     {
2390         return SendPacket ("E08");
2391     }
2392 
2393     // "The reply may contain fewer bytes than requested if the server was able
2394     //  to read only part of the region of memory."
2395     length = bytes_read;
2396 
2397     std::ostringstream ostrm;
2398     for (int i = 0; i < length; i++)
2399         ostrm << RAWHEX8(buf[i]);
2400     return SendPacket (ostrm.str ());
2401 }
2402 
2403 rnb_err_t
2404 RNBRemote::HandlePacket_X (const char *p)
2405 {
2406     if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2407     {
2408         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
2409     }
2410 
2411     char *c;
2412     p++;
2413     errno = 0;
2414     nub_addr_t addr = strtoull (p, &c, 16);
2415     if (errno != 0 && addr == 0)
2416     {
2417         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
2418     }
2419     if (*c != ',')
2420     {
2421         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
2422     }
2423 
2424     /* Advance 'p' to the length part of the packet.  */
2425     p += (c - p) + 1;
2426 
2427     errno = 0;
2428     int length = strtoul (p, NULL, 16);
2429     if (errno != 0 && length == 0)
2430     {
2431         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2432     }
2433 
2434     // I think gdb sends a zero length write request to test whether this
2435     // packet is accepted.
2436     if (length == 0)
2437     {
2438         return SendPacket ("OK");
2439     }
2440 
2441     std::vector<uint8_t> data = decode_binary_data (c, -1);
2442     std::vector<uint8_t>::const_iterator it;
2443     uint8_t *buf = (uint8_t *) alloca (data.size ());
2444     uint8_t *i = buf;
2445     for (it = data.begin (); it != data.end (); ++it)
2446     {
2447         *i++ = *it;
2448     }
2449 
2450     nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
2451     if (wrote != data.size ())
2452         return SendPacket ("E08");
2453     return SendPacket ("OK");
2454 }
2455 
2456 /* 'g' -- read registers
2457  Get the contents of the registers for the current thread,
2458  send them to gdb.
2459  Should the setting of the Hg packet determine which thread's registers
2460  are returned?  */
2461 
2462 rnb_err_t
2463 RNBRemote::HandlePacket_g (const char *p)
2464 {
2465     std::ostringstream ostrm;
2466     if (!m_ctx.HasValidProcessID())
2467     {
2468         return SendPacket ("E11");
2469     }
2470 
2471     if (g_num_reg_entries == 0)
2472         InitializeRegisters ();
2473 
2474     nub_process_t pid = m_ctx.ProcessID ();
2475     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
2476     if (tid == INVALID_NUB_THREAD)
2477         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2478 
2479     if (m_use_native_regs)
2480     {
2481         // Get the register context size first by calling with NULL buffer
2482         nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2483         if (reg_ctx_size)
2484         {
2485             // Now allocate enough space for the entire register context
2486             std::vector<uint8_t> reg_ctx;
2487             reg_ctx.resize(reg_ctx_size);
2488             // Now read the register context
2489             reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
2490             if (reg_ctx_size)
2491             {
2492                 append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
2493                 return SendPacket (ostrm.str ());
2494             }
2495         }
2496     }
2497 
2498     for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2499         register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg]);
2500 
2501     return SendPacket (ostrm.str ());
2502 }
2503 
2504 /* 'G XXX...' -- write registers
2505  How is the thread for these specified, beyond "the current thread"?
2506  Does gdb actually use the Hg packet to set this?  */
2507 
2508 rnb_err_t
2509 RNBRemote::HandlePacket_G (const char *p)
2510 {
2511     if (!m_ctx.HasValidProcessID())
2512     {
2513         return SendPacket ("E11");
2514     }
2515 
2516     if (g_num_reg_entries == 0)
2517         InitializeRegisters ();
2518 
2519     StringExtractor packet(p);
2520     packet.SetFilePos(1); // Skip the 'G'
2521 
2522     nub_process_t pid = m_ctx.ProcessID();
2523     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2524     if (tid == INVALID_NUB_THREAD)
2525         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2526 
2527     if (m_use_native_regs)
2528     {
2529         // Get the register context size first by calling with NULL buffer
2530         nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2531         if (reg_ctx_size)
2532         {
2533             // Now allocate enough space for the entire register context
2534             std::vector<uint8_t> reg_ctx;
2535             reg_ctx.resize(reg_ctx_size);
2536 
2537             const nub_size_t bytes_extracted = packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc);
2538             if (bytes_extracted == reg_ctx.size())
2539             {
2540                 // Now write the register context
2541                 reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
2542                 if (reg_ctx_size == reg_ctx.size())
2543                     return SendPacket ("OK");
2544                 else
2545                     return SendPacket ("E55");
2546             }
2547             else
2548             {
2549                 DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %zu of %zu bytes, size mismatch\n", p, bytes_extracted, reg_ctx_size);
2550                 return SendPacket ("E64");
2551             }
2552         }
2553         else
2554             return SendPacket ("E65");
2555     }
2556 
2557 
2558     DNBRegisterValue reg_value;
2559     for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2560     {
2561         const register_map_entry_t *reg_entry = &g_reg_entries[reg];
2562 
2563         reg_value.info = reg_entry->nub_info;
2564         if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size)
2565             break;
2566 
2567         if (reg_entry->fail_value == NULL)
2568         {
2569             if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
2570                 return SendPacket ("E15");
2571         }
2572     }
2573     return SendPacket ("OK");
2574 }
2575 
2576 static bool
2577 RNBRemoteShouldCancelCallback (void *not_used)
2578 {
2579     RNBRemoteSP remoteSP(g_remoteSP);
2580     if (remoteSP.get() != NULL)
2581     {
2582         RNBRemote* remote = remoteSP.get();
2583         if (remote->Comm().IsConnected())
2584             return false;
2585         else
2586             return true;
2587     }
2588     return true;
2589 }
2590 
2591 
2592 // FORMAT: _MXXXXXX,PPP
2593 //      XXXXXX: big endian hex chars
2594 //      PPP: permissions can be any combo of r w x chars
2595 //
2596 // RESPONSE: XXXXXX
2597 //      XXXXXX: hex address of the newly allocated memory
2598 //      EXX: error code
2599 //
2600 // EXAMPLES:
2601 //      _M123000,rw
2602 //      _M123000,rwx
2603 //      _M123000,xw
2604 
2605 rnb_err_t
2606 RNBRemote::HandlePacket_AllocateMemory (const char *p)
2607 {
2608     StringExtractor packet (p);
2609     packet.SetFilePos(2); // Skip the "_M"
2610 
2611     nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
2612     if (size != 0)
2613     {
2614         if (packet.GetChar() == ',')
2615         {
2616             uint32_t permissions = 0;
2617             char ch;
2618             bool success = true;
2619             while (success && (ch = packet.GetChar()) != '\0')
2620             {
2621                 switch (ch)
2622                 {
2623                 case 'r':   permissions |= eMemoryPermissionsReadable; break;
2624                 case 'w':   permissions |= eMemoryPermissionsWritable; break;
2625                 case 'x':   permissions |= eMemoryPermissionsExecutable; break;
2626                 default:    success = false; break;
2627                 }
2628             }
2629 
2630             if (success)
2631             {
2632                 nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
2633                 if (addr != INVALID_NUB_ADDRESS)
2634                 {
2635                     std::ostringstream ostrm;
2636                     ostrm << RAW_HEXBASE << addr;
2637                     return SendPacket (ostrm.str ());
2638                 }
2639             }
2640         }
2641     }
2642     return SendPacket ("E53");
2643 }
2644 
2645 // FORMAT: _mXXXXXX
2646 //      XXXXXX: address that was previosly allocated
2647 //
2648 // RESPONSE: XXXXXX
2649 //      OK: address was deallocated
2650 //      EXX: error code
2651 //
2652 // EXAMPLES:
2653 //      _m123000
2654 
2655 rnb_err_t
2656 RNBRemote::HandlePacket_DeallocateMemory (const char *p)
2657 {
2658     StringExtractor packet (p);
2659     packet.SetFilePos(2); // Skip the "_m"
2660     nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
2661 
2662     if (addr != INVALID_NUB_ADDRESS)
2663     {
2664         if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
2665             return SendPacket ("OK");
2666     }
2667     return SendPacket ("E54");
2668 }
2669 
2670 /*
2671  vAttach;pid
2672 
2673  Attach to a new process with the specified process ID. pid is a hexadecimal integer
2674  identifying the process. If the stub is currently controlling a process, it is
2675  killed. The attached process is stopped.This packet is only available in extended
2676  mode (see extended mode).
2677 
2678  Reply:
2679  "ENN"                      for an error
2680  "Any Stop Reply Packet"     for success
2681  */
2682 
2683 rnb_err_t
2684 RNBRemote::HandlePacket_v (const char *p)
2685 {
2686     if (strcmp (p, "vCont;c") == 0)
2687     {
2688         // Simple continue
2689         return RNBRemote::HandlePacket_c("c");
2690     }
2691     else if (strcmp (p, "vCont;s") == 0)
2692     {
2693         // Simple step
2694         return RNBRemote::HandlePacket_s("s");
2695     }
2696     else if (strstr (p, "vCont") == p)
2697     {
2698         rnb_err_t rnb_err = rnb_success;
2699         typedef struct
2700         {
2701             nub_thread_t tid;
2702             char action;
2703             int signal;
2704         } vcont_action_t;
2705 
2706         DNBThreadResumeActions thread_actions;
2707         char *c = (char *)(p += strlen("vCont"));
2708         char *c_end = c + strlen(c);
2709         if (*c == '?')
2710             return SendPacket ("vCont;c;C;s;S");
2711 
2712         while (c < c_end && *c == ';')
2713         {
2714             ++c;    // Skip the semi-colon
2715             DNBThreadResumeAction thread_action;
2716             thread_action.tid = INVALID_NUB_THREAD;
2717             thread_action.state = eStateInvalid;
2718             thread_action.signal = 0;
2719             thread_action.addr = INVALID_NUB_ADDRESS;
2720 
2721             char action = *c++;
2722 
2723             switch (action)
2724             {
2725                 case 'C':
2726                     errno = 0;
2727                     thread_action.signal = strtoul (c, &c, 16);
2728                     if (errno != 0)
2729                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2730                     // Fall through to next case...
2731 
2732                 case 'c':
2733                     // Continue
2734                     thread_action.state = eStateRunning;
2735                     break;
2736 
2737                 case 'S':
2738                     errno = 0;
2739                     thread_action.signal = strtoul (c, &c, 16);
2740                     if (errno != 0)
2741                         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2742                     // Fall through to next case...
2743 
2744                 case 's':
2745                     // Step
2746                     thread_action.state = eStateStepping;
2747                     break;
2748 
2749                 default:
2750                     rnb_err = HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
2751                     break;
2752             }
2753             if (*c == ':')
2754             {
2755                 errno = 0;
2756                 thread_action.tid = strtoul (++c, &c, 16);
2757                 if (errno != 0)
2758                     return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
2759             }
2760 
2761             thread_actions.Append (thread_action);
2762         }
2763 
2764         // If a default action for all other threads wasn't mentioned
2765         // then we should stop the threads
2766         thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
2767         DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
2768         return rnb_success;
2769     }
2770     else if (strstr (p, "vAttach") == p)
2771     {
2772         nub_process_t attach_pid = INVALID_NUB_PROCESS;
2773         char err_str[1024]={'\0'};
2774         if (strstr (p, "vAttachWait;") == p)
2775         {
2776             p += strlen("vAttachWait;");
2777             std::string attach_name;
2778             while (*p != '\0')
2779             {
2780                 char smallbuf[3];
2781                 smallbuf[0] = *p;
2782                 smallbuf[1] = *(p + 1);
2783                 smallbuf[2] = '\0';
2784 
2785                 errno = 0;
2786                 int ch = strtoul (smallbuf, NULL, 16);
2787                 if (errno != 0 && ch == 0)
2788                 {
2789                     return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2790                 }
2791 
2792                 attach_name.push_back(ch);
2793                 p += 2;
2794             }
2795 
2796             attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2797 
2798         }
2799         else if (strstr (p, "vAttachName;") == p)
2800         {
2801             p += strlen("vAttachName;");
2802             std::string attach_name;
2803             while (*p != '\0')
2804             {
2805                 char smallbuf[3];
2806                 smallbuf[0] = *p;
2807                 smallbuf[1] = *(p + 1);
2808                 smallbuf[2] = '\0';
2809 
2810                 errno = 0;
2811                 int ch = strtoul (smallbuf, NULL, 16);
2812                 if (errno != 0 && ch == 0)
2813                 {
2814                     return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2815                 }
2816 
2817                 attach_name.push_back(ch);
2818                 p += 2;
2819             }
2820 
2821             attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
2822 
2823         }
2824         else if (strstr (p, "vAttach;") == p)
2825         {
2826             p += strlen("vAttach;");
2827             char *end = NULL;
2828             attach_pid = strtoul (p, &end, 16);    // PID will be in hex, so use base 16 to decode
2829             if (p != end && *end == '\0')
2830             {
2831                 // Wait at most 30 second for attach
2832                 struct timespec attach_timeout_abstime;
2833                 DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
2834                 attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
2835             }
2836         }
2837         else
2838             return HandlePacket_UNIMPLEMENTED(p);
2839 
2840 
2841         if (attach_pid != INVALID_NUB_PROCESS)
2842         {
2843             if (m_ctx.ProcessID() != attach_pid)
2844                 m_ctx.SetProcessID(attach_pid);
2845             // Send a stop reply packet to indicate we successfully attached!
2846             NotifyThatProcessStopped ();
2847             return rnb_success;
2848         }
2849         else
2850         {
2851             m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
2852             if (err_str[0])
2853                 m_ctx.LaunchStatus().SetErrorString(err_str);
2854             else
2855                 m_ctx.LaunchStatus().SetErrorString("attach failed");
2856             return SendPacket ("E01");  // E01 is our magic error value for attach failed.
2857         }
2858     }
2859 
2860     // All other failures come through here
2861     return HandlePacket_UNIMPLEMENTED(p);
2862 }
2863 
2864 /* 'T XX' -- status of thread
2865  Check if the specified thread is alive.
2866  The thread number is in hex?  */
2867 
2868 rnb_err_t
2869 RNBRemote::HandlePacket_T (const char *p)
2870 {
2871     p++;
2872     if (p == NULL || *p == '\0')
2873     {
2874         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
2875     }
2876     if (!m_ctx.HasValidProcessID())
2877     {
2878         return SendPacket ("E15");
2879     }
2880     errno = 0;
2881     nub_thread_t tid = strtoul (p, NULL, 16);
2882     if (errno != 0 && tid == 0)
2883     {
2884         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
2885     }
2886 
2887     nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
2888     if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
2889     {
2890         return SendPacket ("E16");
2891     }
2892 
2893     return SendPacket ("OK");
2894 }
2895 
2896 
2897 rnb_err_t
2898 RNBRemote::HandlePacket_z (const char *p)
2899 {
2900     if (p == NULL || *p == '\0')
2901         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
2902 
2903     if (!m_ctx.HasValidProcessID())
2904         return SendPacket ("E15");
2905 
2906     char packet_cmd = *p++;
2907     char break_type = *p++;
2908 
2909     if (*p++ != ',')
2910         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
2911 
2912     char *c = NULL;
2913     nub_process_t pid = m_ctx.ProcessID();
2914     errno = 0;
2915     nub_addr_t addr = strtoull (p, &c, 16);
2916     if (errno != 0 && addr == 0)
2917         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
2918     p = c;
2919     if (*p++ != ',')
2920         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
2921 
2922     errno = 0;
2923     uint32_t byte_size = strtoul (p, &c, 16);
2924     if (errno != 0 && byte_size == 0)
2925         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
2926 
2927     if (packet_cmd == 'Z')
2928     {
2929         // set
2930         switch (break_type)
2931         {
2932             case '0':   // set software breakpoint
2933             case '1':   // set hardware breakpoint
2934             {
2935                 // gdb can send multiple Z packets for the same address and
2936                 // these calls must be ref counted.
2937                 bool hardware = (break_type == '1');
2938 
2939                 // Check if we currently have a breakpoint already set at this address
2940                 BreakpointMapIter pos = m_breakpoints.find(addr);
2941                 if (pos != m_breakpoints.end())
2942                 {
2943                     // We do already have a breakpoint at this address, increment
2944                     // its reference count and return OK
2945                     pos->second.Retain();
2946                     return SendPacket ("OK");
2947                 }
2948                 else
2949                 {
2950                     // We do NOT already have a breakpoint at this address, So lets
2951                     // create one.
2952                     nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware);
2953                     if (NUB_BREAK_ID_IS_VALID(break_id))
2954                     {
2955                         // We successfully created a breakpoint, now lets full out
2956                         // a ref count structure with the breakID and add it to our
2957                         // map.
2958                         Breakpoint rnbBreakpoint(break_id);
2959                         m_breakpoints[addr] = rnbBreakpoint;
2960                         return SendPacket ("OK");
2961                     }
2962                     else
2963                     {
2964                         // We failed to set the software breakpoint
2965                         return SendPacket ("E09");
2966                     }
2967                 }
2968             }
2969                 break;
2970 
2971             case '2':   // set write watchpoint
2972             case '3':   // set read watchpoint
2973             case '4':   // set access watchpoint
2974             {
2975                 bool hardware = true;
2976                 uint32_t watch_flags = 0;
2977                 if (break_type == '2')
2978                     watch_flags = WATCH_TYPE_WRITE;
2979                 else if (break_type == '3')
2980                     watch_flags = WATCH_TYPE_READ;
2981                 else
2982                     watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
2983 
2984                 // Check if we currently have a watchpoint already set at this address
2985                 BreakpointMapIter pos = m_watchpoints.find(addr);
2986                 if (pos != m_watchpoints.end())
2987                 {
2988                     // We do already have a watchpoint at this address, increment
2989                     // its reference count and return OK
2990                     pos->second.Retain();
2991                     return SendPacket ("OK");
2992                 }
2993                 else
2994                 {
2995                     // We do NOT already have a watchpoint at this address, So lets
2996                     // create one.
2997                     nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware);
2998                     if (NUB_WATCH_ID_IS_VALID(watch_id))
2999                     {
3000                         // We successfully created a watchpoint, now lets full out
3001                         // a ref count structure with the watch_id and add it to our
3002                         // map.
3003                         Breakpoint rnbWatchpoint(watch_id);
3004                         m_watchpoints[addr] = rnbWatchpoint;
3005                         return SendPacket ("OK");
3006                     }
3007                     else
3008                     {
3009                         // We failed to set the watchpoint
3010                         return SendPacket ("E09");
3011                     }
3012                 }
3013             }
3014                 break;
3015 
3016             default:
3017                 break;
3018         }
3019     }
3020     else if (packet_cmd == 'z')
3021     {
3022         // remove
3023         switch (break_type)
3024         {
3025             case '0':   // remove software breakpoint
3026             case '1':   // remove hardware breakpoint
3027             {
3028                 // gdb can send multiple z packets for the same address and
3029                 // these calls must be ref counted.
3030                 BreakpointMapIter pos = m_breakpoints.find(addr);
3031                 if (pos != m_breakpoints.end())
3032                 {
3033                     // We currently have a breakpoint at address ADDR. Decrement
3034                     // its reference count, and it that count is now zero we
3035                     // can clear the breakpoint.
3036                     pos->second.Release();
3037                     if (pos->second.RefCount() == 0)
3038                     {
3039                         if (DNBBreakpointClear (pid, pos->second.BreakID()))
3040                         {
3041                             m_breakpoints.erase(pos);
3042                             return SendPacket ("OK");
3043                         }
3044                         else
3045                         {
3046                             return SendPacket ("E08");
3047                         }
3048                     }
3049                     else
3050                     {
3051                         // We still have references to this breakpoint don't
3052                         // delete it, just decrementing the reference count
3053                         // is enough.
3054                         return SendPacket ("OK");
3055                     }
3056                 }
3057                 else
3058                 {
3059                     // We don't know about any breakpoints at this address
3060                     return SendPacket ("E08");
3061                 }
3062             }
3063                 break;
3064 
3065             case '2':   // remove write watchpoint
3066             case '3':   // remove read watchpoint
3067             case '4':   // remove access watchpoint
3068             {
3069                 // gdb can send multiple z packets for the same address and
3070                 // these calls must be ref counted.
3071                 BreakpointMapIter pos = m_watchpoints.find(addr);
3072                 if (pos != m_watchpoints.end())
3073                 {
3074                     // We currently have a watchpoint at address ADDR. Decrement
3075                     // its reference count, and it that count is now zero we
3076                     // can clear the watchpoint.
3077                     pos->second.Release();
3078                     if (pos->second.RefCount() == 0)
3079                     {
3080                         if (DNBWatchpointClear (pid, pos->second.BreakID()))
3081                         {
3082                             m_watchpoints.erase(pos);
3083                             return SendPacket ("OK");
3084                         }
3085                         else
3086                         {
3087                             return SendPacket ("E08");
3088                         }
3089                     }
3090                     else
3091                     {
3092                         // We still have references to this watchpoint don't
3093                         // delete it, just decrementing the reference count
3094                         // is enough.
3095                         return SendPacket ("OK");
3096                     }
3097                 }
3098                 else
3099                 {
3100                     // We don't know about any watchpoints at this address
3101                     return SendPacket ("E08");
3102                 }
3103             }
3104                 break;
3105 
3106             default:
3107                 break;
3108         }
3109     }
3110     return HandlePacket_UNIMPLEMENTED(p);
3111 }
3112 
3113 // Extract the thread number from the thread suffix that might be appended to
3114 // thread specific packets. This will only be enabled if m_thread_suffix_supported
3115 // is true.
3116 nub_thread_t
3117 RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
3118 {
3119     if (m_thread_suffix_supported)
3120     {
3121         nub_thread_t tid = INVALID_NUB_THREAD;
3122         if (p)
3123         {
3124             const char *tid_cstr = strstr (p, "thread:");
3125             if (tid_cstr)
3126             {
3127                 tid_cstr += strlen ("thread:");
3128                 tid = strtoul(tid_cstr, NULL, 16);
3129             }
3130         }
3131         return tid;
3132     }
3133     return GetCurrentThread();
3134 
3135 }
3136 
3137 /* 'p XX'
3138  print the contents of register X */
3139 
3140 rnb_err_t
3141 RNBRemote::HandlePacket_p (const char *p)
3142 {
3143     if (g_num_reg_entries == 0)
3144         InitializeRegisters ();
3145 
3146     if (p == NULL || *p == '\0')
3147     {
3148         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3149     }
3150     if (!m_ctx.HasValidProcessID())
3151     {
3152         return SendPacket ("E15");
3153     }
3154     nub_process_t pid = m_ctx.ProcessID();
3155     errno = 0;
3156     char *tid_cstr = NULL;
3157     uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
3158     if (errno != 0 && reg == 0)
3159     {
3160         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
3161     }
3162 
3163     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
3164     if (tid == INVALID_NUB_THREAD)
3165         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3166 
3167     const register_map_entry_t *reg_entry;
3168 
3169     if (reg < g_num_reg_entries)
3170         reg_entry = &g_reg_entries[reg];
3171     else
3172         reg_entry = NULL;
3173 
3174     std::ostringstream ostrm;
3175     if (reg_entry == NULL)
3176     {
3177         DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
3178         ostrm << "00000000";
3179     }
3180     else if (reg_entry->nub_info.reg == -1)
3181     {
3182         if (reg_entry->gdb_size > 0)
3183         {
3184             if (reg_entry->fail_value != NULL)
3185             {
3186                 append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false);
3187             }
3188             else
3189             {
3190                 std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0');
3191                 append_hex_value(ostrm, zeros.data(), zeros.size(), false);
3192             }
3193         }
3194     }
3195     else
3196     {
3197         register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry);
3198     }
3199     return SendPacket (ostrm.str());
3200 }
3201 
3202 /* 'Pnn=rrrrr'
3203  Set register number n to value r.
3204  n and r are hex strings.  */
3205 
3206 rnb_err_t
3207 RNBRemote::HandlePacket_P (const char *p)
3208 {
3209     if (g_num_reg_entries == 0)
3210         InitializeRegisters ();
3211 
3212     if (p == NULL || *p == '\0')
3213     {
3214         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
3215     }
3216     if (!m_ctx.HasValidProcessID())
3217     {
3218         return SendPacket ("E28");
3219     }
3220 
3221     nub_process_t pid = m_ctx.ProcessID();
3222 
3223     StringExtractor packet (p);
3224 
3225     const char cmd_char = packet.GetChar();
3226     // Register ID is always in big endian
3227     const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
3228     const char equal_char = packet.GetChar();
3229 
3230     if (cmd_char != 'P')
3231         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
3232 
3233     if (reg == UINT32_MAX)
3234         return SendPacket ("E29");
3235 
3236     if (equal_char != '=')
3237         return SendPacket ("E30");
3238 
3239     const register_map_entry_t *reg_entry;
3240 
3241     if (reg >= g_num_reg_entries)
3242         return SendPacket("E47");
3243 
3244     reg_entry = &g_reg_entries[reg];
3245 
3246     if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3247     {
3248         DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3249         return SendPacket("E48");
3250     }
3251 
3252     DNBRegisterValue reg_value;
3253     reg_value.info = reg_entry->nub_info;
3254     packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
3255 
3256     nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3257     if (tid == INVALID_NUB_THREAD)
3258         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3259 
3260     if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3261     {
3262         return SendPacket ("E32");
3263     }
3264     return SendPacket ("OK");
3265 }
3266 
3267 /* 'c [addr]'
3268  Continue, optionally from a specified address. */
3269 
3270 rnb_err_t
3271 RNBRemote::HandlePacket_c (const char *p)
3272 {
3273     const nub_process_t pid = m_ctx.ProcessID();
3274 
3275     if (pid == INVALID_NUB_PROCESS)
3276         return SendPacket ("E23");
3277 
3278     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3279 
3280     if (*(p + 1) != '\0')
3281     {
3282         action.tid = GetContinueThread();
3283         errno = 0;
3284         action.addr = strtoull (p + 1, NULL, 16);
3285         if (errno != 0 && action.addr == 0)
3286             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
3287     }
3288 
3289     DNBThreadResumeActions thread_actions;
3290     thread_actions.Append(action);
3291     thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3292     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3293         return SendPacket ("E25");
3294     // Don't send an "OK" packet; response is the stopped/exited message.
3295     return rnb_success;
3296 }
3297 
3298 rnb_err_t
3299 RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
3300 {
3301     /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code)
3302        for the memory region containing a given address and return that information.
3303 
3304        Users of this packet must be prepared for three results:
3305 
3306            Region information is returned
3307            Region information is unavailable for this address because the address is in unmapped memory
3308            Region lookup cannot be performed on this platform or process is not yet launched
3309            This packet isn't implemented
3310 
3311        Examples of use:
3312           qMemoryRegionInfo:3a55140
3313           start:3a50000,size:100000,permissions:rwx
3314 
3315           qMemoryRegionInfo:0
3316           error:address in unmapped region
3317 
3318           qMemoryRegionInfo:3a551140   (on a different platform)
3319           error:region lookup cannot be performed
3320 
3321           qMemoryRegionInfo
3322           OK                   // this packet is implemented by the remote nub
3323     */
3324 
3325     p += sizeof ("qMemoryRegionInfo") - 1;
3326     if (*p == '\0')
3327        return SendPacket ("OK");
3328     if (*p++ != ':')
3329        return SendPacket ("E67");
3330     if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
3331        p += 2;
3332 
3333     errno = 0;
3334     uint64_t address = strtoul (p, NULL, 16);
3335     if (errno != 0 && address == 0)
3336     {
3337         return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
3338     }
3339 
3340     DNBRegionInfo region_info = { 0, 0, 0 };
3341     DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, &region_info);
3342     std::ostringstream ostrm;
3343 
3344         // start:3a50000,size:100000,permissions:rwx
3345     ostrm << "start:" << std::hex << region_info.addr << ';';
3346 
3347     if (region_info.size > 0)
3348         ostrm << "size:"  << std::hex << region_info.size << ';';
3349 
3350     if (region_info.permissions)
3351     {
3352         ostrm << "permissions:";
3353 
3354         if (region_info.permissions & eMemoryPermissionsReadable)
3355             ostrm << 'r';
3356         if (region_info.permissions & eMemoryPermissionsWritable)
3357             ostrm << 'w';
3358         if (region_info.permissions & eMemoryPermissionsExecutable)
3359             ostrm << 'x';
3360         ostrm << ';';
3361     }
3362     return SendPacket (ostrm.str());
3363 }
3364 
3365 rnb_err_t
3366 RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p)
3367 {
3368     /* This packet simply returns the number of supported hardware watchpoints.
3369 
3370        Examples of use:
3371           qWatchpointSupportInfo:
3372           num:4
3373 
3374           qWatchpointSupportInfo
3375           OK                   // this packet is implemented by the remote nub
3376     */
3377 
3378     p += sizeof ("qWatchpointSupportInfo") - 1;
3379     if (*p == '\0')
3380        return SendPacket ("OK");
3381     if (*p++ != ':')
3382        return SendPacket ("E67");
3383 
3384     errno = 0;
3385     uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID());
3386     std::ostringstream ostrm;
3387 
3388     // size:4
3389     ostrm << "num:" << std::dec << num << ';';
3390     return SendPacket (ostrm.str());
3391 }
3392 
3393 /* 'C sig [;addr]'
3394  Resume with signal sig, optionally at address addr.  */
3395 
3396 rnb_err_t
3397 RNBRemote::HandlePacket_C (const char *p)
3398 {
3399     const nub_process_t pid = m_ctx.ProcessID();
3400 
3401     if (pid == INVALID_NUB_PROCESS)
3402         return SendPacket ("E36");
3403 
3404     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3405     int process_signo = -1;
3406     if (*(p + 1) != '\0')
3407     {
3408         action.tid = GetContinueThread();
3409         char *end = NULL;
3410         errno = 0;
3411         process_signo = strtoul (p + 1, &end, 16);
3412         if (errno != 0)
3413             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
3414         else if (*end == ';')
3415         {
3416             errno = 0;
3417             action.addr = strtoull (end + 1, NULL, 16);
3418             if (errno != 0 && action.addr == 0)
3419                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
3420         }
3421     }
3422 
3423     DNBThreadResumeActions thread_actions;
3424     thread_actions.Append (action);
3425     thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
3426     if (!DNBProcessSignal(pid, process_signo))
3427         return SendPacket ("E52");
3428     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3429         return SendPacket ("E38");
3430     /* Don't send an "OK" packet; response is the stopped/exited message.  */
3431     return rnb_success;
3432 }
3433 
3434 //----------------------------------------------------------------------
3435 // 'D' packet
3436 // Detach from gdb.
3437 //----------------------------------------------------------------------
3438 rnb_err_t
3439 RNBRemote::HandlePacket_D (const char *p)
3440 {
3441     SendPacket ("OK");
3442     if (m_ctx.HasValidProcessID())
3443         DNBProcessDetach(m_ctx.ProcessID());
3444     return rnb_success;
3445 }
3446 
3447 /* 'k'
3448  Kill the inferior process.  */
3449 
3450 rnb_err_t
3451 RNBRemote::HandlePacket_k (const char *p)
3452 {
3453     // No response to should be sent to the kill packet
3454     if (m_ctx.HasValidProcessID())
3455         DNBProcessKill (m_ctx.ProcessID());
3456     SendPacket ("W09");
3457     return rnb_success;
3458 }
3459 
3460 rnb_err_t
3461 RNBRemote::HandlePacket_stop_process (const char *p)
3462 {
3463     DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
3464     //DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
3465     // Do not send any response packet! Wait for the stop reply packet to naturally happen
3466     return rnb_success;
3467 }
3468 
3469 /* 's'
3470  Step the inferior process.  */
3471 
3472 rnb_err_t
3473 RNBRemote::HandlePacket_s (const char *p)
3474 {
3475     const nub_process_t pid = m_ctx.ProcessID();
3476     if (pid == INVALID_NUB_PROCESS)
3477         return SendPacket ("E32");
3478 
3479     // Hardware supported stepping not supported on arm
3480     nub_thread_t tid = GetContinueThread ();
3481     if (tid == 0 || tid == -1)
3482         tid = GetCurrentThread();
3483 
3484     if (tid == INVALID_NUB_THREAD)
3485         return SendPacket ("E33");
3486 
3487     DNBThreadResumeActions thread_actions;
3488     thread_actions.AppendAction(tid, eStateStepping);
3489 
3490     // Make all other threads stop when we are stepping
3491     thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3492     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3493         return SendPacket ("E49");
3494     // Don't send an "OK" packet; response is the stopped/exited message.
3495     return rnb_success;
3496 }
3497 
3498 /* 'S sig [;addr]'
3499  Step with signal sig, optionally at address addr.  */
3500 
3501 rnb_err_t
3502 RNBRemote::HandlePacket_S (const char *p)
3503 {
3504     const nub_process_t pid = m_ctx.ProcessID();
3505     if (pid == INVALID_NUB_PROCESS)
3506         return SendPacket ("E36");
3507 
3508     DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
3509 
3510     if (*(p + 1) != '\0')
3511     {
3512         char *end = NULL;
3513         errno = 0;
3514         action.signal = strtoul (p + 1, &end, 16);
3515         if (errno != 0)
3516             return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
3517         else if (*end == ';')
3518         {
3519             errno = 0;
3520             action.addr = strtoull (end + 1, NULL, 16);
3521             if (errno != 0 && action.addr == 0)
3522             {
3523                 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
3524             }
3525         }
3526     }
3527 
3528     action.tid = GetContinueThread ();
3529     if (action.tid == 0 || action.tid == -1)
3530         return SendPacket ("E40");
3531 
3532     nub_state_t tstate = DNBThreadGetState (pid, action.tid);
3533     if (tstate == eStateInvalid || tstate == eStateExited)
3534         return SendPacket ("E37");
3535 
3536 
3537     DNBThreadResumeActions thread_actions;
3538     thread_actions.Append (action);
3539 
3540     // Make all other threads stop when we are stepping
3541     thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
3542     if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3543         return SendPacket ("E39");
3544 
3545     // Don't send an "OK" packet; response is the stopped/exited message.
3546     return rnb_success;
3547 }
3548 
3549 rnb_err_t
3550 RNBRemote::HandlePacket_qHostInfo (const char *p)
3551 {
3552     std::ostringstream strm;
3553 
3554     uint32_t cputype, is_64_bit_capable;
3555     size_t len = sizeof(cputype);
3556     bool promoted_to_64 = false;
3557     if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
3558     {
3559         len = sizeof (is_64_bit_capable);
3560         if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
3561         {
3562             if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
3563             {
3564                 promoted_to_64 = true;
3565                 cputype |= CPU_ARCH_ABI64;
3566             }
3567         }
3568 
3569         strm << "cputype:" << std::dec << cputype << ';';
3570     }
3571 
3572     uint32_t cpusubtype;
3573     len = sizeof(cpusubtype);
3574     if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
3575     {
3576         if (promoted_to_64 &&
3577             cputype == CPU_TYPE_X86_64 &&
3578             cpusubtype == CPU_SUBTYPE_486)
3579             cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3580 
3581         strm << "cpusubtype:" << std::dec << cpusubtype << ';';
3582     }
3583 
3584     // The OS in the triple should be "ios" or "macosx" which doesn't match our
3585     // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
3586     // this for now.
3587     if (cputype == CPU_TYPE_ARM)
3588     {
3589         strm << "ostype:ios;";
3590     }
3591     else
3592     {
3593         strm << "ostype:macosx;";
3594     }
3595 //    char ostype[64];
3596 //    len = sizeof(ostype);
3597 //    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
3598 //    {
3599 //        len = strlen(ostype);
3600 //        std::transform (ostype, ostype + len, ostype, tolower);
3601 //        strm << "ostype:" << std::dec << ostype << ';';
3602 //    }
3603 
3604     strm << "vendor:apple;";
3605 
3606 #if defined (__LITTLE_ENDIAN__)
3607     strm << "endian:little;";
3608 #elif defined (__BIG_ENDIAN__)
3609     strm << "endian:big;";
3610 #elif defined (__PDP_ENDIAN__)
3611     strm << "endian:pdp;";
3612 #endif
3613 
3614     if (promoted_to_64)
3615         strm << "ptrsize:8;";
3616     else
3617         strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
3618     return SendPacket (strm.str());
3619 }
3620