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