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