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