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