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