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