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