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