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