RNBRemote.cpp revision e86cbb9ef128db87cf904e330b2edfc15566bacd
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}, NULL, 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            return rnb_success;  // Ignore
2072
2073        case eStateSuspended:
2074        case eStateStopped:
2075        case eStateCrashed:
2076            {
2077                nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2078                // Make sure we set the current thread so g and p packets return
2079                // the data the gdb will expect.
2080                SetCurrentThread (tid);
2081
2082                SendStopReplyPacketForThread (tid);
2083            }
2084            break;
2085
2086        case eStateInvalid:
2087        case eStateUnloaded:
2088        case eStateExited:
2089            {
2090                char pid_exited_packet[16] = "";
2091                int pid_status = 0;
2092                // Process exited with exit status
2093                if (!DNBProcessGetExitStatus(pid, &pid_status))
2094                    pid_status = 0;
2095
2096                if (pid_status)
2097                {
2098                    if (WIFEXITED (pid_status))
2099                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2100                    else if (WIFSIGNALED (pid_status))
2101                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2102                    else if (WIFSTOPPED (pid_status))
2103                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2104                }
2105
2106                // If we have an empty exit packet, lets fill one in to be safe.
2107                if (!pid_exited_packet[0])
2108                {
2109                    strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2110                    pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2111                }
2112
2113                return SendPacket (pid_exited_packet);
2114            }
2115            break;
2116    }
2117    return rnb_success;
2118}
2119
2120rnb_err_t
2121RNBRemote::HandlePacket_M (const char *p)
2122{
2123    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2124    {
2125        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2126    }
2127
2128    char *c;
2129    p++;
2130    errno = 0;
2131    nub_addr_t addr = strtoull (p, &c, 16);
2132    if (errno != 0 && addr == 0)
2133    {
2134        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2135    }
2136    if (*c != ',')
2137    {
2138        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2139    }
2140
2141    /* Advance 'p' to the length part of the packet.  */
2142    p += (c - p) + 1;
2143
2144    errno = 0;
2145    uint32_t length = strtoul (p, &c, 16);
2146    if (errno != 0 && length == 0)
2147    {
2148        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2149    }
2150    if (length == 0)
2151    {
2152        return SendPacket ("OK");
2153    }
2154
2155    if (*c != ':')
2156    {
2157        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2158    }
2159    /* Advance 'p' to the data part of the packet.  */
2160    p += (c - p) + 1;
2161
2162    int datalen = strlen (p);
2163    if (datalen & 0x1)
2164    {
2165        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2166    }
2167    if (datalen == 0)
2168    {
2169        return SendPacket ("OK");
2170    }
2171
2172    uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2173    uint8_t *i = buf;
2174
2175    while (*p != '\0' && *(p + 1) != '\0')
2176    {
2177        char hexbuf[3];
2178        hexbuf[0] = *p;
2179        hexbuf[1] = *(p + 1);
2180        hexbuf[2] = '\0';
2181        errno = 0;
2182        uint8_t byte = strtoul (hexbuf, NULL, 16);
2183        if (errno != 0 && byte == 0)
2184        {
2185            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2186        }
2187        *i++ = byte;
2188        p += 2;
2189    }
2190
2191    nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2192    if (wrote != length)
2193        return SendPacket ("E09");
2194    else
2195        return SendPacket ("OK");
2196}
2197
2198
2199rnb_err_t
2200RNBRemote::HandlePacket_m (const char *p)
2201{
2202    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2203    {
2204        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
2205    }
2206
2207    char *c;
2208    p++;
2209    errno = 0;
2210    nub_addr_t addr = strtoull (p, &c, 16);
2211    if (errno != 0 && addr == 0)
2212    {
2213        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
2214    }
2215    if (*c != ',')
2216    {
2217        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
2218    }
2219
2220    /* Advance 'p' to the length part of the packet.  */
2221    p += (c - p) + 1;
2222
2223    errno = 0;
2224    uint32_t length = strtoul (p, NULL, 16);
2225    if (errno != 0 && length == 0)
2226    {
2227        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2228    }
2229    if (length == 0)
2230    {
2231        return SendPacket ("");
2232    }
2233
2234    uint8_t buf[length];
2235    int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf);
2236    if (bytes_read == 0)
2237    {
2238        return SendPacket ("E08");
2239    }
2240
2241    // "The reply may contain fewer bytes than requested if the server was able
2242    //  to read only part of the region of memory."
2243    length = bytes_read;
2244
2245    std::ostringstream ostrm;
2246    for (int i = 0; i < length; i++)
2247        ostrm << RAWHEX8(buf[i]);
2248    return SendPacket (ostrm.str ());
2249}
2250
2251rnb_err_t
2252RNBRemote::HandlePacket_X (const char *p)
2253{
2254    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2255    {
2256        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
2257    }
2258
2259    char *c;
2260    p++;
2261    errno = 0;
2262    nub_addr_t addr = strtoull (p, &c, 16);
2263    if (errno != 0 && addr == 0)
2264    {
2265        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
2266    }
2267    if (*c != ',')
2268    {
2269        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
2270    }
2271
2272    /* Advance 'p' to the length part of the packet.  */
2273    p += (c - p) + 1;
2274
2275    errno = 0;
2276    int length = strtoul (p, NULL, 16);
2277    if (errno != 0 && length == 0)
2278    {
2279        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2280    }
2281
2282    // I think gdb sends a zero length write request to test whether this
2283    // packet is accepted.
2284    if (length == 0)
2285    {
2286        return SendPacket ("OK");
2287    }
2288
2289    std::vector<uint8_t> data = decode_binary_data (c, -1);
2290    std::vector<uint8_t>::const_iterator it;
2291    uint8_t *buf = (uint8_t *) alloca (data.size ());
2292    uint8_t *i = buf;
2293    for (it = data.begin (); it != data.end (); ++it)
2294    {
2295        *i++ = *it;
2296    }
2297
2298    nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
2299    if (wrote != data.size ())
2300        return SendPacket ("E08");
2301    return SendPacket ("OK");
2302}
2303
2304/* `g' -- read registers
2305 Get the contents of the registers for the current thread,
2306 send them to gdb.
2307 Should the setting of the Hg packet determine which thread's registers
2308 are returned?  */
2309
2310rnb_err_t
2311RNBRemote::HandlePacket_g (const char *p)
2312{
2313    std::ostringstream ostrm;
2314    if (!m_ctx.HasValidProcessID())
2315    {
2316        return SendPacket ("E11");
2317    }
2318
2319    if (g_num_reg_entries == 0)
2320        InitializeRegisters ();
2321
2322    nub_process_t pid = m_ctx.ProcessID ();
2323    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
2324    if (tid == INVALID_NUB_THREAD)
2325        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2326
2327    if (m_use_native_regs)
2328    {
2329        // Get the register context size first by calling with NULL buffer
2330        nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2331        if (reg_ctx_size)
2332        {
2333            // Now allocate enough space for the entire register context
2334            std::vector<uint8_t> reg_ctx;
2335            reg_ctx.resize(reg_ctx_size);
2336            // Now read the register context
2337            reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
2338            if (reg_ctx_size)
2339            {
2340                append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
2341                return SendPacket (ostrm.str ());
2342            }
2343        }
2344    }
2345
2346    for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2347        register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg]);
2348
2349    return SendPacket (ostrm.str ());
2350}
2351
2352/* `G XXX...' -- write registers
2353 How is the thread for these specified, beyond "the current thread"?
2354 Does gdb actually use the Hg packet to set this?  */
2355
2356rnb_err_t
2357RNBRemote::HandlePacket_G (const char *p)
2358{
2359    if (!m_ctx.HasValidProcessID())
2360    {
2361        return SendPacket ("E11");
2362    }
2363
2364    if (g_num_reg_entries == 0)
2365        InitializeRegisters ();
2366
2367    StringExtractor packet(p);
2368    packet.SetFilePos(1); // Skip the 'G'
2369
2370    nub_process_t pid = m_ctx.ProcessID();
2371    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2372    if (tid == INVALID_NUB_THREAD)
2373        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2374
2375    if (m_use_native_regs)
2376    {
2377        // Get the register context size first by calling with NULL buffer
2378        nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2379        if (reg_ctx_size)
2380        {
2381            // Now allocate enough space for the entire register context
2382            std::vector<uint8_t> reg_ctx;
2383            reg_ctx.resize(reg_ctx_size);
2384
2385            if (packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc) == reg_ctx.size())
2386            {
2387                // Now write the register context
2388                reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
2389                if (reg_ctx_size == reg_ctx.size())
2390                    return SendPacket ("OK");
2391                else
2392                    return SendPacket ("E55");
2393            }
2394        }
2395    }
2396
2397
2398    DNBRegisterValue reg_value;
2399    for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2400    {
2401        const register_map_entry_t *reg_entry = &g_reg_entries[reg];
2402
2403        reg_value.info = reg_entry->nub_info;
2404        if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size)
2405            break;
2406
2407        if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
2408            return SendPacket ("E15");
2409    }
2410    return SendPacket ("OK");
2411}
2412
2413static bool
2414RNBRemoteShouldCancelCallback (void *not_used)
2415{
2416    RNBRemoteSP remoteSP(g_remoteSP);
2417    if (remoteSP.get() != NULL)
2418    {
2419        RNBRemote* remote = remoteSP.get();
2420        if (remote->Comm().IsConnected())
2421            return false;
2422        else
2423            return true;
2424    }
2425    return true;
2426}
2427
2428
2429// FORMAT: _MXXXXXX,PPP
2430//      XXXXXX: big endian hex chars
2431//      PPP: permissions can be any combo of r w x chars
2432//
2433// RESPONSE: XXXXXX
2434//      XXXXXX: hex address of the newly allocated memory
2435//      EXX: error code
2436//
2437// EXAMPLES:
2438//      _M123000,rw
2439//      _M123000,rwx
2440//      _M123000,xw
2441
2442rnb_err_t
2443RNBRemote::HandlePacket_AllocateMemory (const char *p)
2444{
2445    StringExtractor packet (p);
2446    packet.SetFilePos(2); // Skip the "_M"
2447
2448    nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
2449    if (size != 0)
2450    {
2451        if (packet.GetChar() == ',')
2452        {
2453            uint32_t permissions = 0;
2454            char ch;
2455            bool success = true;
2456            while (success && (ch = packet.GetChar()) != '\0')
2457            {
2458                switch (ch)
2459                {
2460                case 'r':   permissions |= eMemoryPermissionsReadable; break;
2461                case 'w':   permissions |= eMemoryPermissionsWritable; break;
2462                case 'x':   permissions |= eMemoryPermissionsExecutable; break;
2463                default:    success = false; break;
2464                }
2465            }
2466
2467            if (success)
2468            {
2469                nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
2470                if (addr != INVALID_NUB_ADDRESS)
2471                {
2472                    std::ostringstream ostrm;
2473                    ostrm << RAW_HEXBASE << addr;
2474                    return SendPacket (ostrm.str ());
2475                }
2476            }
2477        }
2478    }
2479    return SendPacket ("E53");
2480}
2481
2482// FORMAT: _mXXXXXX
2483//      XXXXXX: address that was previosly allocated
2484//
2485// RESPONSE: XXXXXX
2486//      OK: address was deallocated
2487//      EXX: error code
2488//
2489// EXAMPLES:
2490//      _m123000
2491
2492rnb_err_t
2493RNBRemote::HandlePacket_DeallocateMemory (const char *p)
2494{
2495    StringExtractor packet (p);
2496    packet.SetFilePos(2); // Skip the "_m"
2497    nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
2498
2499    if (addr != INVALID_NUB_ADDRESS)
2500    {
2501        if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
2502            return SendPacket ("OK");
2503    }
2504    return SendPacket ("E54");
2505}
2506
2507/*
2508 vAttach;pid
2509
2510 Attach to a new process with the specified process ID. pid is a hexadecimal integer
2511 identifying the process. If the stub is currently controlling a process, it is
2512 killed. The attached process is stopped.This packet is only available in extended
2513 mode (see extended mode).
2514
2515 Reply:
2516 "ENN"                      for an error
2517 "Any Stop Reply Packet"     for success
2518 */
2519
2520rnb_err_t
2521RNBRemote::HandlePacket_v (const char *p)
2522{
2523    if (strcmp (p, "vCont;c") == 0)
2524    {
2525        // Simple continue
2526        return RNBRemote::HandlePacket_c("c");
2527    }
2528    else if (strcmp (p, "vCont;s") == 0)
2529    {
2530        // Simple step
2531        return RNBRemote::HandlePacket_s("s");
2532    }
2533    else if (strstr (p, "vCont") == p)
2534    {
2535        rnb_err_t rnb_err = rnb_success;
2536        typedef struct
2537        {
2538            nub_thread_t tid;
2539            char action;
2540            int signal;
2541        } vcont_action_t;
2542
2543        DNBThreadResumeActions thread_actions;
2544        char *c = (char *)(p += strlen("vCont"));
2545        char *c_end = c + strlen(c);
2546        if (*c == '?')
2547            return SendPacket ("vCont;c;C;s;S");
2548
2549        while (c < c_end && *c == ';')
2550        {
2551            ++c;    // Skip the semi-colon
2552            DNBThreadResumeAction thread_action;
2553            thread_action.tid = INVALID_NUB_THREAD;
2554            thread_action.state = eStateInvalid;
2555            thread_action.signal = 0;
2556            thread_action.addr = INVALID_NUB_ADDRESS;
2557
2558            char action = *c++;
2559
2560            switch (action)
2561            {
2562                case 'C':
2563                    errno = 0;
2564                    thread_action.signal = strtoul (c, &c, 16);
2565                    if (errno != 0)
2566                        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2567                    // Fall through to next case...
2568
2569                case 'c':
2570                    // Continue
2571                    thread_action.state = eStateRunning;
2572                    break;
2573
2574                case 'S':
2575                    errno = 0;
2576                    thread_action.signal = strtoul (c, &c, 16);
2577                    if (errno != 0)
2578                        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2579                    // Fall through to next case...
2580
2581                case 's':
2582                    // Step
2583                    thread_action.state = eStateStepping;
2584                    break;
2585
2586                    break;
2587
2588                default:
2589                    rnb_err = HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
2590                    break;
2591            }
2592            if (*c == ':')
2593            {
2594                errno = 0;
2595                thread_action.tid = strtoul (++c, &c, 16);
2596                if (errno != 0)
2597                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
2598            }
2599
2600            thread_actions.Append (thread_action);
2601        }
2602
2603        // If a default action for all other threads wasn't mentioned
2604        // then we should stop the threads
2605        thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
2606        DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
2607        return rnb_success;
2608    }
2609    else if (strstr (p, "vAttach") == p)
2610    {
2611        nub_process_t attach_pid = INVALID_NUB_PROCESS;
2612        char err_str[1024]={'\0'};
2613        if (strstr (p, "vAttachWait;") == p)
2614        {
2615            p += strlen("vAttachWait;");
2616            std::string attach_name;
2617            while (*p != '\0')
2618            {
2619                char smallbuf[3];
2620                smallbuf[0] = *p;
2621                smallbuf[1] = *(p + 1);
2622                smallbuf[2] = '\0';
2623
2624                errno = 0;
2625                int ch = strtoul (smallbuf, NULL, 16);
2626                if (errno != 0 && ch == 0)
2627                {
2628                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2629                }
2630
2631                attach_name.push_back(ch);
2632                p += 2;
2633            }
2634
2635            attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2636
2637        }
2638        else if (strstr (p, "vAttachName;") == p)
2639        {
2640            p += strlen("vAttachName;");
2641            std::string attach_name;
2642            while (*p != '\0')
2643            {
2644                char smallbuf[3];
2645                smallbuf[0] = *p;
2646                smallbuf[1] = *(p + 1);
2647                smallbuf[2] = '\0';
2648
2649                errno = 0;
2650                int ch = strtoul (smallbuf, NULL, 16);
2651                if (errno != 0 && ch == 0)
2652                {
2653                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2654                }
2655
2656                attach_name.push_back(ch);
2657                p += 2;
2658            }
2659
2660            attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
2661
2662        }
2663        else if (strstr (p, "vAttach;") == p)
2664        {
2665            p += strlen("vAttach;");
2666            char *end = NULL;
2667            attach_pid = strtoul (p, &end, 16);    // PID will be in hex, so use base 16 to decode
2668            if (p != end && *end == '\0')
2669            {
2670                // Wait at most 30 second for attach
2671                struct timespec attach_timeout_abstime;
2672                DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
2673                attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
2674            }
2675        }
2676        else
2677            return HandlePacket_UNIMPLEMENTED(p);
2678
2679
2680        if (attach_pid != INVALID_NUB_PROCESS)
2681        {
2682            if (m_ctx.ProcessID() != attach_pid)
2683                m_ctx.SetProcessID(attach_pid);
2684            // Send a stop reply packet to indicate we successfully attached!
2685            NotifyThatProcessStopped ();
2686            return rnb_success;
2687        }
2688        else
2689        {
2690            m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
2691            if (err_str[0])
2692                m_ctx.LaunchStatus().SetErrorString(err_str);
2693            else
2694                m_ctx.LaunchStatus().SetErrorString("attach failed");
2695            return SendPacket ("E01");  // E01 is our magic error value for attach failed.
2696        }
2697    }
2698
2699    // All other failures come through here
2700    return HandlePacket_UNIMPLEMENTED(p);
2701}
2702
2703/* `T XX' -- status of thread
2704 Check if the specified thread is alive.
2705 The thread number is in hex?  */
2706
2707rnb_err_t
2708RNBRemote::HandlePacket_T (const char *p)
2709{
2710    p++;
2711    if (p == NULL || *p == '\0')
2712    {
2713        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
2714    }
2715    if (!m_ctx.HasValidProcessID())
2716    {
2717        return SendPacket ("E15");
2718    }
2719    errno = 0;
2720    nub_thread_t tid = strtoul (p, NULL, 16);
2721    if (errno != 0 && tid == 0)
2722    {
2723        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
2724    }
2725
2726    nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
2727    if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
2728    {
2729        return SendPacket ("E16");
2730    }
2731
2732    return SendPacket ("OK");
2733}
2734
2735
2736rnb_err_t
2737RNBRemote::HandlePacket_z (const char *p)
2738{
2739    if (p == NULL || *p == '\0')
2740        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
2741
2742    if (!m_ctx.HasValidProcessID())
2743        return SendPacket ("E15");
2744
2745    char packet_cmd = *p++;
2746    char break_type = *p++;
2747
2748    if (*p++ != ',')
2749        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
2750
2751    char *c = NULL;
2752    nub_process_t pid = m_ctx.ProcessID();
2753    errno = 0;
2754    nub_addr_t addr = strtoull (p, &c, 16);
2755    if (errno != 0 && addr == 0)
2756        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
2757    p = c;
2758    if (*p++ != ',')
2759        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
2760
2761    errno = 0;
2762    uint32_t byte_size = strtoul (p, &c, 16);
2763    if (errno != 0 && byte_size == 0)
2764        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
2765
2766    if (packet_cmd == 'Z')
2767    {
2768        // set
2769        switch (break_type)
2770        {
2771            case '0':   // set software breakpoint
2772            case '1':   // set hardware breakpoint
2773            {
2774                // gdb can send multiple Z packets for the same address and
2775                // these calls must be ref counted.
2776                bool hardware = (break_type == '1');
2777
2778                // Check if we currently have a breakpoint already set at this address
2779                BreakpointMapIter pos = m_breakpoints.find(addr);
2780                if (pos != m_breakpoints.end())
2781                {
2782                    // We do already have a breakpoint at this address, increment
2783                    // its reference count and return OK
2784                    pos->second.Retain();
2785                    return SendPacket ("OK");
2786                }
2787                else
2788                {
2789                    // We do NOT already have a breakpoint at this address, So lets
2790                    // create one.
2791                    nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware);
2792                    if (break_id != INVALID_NUB_BREAK_ID)
2793                    {
2794                        // We successfully created a breakpoint, now lets full out
2795                        // a ref count structure with the breakID and add it to our
2796                        // map.
2797                        Breakpoint rnbBreakpoint(break_id);
2798                        m_breakpoints[addr] = rnbBreakpoint;
2799                        return SendPacket ("OK");
2800                    }
2801                    else
2802                    {
2803                        // We failed to set the software breakpoint
2804                        return SendPacket ("E09");
2805                    }
2806                }
2807            }
2808                break;
2809
2810            case '2':   // set write watchpoint
2811            case '3':   // set read watchpoint
2812            case '4':   // set access watchpoint
2813            {
2814                bool hardware = true;
2815                uint32_t watch_flags = 0;
2816                if (break_type == '2')
2817                    watch_flags = WATCH_TYPE_WRITE;
2818                else if (break_type == '3')
2819                    watch_flags = WATCH_TYPE_READ;
2820                else
2821                    watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
2822
2823                // Check if we currently have a watchpoint already set at this address
2824                BreakpointMapIter pos = m_watchpoints.find(addr);
2825                if (pos != m_watchpoints.end())
2826                {
2827                    // We do already have a watchpoint at this address, increment
2828                    // its reference count and return OK
2829                    pos->second.Retain();
2830                    return SendPacket ("OK");
2831                }
2832                else
2833                {
2834                    // We do NOT already have a breakpoint at this address, So lets
2835                    // create one.
2836                    nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware);
2837                    if (watch_id != INVALID_NUB_BREAK_ID)
2838                    {
2839                        // We successfully created a watchpoint, now lets full out
2840                        // a ref count structure with the watch_id and add it to our
2841                        // map.
2842                        Breakpoint rnbWatchpoint(watch_id);
2843                        m_watchpoints[addr] = rnbWatchpoint;
2844                        return SendPacket ("OK");
2845                    }
2846                    else
2847                    {
2848                        // We failed to set the watchpoint
2849                        return SendPacket ("E09");
2850                    }
2851                }
2852            }
2853                break;
2854
2855            default:
2856                break;
2857        }
2858    }
2859    else if (packet_cmd == 'z')
2860    {
2861        // remove
2862        switch (break_type)
2863        {
2864            case '0':   // remove software breakpoint
2865            case '1':   // remove hardware breakpoint
2866            {
2867                // gdb can send multiple z packets for the same address and
2868                // these calls must be ref counted.
2869                BreakpointMapIter pos = m_breakpoints.find(addr);
2870                if (pos != m_breakpoints.end())
2871                {
2872                    // We currently have a breakpoint at address ADDR. Decrement
2873                    // its reference count, and it that count is now zero we
2874                    // can clear the breakpoint.
2875                    pos->second.Release();
2876                    if (pos->second.RefCount() == 0)
2877                    {
2878                        if (DNBBreakpointClear (pid, pos->second.BreakID()))
2879                        {
2880                            m_breakpoints.erase(pos);
2881                            return SendPacket ("OK");
2882                        }
2883                        else
2884                        {
2885                            return SendPacket ("E08");
2886                        }
2887                    }
2888                    else
2889                    {
2890                        // We still have references to this breakpoint don't
2891                        // delete it, just decrementing the reference count
2892                        // is enough.
2893                        return SendPacket ("OK");
2894                    }
2895                }
2896                else
2897                {
2898                    // We don't know about any breakpoints at this address
2899                    return SendPacket ("E08");
2900                }
2901            }
2902                break;
2903
2904            case '2':   // remove write watchpoint
2905            case '3':   // remove read watchpoint
2906            case '4':   // remove access watchpoint
2907            {
2908                // gdb can send multiple z packets for the same address and
2909                // these calls must be ref counted.
2910                BreakpointMapIter pos = m_watchpoints.find(addr);
2911                if (pos != m_watchpoints.end())
2912                {
2913                    // We currently have a watchpoint at address ADDR. Decrement
2914                    // its reference count, and it that count is now zero we
2915                    // can clear the watchpoint.
2916                    pos->second.Release();
2917                    if (pos->second.RefCount() == 0)
2918                    {
2919                        if (DNBWatchpointClear (pid, pos->second.BreakID()))
2920                        {
2921                            m_watchpoints.erase(pos);
2922                            return SendPacket ("OK");
2923                        }
2924                        else
2925                        {
2926                            return SendPacket ("E08");
2927                        }
2928                    }
2929                    else
2930                    {
2931                        // We still have references to this watchpoint don't
2932                        // delete it, just decrementing the reference count
2933                        // is enough.
2934                        return SendPacket ("OK");
2935                    }
2936                }
2937                else
2938                {
2939                    // We don't know about any watchpoints at this address
2940                    return SendPacket ("E08");
2941                }
2942            }
2943                break;
2944
2945            default:
2946                break;
2947        }
2948    }
2949    return HandlePacket_UNIMPLEMENTED(p);
2950}
2951
2952// Extract the thread number from the thread suffix that might be appended to
2953// thread specific packets. This will only be enabled if m_thread_suffix_supported
2954// is true.
2955nub_thread_t
2956RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
2957{
2958    if (m_thread_suffix_supported)
2959    {
2960        nub_thread_t tid = INVALID_NUB_THREAD;
2961        if (p)
2962        {
2963            const char *tid_cstr = strstr (p, "thread:");
2964            if (tid_cstr)
2965            {
2966                tid_cstr += strlen ("thread:");
2967                tid = strtoul(tid_cstr, NULL, 16);
2968            }
2969        }
2970        return tid;
2971    }
2972    return GetCurrentThread();
2973
2974}
2975
2976/* `p XX'
2977 print the contents of register X */
2978
2979rnb_err_t
2980RNBRemote::HandlePacket_p (const char *p)
2981{
2982    if (g_num_reg_entries == 0)
2983        InitializeRegisters ();
2984
2985    if (p == NULL || *p == '\0')
2986    {
2987        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2988    }
2989    if (!m_ctx.HasValidProcessID())
2990    {
2991        return SendPacket ("E15");
2992    }
2993    nub_process_t pid = m_ctx.ProcessID();
2994    errno = 0;
2995    char *tid_cstr = NULL;
2996    uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
2997    if (errno != 0 && reg == 0)
2998    {
2999        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
3000    }
3001
3002    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
3003    if (tid == INVALID_NUB_THREAD)
3004        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3005
3006    const register_map_entry_t *reg_entry;
3007
3008    if (reg < g_num_reg_entries)
3009        reg_entry = &g_reg_entries[reg];
3010    else
3011        reg_entry = NULL;
3012
3013    std::ostringstream ostrm;
3014    if (reg_entry == NULL)
3015    {
3016        DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
3017        ostrm << "00000000";
3018    }
3019    else if (reg_entry->nub_info.reg == -1)
3020    {
3021        if (reg_entry->gdb_size > 0)
3022        {
3023            if (reg_entry->fail_value != NULL)
3024            {
3025                append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false);
3026            }
3027            else
3028            {
3029                std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0');
3030                append_hex_value(ostrm, zeros.data(), zeros.size(), false);
3031            }
3032        }
3033    }
3034    else
3035    {
3036        register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry);
3037    }
3038    return SendPacket (ostrm.str());
3039}
3040
3041/* `Pnn=rrrrr'
3042 Set register number n to value r.
3043 n and r are hex strings.  */
3044
3045rnb_err_t
3046RNBRemote::HandlePacket_P (const char *p)
3047{
3048    if (g_num_reg_entries == 0)
3049        InitializeRegisters ();
3050
3051    if (p == NULL || *p == '\0')
3052    {
3053        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
3054    }
3055    if (!m_ctx.HasValidProcessID())
3056    {
3057        return SendPacket ("E28");
3058    }
3059
3060    nub_process_t pid = m_ctx.ProcessID();
3061
3062    StringExtractor packet (p);
3063
3064    const char cmd_char = packet.GetChar();
3065    // Register ID is always in big endian
3066    const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
3067    const char equal_char = packet.GetChar();
3068
3069    if (cmd_char != 'P')
3070        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
3071
3072    if (reg == UINT32_MAX)
3073        return SendPacket ("E29");
3074
3075    if (equal_char != '=')
3076        return SendPacket ("E30");
3077
3078    const register_map_entry_t *reg_entry;
3079
3080    if (reg >= g_num_reg_entries)
3081        return SendPacket("E47");
3082
3083    reg_entry = &g_reg_entries[reg];
3084
3085    if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3086    {
3087        DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3088        return SendPacket("E48");
3089    }
3090
3091    DNBRegisterValue reg_value;
3092    reg_value.info = reg_entry->nub_info;
3093    packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
3094
3095    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3096    if (tid == INVALID_NUB_THREAD)
3097        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3098
3099    if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3100    {
3101        return SendPacket ("E32");
3102    }
3103    return SendPacket ("OK");
3104}
3105
3106/* `c [addr]'
3107 Continue, optionally from a specified address. */
3108
3109rnb_err_t
3110RNBRemote::HandlePacket_c (const char *p)
3111{
3112    const nub_process_t pid = m_ctx.ProcessID();
3113
3114    if (pid == INVALID_NUB_PROCESS)
3115        return SendPacket ("E23");
3116
3117    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3118
3119    if (*(p + 1) != '\0')
3120    {
3121        action.tid = GetContinueThread();
3122        errno = 0;
3123        action.addr = strtoull (p + 1, NULL, 16);
3124        if (errno != 0 && action.addr == 0)
3125            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
3126    }
3127
3128    DNBThreadResumeActions thread_actions;
3129    thread_actions.Append(action);
3130    thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3131    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3132        return SendPacket ("E25");
3133    // Don't send an "OK" packet; response is the stopped/exited message.
3134    return rnb_success;
3135}
3136
3137/* `C sig [;addr]'
3138 Resume with signal sig, optionally at address addr.  */
3139
3140rnb_err_t
3141RNBRemote::HandlePacket_C (const char *p)
3142{
3143    const nub_process_t pid = m_ctx.ProcessID();
3144
3145    if (pid == INVALID_NUB_PROCESS)
3146        return SendPacket ("E36");
3147
3148    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3149    int process_signo = -1;
3150    if (*(p + 1) != '\0')
3151    {
3152        action.tid = GetContinueThread();
3153        char *end = NULL;
3154        errno = 0;
3155        process_signo = strtoul (p + 1, &end, 16);
3156        if (errno != 0)
3157            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
3158        else if (*end == ';')
3159        {
3160            errno = 0;
3161            action.addr = strtoull (end + 1, NULL, 16);
3162            if (errno != 0 && action.addr == 0)
3163                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
3164        }
3165    }
3166
3167    DNBThreadResumeActions thread_actions;
3168    thread_actions.Append (action);
3169    thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
3170    if (!DNBProcessSignal(pid, process_signo))
3171        return SendPacket ("E52");
3172    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3173        return SendPacket ("E38");
3174    /* Don't send an "OK" packet; response is the stopped/exited message.  */
3175    return rnb_success;
3176}
3177
3178//----------------------------------------------------------------------
3179// 'D' packet
3180// Detach from gdb.
3181//----------------------------------------------------------------------
3182rnb_err_t
3183RNBRemote::HandlePacket_D (const char *p)
3184{
3185    // We are not supposed to send a response for deatch.
3186    //SendPacket ("OK");
3187    if (m_ctx.HasValidProcessID())
3188        DNBProcessDetach(m_ctx.ProcessID());
3189    return rnb_success;
3190}
3191
3192/* `k'
3193 Kill the inferior process.  */
3194
3195rnb_err_t
3196RNBRemote::HandlePacket_k (const char *p)
3197{
3198    // No response to should be sent to the kill packet
3199    if (m_ctx.HasValidProcessID())
3200        DNBProcessKill (m_ctx.ProcessID());
3201    SendPacket ("W09");
3202    return rnb_success;
3203}
3204
3205rnb_err_t
3206RNBRemote::HandlePacket_stop_process (const char *p)
3207{
3208    DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
3209    //DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
3210    // Do not send any response packet! Wait for the stop reply packet to naturally happen
3211    return rnb_success;
3212}
3213
3214/* `s'
3215 Step the inferior process.  */
3216
3217rnb_err_t
3218RNBRemote::HandlePacket_s (const char *p)
3219{
3220    const nub_process_t pid = m_ctx.ProcessID();
3221    if (pid == INVALID_NUB_PROCESS)
3222        return SendPacket ("E32");
3223
3224    // Hardware supported stepping not supported on arm
3225    nub_thread_t tid = GetContinueThread ();
3226    if (tid == 0 || tid == -1)
3227        tid = GetCurrentThread();
3228
3229    if (tid == INVALID_NUB_THREAD)
3230        return SendPacket ("E33");
3231
3232    DNBThreadResumeActions thread_actions;
3233    thread_actions.AppendAction(tid, eStateStepping);
3234
3235    // Make all other threads stop when we are stepping
3236    thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3237    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3238        return SendPacket ("E49");
3239    // Don't send an "OK" packet; response is the stopped/exited message.
3240    return rnb_success;
3241}
3242
3243/* `S sig [;addr]'
3244 Step with signal sig, optionally at address addr.  */
3245
3246rnb_err_t
3247RNBRemote::HandlePacket_S (const char *p)
3248{
3249    const nub_process_t pid = m_ctx.ProcessID();
3250    if (pid == INVALID_NUB_PROCESS)
3251        return SendPacket ("E36");
3252
3253    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
3254
3255    if (*(p + 1) != '\0')
3256    {
3257        char *end = NULL;
3258        errno = 0;
3259        action.signal = strtoul (p + 1, &end, 16);
3260        if (errno != 0)
3261            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
3262        else if (*end == ';')
3263        {
3264            errno = 0;
3265            action.addr = strtoull (end + 1, NULL, 16);
3266            if (errno != 0 && action.addr == 0)
3267            {
3268                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
3269            }
3270        }
3271    }
3272
3273    action.tid = GetContinueThread ();
3274    if (action.tid == 0 || action.tid == -1)
3275        return SendPacket ("E40");
3276
3277    nub_state_t tstate = DNBThreadGetState (pid, action.tid);
3278    if (tstate == eStateInvalid || tstate == eStateExited)
3279        return SendPacket ("E37");
3280
3281
3282    DNBThreadResumeActions thread_actions;
3283    thread_actions.Append (action);
3284
3285    // Make all other threads stop when we are stepping
3286    thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
3287    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3288        return SendPacket ("E39");
3289
3290    // Don't send an "OK" packet; response is the stopped/exited message.
3291    return rnb_success;
3292}
3293
3294rnb_err_t
3295RNBRemote::HandlePacket_qHostInfo (const char *p)
3296{
3297    std::ostringstream strm;
3298
3299    uint32_t cputype, is_64_bit_capable;
3300    size_t len = sizeof(cputype);
3301    bool promoted_to_64 = false;
3302    if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
3303    {
3304        len = sizeof (is_64_bit_capable);
3305        if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
3306        {
3307            if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
3308            {
3309                promoted_to_64 = true;
3310                cputype |= CPU_ARCH_ABI64;
3311            }
3312        }
3313
3314        strm << "cputype:" << std::dec << cputype << ';';
3315    }
3316
3317    uint32_t cpusubtype;
3318    len = sizeof(cpusubtype);
3319    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
3320    {
3321        if (promoted_to_64 &&
3322            cputype == CPU_TYPE_X86_64 &&
3323            cpusubtype == CPU_SUBTYPE_486)
3324            cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3325
3326        strm << "cpusubtype:" << std::dec << cpusubtype << ';';
3327    }
3328
3329    char ostype[64];
3330    len = sizeof(ostype);
3331    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
3332    {
3333        len = strlen(ostype);
3334        std::transform (ostype, ostype + len, ostype, tolower);
3335        strm << "ostype:" << std::dec << ostype << ';';
3336    }
3337
3338    strm << "vendor:apple;";
3339
3340#if defined (__LITTLE_ENDIAN__)
3341    strm << "endian:little;";
3342#elif defined (__BIG_ENDIAN__)
3343    strm << "endian:big;";
3344#elif defined (__PDP_ENDIAN__)
3345    strm << "endian:pdp;";
3346#endif
3347
3348    if (promoted_to_64)
3349        strm << "ptrsize:8;";
3350    else
3351        strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
3352    return SendPacket (strm.str());
3353}
3354
3355rnb_err_t
3356RNBRemote::HandlePacket_qProcessInfo (const char *p)
3357{
3358    return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
3359}
3360
3361rnb_err_t
3362RNBRemote::HandlePacket_qfProcessInfoAll (const char *p)
3363{
3364    return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
3365}
3366
3367rnb_err_t
3368RNBRemote::HandlePacket_qfProcessInfoName (const char *p)
3369{
3370    return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
3371}
3372
3373rnb_err_t
3374RNBRemote::HandlePacket_qsProcessInfo (const char *p)
3375{
3376    return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
3377}
3378
3379
3380
3381