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