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