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