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