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