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