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