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