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