RNBRemote.cpp revision 5a26910ed231503d2a7a71365a44e379a994f4e6
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            case GENERIC_REGNUM_ARG1:   ostrm << "generic:arg1;"; break;
1457            case GENERIC_REGNUM_ARG2:   ostrm << "generic:arg2;"; break;
1458            case GENERIC_REGNUM_ARG3:   ostrm << "generic:arg3;"; break;
1459            case GENERIC_REGNUM_ARG4:   ostrm << "generic:arg4;"; break;
1460            case GENERIC_REGNUM_ARG5:   ostrm << "generic:arg5;"; break;
1461            case GENERIC_REGNUM_ARG6:   ostrm << "generic:arg6;"; break;
1462            case GENERIC_REGNUM_ARG7:   ostrm << "generic:arg7;"; break;
1463            case GENERIC_REGNUM_ARG8:   ostrm << "generic:arg8;"; break;
1464            default: break;
1465        }
1466
1467        return SendPacket (ostrm.str ());
1468    }
1469    return SendPacket ("E45");
1470}
1471
1472
1473/* This expects a packet formatted like
1474
1475 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
1476
1477 with the "QSetLogging:" already removed from the start.  Maybe in the
1478 future this packet will include other keyvalue pairs like
1479
1480 QSetLogging:bitmask=LOG_ALL;mode=asl;
1481 */
1482
1483rnb_err_t
1484set_logging (const char *p)
1485{
1486    int bitmask = 0;
1487    while (p && *p != '\0')
1488    {
1489        if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0)
1490        {
1491            p += sizeof ("bitmask=") - 1;
1492            while (p && *p != '\0' && *p != ';')
1493            {
1494                if (*p == '|')
1495                    p++;
1496                if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
1497                {
1498                    p += sizeof ("LOG_VERBOSE") - 1;
1499                    bitmask |= LOG_VERBOSE;
1500                }
1501                else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0)
1502                {
1503                    p += sizeof ("LOG_PROCESS") - 1;
1504                    bitmask |= LOG_PROCESS;
1505                }
1506                else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0)
1507                {
1508                    p += sizeof ("LOG_THREAD") - 1;
1509                    bitmask |= LOG_THREAD;
1510                }
1511                else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0)
1512                {
1513                    p += sizeof ("LOG_EXCEPTIONS") - 1;
1514                    bitmask |= LOG_EXCEPTIONS;
1515                }
1516                else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0)
1517                {
1518                    p += sizeof ("LOG_SHLIB") - 1;
1519                    bitmask |= LOG_SHLIB;
1520                }
1521                else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0)
1522                {
1523                    p += sizeof ("LOG_MEMORY") - 1;
1524                    bitmask |= LOG_MEMORY;
1525                }
1526                else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0)
1527                {
1528                    p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1;
1529                    bitmask |= LOG_MEMORY_DATA_SHORT;
1530                }
1531                else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0)
1532                {
1533                    p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
1534                    bitmask |= LOG_MEMORY_DATA_LONG;
1535                }
1536                else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
1537                {
1538                    p += sizeof ("LOG_BREAKPOINTS") - 1;
1539                    bitmask |= LOG_BREAKPOINTS;
1540                }
1541                else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
1542                {
1543                    p += sizeof ("LOG_ALL") - 1;
1544                    bitmask |= LOG_ALL;
1545                }
1546                else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
1547                {
1548                    p += sizeof ("LOG_EVENTS") - 1;
1549                    bitmask |= LOG_EVENTS;
1550                }
1551                else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
1552                {
1553                    p += sizeof ("LOG_DEFAULT") - 1;
1554                    bitmask |= LOG_DEFAULT;
1555                }
1556                else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
1557                {
1558                    p += sizeof ("LOG_NONE") - 1;
1559                    bitmask = 0;
1560                }
1561                else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0)
1562                {
1563                    p += sizeof ("LOG_RNB_MINIMAL") - 1;
1564                    bitmask |= LOG_RNB_MINIMAL;
1565                }
1566                else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0)
1567                {
1568                    p += sizeof ("LOG_RNB_MEDIUM") - 1;
1569                    bitmask |= LOG_RNB_MEDIUM;
1570                }
1571                else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0)
1572                {
1573                    p += sizeof ("LOG_RNB_MAX") - 1;
1574                    bitmask |= LOG_RNB_MAX;
1575                }
1576                else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0)
1577                {
1578                    p += sizeof ("LOG_RNB_COMM") - 1;
1579                    bitmask |= LOG_RNB_COMM;
1580                }
1581                else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0)
1582                {
1583                    p += sizeof ("LOG_RNB_REMOTE") - 1;
1584                    bitmask |= LOG_RNB_REMOTE;
1585                }
1586                else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0)
1587                {
1588                    p += sizeof ("LOG_RNB_EVENTS") - 1;
1589                    bitmask |= LOG_RNB_EVENTS;
1590                }
1591                else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0)
1592                {
1593                    p += sizeof ("LOG_RNB_PROC") - 1;
1594                    bitmask |= LOG_RNB_PROC;
1595                }
1596                else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0)
1597                {
1598                    p += sizeof ("LOG_RNB_PACKETS") - 1;
1599                    bitmask |= LOG_RNB_PACKETS;
1600                }
1601                else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0)
1602                {
1603                    p += sizeof ("LOG_RNB_ALL") - 1;
1604                    bitmask |= LOG_RNB_ALL;
1605                }
1606                else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0)
1607                {
1608                    p += sizeof ("LOG_RNB_DEFAULT") - 1;
1609                    bitmask |= LOG_RNB_DEFAULT;
1610                }
1611                else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0)
1612                {
1613                    p += sizeof ("LOG_RNB_NONE") - 1;
1614                    bitmask = 0;
1615                }
1616                else
1617                {
1618                    /* Unrecognized logging bit; ignore it.  */
1619                    const char *c = strchr (p, '|');
1620                    if (c)
1621                    {
1622                        p = c;
1623                    }
1624                    else
1625                    {
1626                        c = strchr (p, ';');
1627                        if (c)
1628                        {
1629                            p = c;
1630                        }
1631                        else
1632                        {
1633                            // Improperly terminated word; just go to end of str
1634                            p = strchr (p, '\0');
1635                        }
1636                    }
1637                }
1638            }
1639            // Did we get a properly formatted logging bitmask?
1640            if (*p == ';')
1641            {
1642                // Enable DNB logging
1643                DNBLogSetLogCallback(ASLLogCallback, NULL);
1644                DNBLogSetLogMask (bitmask);
1645                p++;
1646            }
1647        }
1648        // We're not going to support logging to a file for now.  All logging
1649        // goes through ASL.
1650#if 0
1651        else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
1652        {
1653            p += sizeof ("mode=") - 1;
1654            if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
1655            {
1656                DNBLogToASL ();
1657                p += sizeof ("asl;") - 1;
1658            }
1659            else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
1660            {
1661                DNBLogToFile ();
1662                p += sizeof ("file;") - 1;
1663            }
1664            else
1665            {
1666                // Ignore unknown argument
1667                const char *c = strchr (p, ';');
1668                if (c)
1669                    p = c + 1;
1670                else
1671                    p = strchr (p, '\0');
1672            }
1673        }
1674        else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
1675        {
1676            p += sizeof ("filename=") - 1;
1677            const char *c = strchr (p, ';');
1678            if (c == NULL)
1679            {
1680                c = strchr (p, '\0');
1681                continue;
1682            }
1683            char *fn = (char *) alloca (c - p + 1);
1684            strncpy (fn, p, c - p);
1685            fn[c - p] = '\0';
1686
1687            // A file name of "asl" is special and is another way to indicate
1688            // that logging should be done via ASL, not by file.
1689            if (strcmp (fn, "asl") == 0)
1690            {
1691                DNBLogToASL ();
1692            }
1693            else
1694            {
1695                FILE *f = fopen (fn, "w");
1696                if (f)
1697                {
1698                    DNBLogSetLogFile (f);
1699                    DNBEnableLogging (f, DNBLogGetLogMask ());
1700                    DNBLogToFile ();
1701                }
1702            }
1703            p = c + 1;
1704        }
1705#endif /* #if 0 to enforce ASL logging only.  */
1706        else
1707        {
1708            // Ignore unknown argument
1709            const char *c = strchr (p, ';');
1710            if (c)
1711                p = c + 1;
1712            else
1713                p = strchr (p, '\0');
1714        }
1715    }
1716
1717    return rnb_success;
1718}
1719
1720rnb_err_t
1721RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
1722{
1723    m_thread_suffix_supported = true;
1724    return SendPacket ("OK");
1725}
1726
1727rnb_err_t
1728RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
1729{
1730    // Send the OK packet first so the correct checksum is appended...
1731    rnb_err_t result = SendPacket ("OK");
1732    m_noack_mode = true;
1733    return result;
1734}
1735
1736
1737rnb_err_t
1738RNBRemote::HandlePacket_QSetLogging (const char *p)
1739{
1740    p += sizeof ("QSetLogging:") - 1;
1741    rnb_err_t result = set_logging (p);
1742    if (result == rnb_success)
1743        return SendPacket ("OK");
1744    else
1745        return SendPacket ("E35");
1746}
1747
1748rnb_err_t
1749RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
1750{
1751    extern int g_disable_aslr;
1752    p += sizeof ("QSetDisableASLR:") - 1;
1753    switch (*p)
1754    {
1755    case '0': g_disable_aslr = 0; break;
1756    case '1': g_disable_aslr = 1; break;
1757    default:
1758        return SendPacket ("E56");
1759    }
1760    return SendPacket ("OK");
1761}
1762
1763rnb_err_t
1764RNBRemote::HandlePacket_QSetSTDIO (const char *p)
1765{
1766    // Only set stdin/out/err if we don't already have a process
1767    if (!m_ctx.HasValidProcessID())
1768    {
1769        bool success = false;
1770        // Check the seventh character since the packet will be one of:
1771        // QSetSTDIN
1772        // QSetSTDOUT
1773        // QSetSTDERR
1774        StringExtractor packet(p);
1775        packet.SetFilePos (7);
1776        char ch = packet.GetChar();
1777        while (packet.GetChar() != ':')
1778            /* Do nothing. */;
1779
1780        switch (ch)
1781        {
1782            case 'I': // STDIN
1783                packet.GetHexByteString (m_ctx.GetSTDIN());
1784                success = !m_ctx.GetSTDIN().empty();
1785                break;
1786
1787            case 'O': // STDOUT
1788                packet.GetHexByteString (m_ctx.GetSTDOUT());
1789                success = !m_ctx.GetSTDOUT().empty();
1790                break;
1791
1792            case 'E': // STDERR
1793                packet.GetHexByteString (m_ctx.GetSTDERR());
1794                success = !m_ctx.GetSTDERR().empty();
1795                break;
1796
1797            default:
1798                break;
1799        }
1800        if (success)
1801            return SendPacket ("OK");
1802        return SendPacket ("E57");
1803    }
1804    return SendPacket ("E58");
1805}
1806
1807rnb_err_t
1808RNBRemote::HandlePacket_QSetWorkingDir (const char *p)
1809{
1810    // Only set the working directory if we don't already have a process
1811    if (!m_ctx.HasValidProcessID())
1812    {
1813        StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);
1814        if (packet.GetHexByteString (m_ctx.GetWorkingDir()))
1815        {
1816            struct stat working_dir_stat;
1817            if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1)
1818            {
1819                m_ctx.GetWorkingDir().clear();
1820                return SendPacket ("E61");    // Working directory doesn't exist...
1821            }
1822            else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR)
1823            {
1824                return SendPacket ("OK");
1825            }
1826            else
1827            {
1828                m_ctx.GetWorkingDir().clear();
1829                return SendPacket ("E62");    // Working directory isn't a directory...
1830            }
1831        }
1832        return SendPacket ("E59");  // Invalid path
1833    }
1834    return SendPacket ("E60"); // Already had a process, too late to set working dir
1835}
1836
1837
1838rnb_err_t
1839RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
1840{
1841    /* The number of characters in a packet payload that gdb is
1842     prepared to accept.  The packet-start char, packet-end char,
1843     2 checksum chars and terminating null character are not included
1844     in this size.  */
1845    p += sizeof ("QSetMaxPayloadSize:") - 1;
1846    errno = 0;
1847    uint32_t size = strtoul (p, NULL, 16);
1848    if (errno != 0 && size == 0)
1849    {
1850        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
1851    }
1852    m_max_payload_size = size;
1853    return SendPacket ("OK");
1854}
1855
1856rnb_err_t
1857RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
1858{
1859    /* This tells us the largest packet that gdb can handle.
1860     i.e. the size of gdb's packet-reading buffer.
1861     QSetMaxPayloadSize is preferred because it is less ambiguous.  */
1862    p += sizeof ("QSetMaxPacketSize:") - 1;
1863    errno = 0;
1864    uint32_t size = strtoul (p, NULL, 16);
1865    if (errno != 0 && size == 0)
1866    {
1867        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
1868    }
1869    m_max_payload_size = size - 5;
1870    return SendPacket ("OK");
1871}
1872
1873
1874
1875
1876rnb_err_t
1877RNBRemote::HandlePacket_QEnvironment (const char *p)
1878{
1879    /* This sets the environment for the target program.  The packet is of the form:
1880
1881     QEnvironment:VARIABLE=VALUE
1882
1883     */
1884
1885    DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
1886                      (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
1887
1888    p += sizeof ("QEnvironment:") - 1;
1889    RNBContext& ctx = Context();
1890
1891    ctx.PushEnvironment (p);
1892    return SendPacket ("OK");
1893}
1894
1895rnb_err_t
1896RNBRemote::HandlePacket_QLaunchArch (const char *p)
1897{
1898    p += sizeof ("QLaunchArch:") - 1;
1899    if (DNBSetArchitecture(p))
1900        return SendPacket ("OK");
1901    return SendPacket ("E63");
1902}
1903
1904void
1905append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap)
1906{
1907    int i;
1908    if (swap)
1909    {
1910        for (i = buf_size-1; i >= 0; i--)
1911            ostrm << RAWHEX8(buf[i]);
1912    }
1913    else
1914    {
1915        for (i = 0; i < buf_size; i++)
1916            ostrm << RAWHEX8(buf[i]);
1917    }
1918}
1919
1920
1921void
1922register_value_in_hex_fixed_width (std::ostream& ostrm,
1923                                   nub_process_t pid,
1924                                   nub_thread_t tid,
1925                                   const register_map_entry_t* reg)
1926{
1927    if (reg != NULL)
1928    {
1929        DNBRegisterValue val;
1930        if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &val))
1931        {
1932            append_hex_value (ostrm, val.value.v_uint8, reg->gdb_size, false);
1933        }
1934        else
1935        {
1936            // If we fail to read a regiser value, check if it has a default
1937            // fail value. If it does, return this instead in case some of
1938            // the registers are not available on the current system.
1939            if (reg->gdb_size > 0)
1940            {
1941                if (reg->fail_value != NULL)
1942                {
1943                    append_hex_value (ostrm, reg->fail_value, reg->gdb_size, false);
1944                }
1945                else
1946                {
1947                    std::basic_string<uint8_t> zeros(reg->gdb_size, '\0');
1948                    append_hex_value (ostrm, zeros.data(), zeros.size(), false);
1949                }
1950            }
1951        }
1952    }
1953}
1954
1955
1956void
1957gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
1958                                                nub_process_t pid,
1959                                                nub_thread_t tid,
1960                                                const register_map_entry_t* reg)
1961{
1962    // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
1963    // gdb register number, and VVVVVVVV is the correct number of hex bytes
1964    // as ASCII for the register value.
1965    if (reg != NULL)
1966    {
1967        ostrm << RAWHEX8(reg->gdb_regnum) << ':';
1968        register_value_in_hex_fixed_width (ostrm, pid, tid, reg);
1969        ostrm << ';';
1970    }
1971}
1972
1973rnb_err_t
1974RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
1975{
1976    const nub_process_t pid = m_ctx.ProcessID();
1977    if (pid == INVALID_NUB_PROCESS)
1978        return SendPacket("E50");
1979
1980    struct DNBThreadStopInfo tid_stop_info;
1981
1982    /* Fill the remaining space in this packet with as many registers
1983     as we can stuff in there.  */
1984
1985    if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
1986    {
1987        std::ostringstream ostrm;
1988        // Output the T packet with the thread
1989        ostrm << 'T';
1990        int signum = tid_stop_info.details.signal.signo;
1991        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);
1992
1993        // Translate any mach exceptions to gdb versions, unless they are
1994        // common exceptions like a breakpoint or a soft signal.
1995        switch (tid_stop_info.details.exception.type)
1996        {
1997            default:                    signum = 0; break;
1998            case EXC_BREAKPOINT:        signum = SIGTRAP; break;
1999            case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2000            case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2001            case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2002            case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2003            case EXC_SOFTWARE:
2004                if (tid_stop_info.details.exception.data_count == 2 &&
2005                    tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2006                    signum = tid_stop_info.details.exception.data[1];
2007                else
2008                    signum = TARGET_EXC_SOFTWARE;
2009                break;
2010        }
2011
2012        ostrm << RAWHEX8(signum & 0xff);
2013
2014        ostrm << std::hex << "thread:" << tid << ';';
2015
2016        const char *thread_name = DNBThreadGetName (pid, tid);
2017        if (thread_name && thread_name[0])
2018        {
2019            size_t thread_name_len = strlen(thread_name);
2020
2021            if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2022                ostrm << std::hex << "name:" << thread_name << ';';
2023            else
2024            {
2025                // the thread name contains special chars, send as hex bytes
2026                ostrm << std::hex << "hexname:";
2027                uint8_t *u_thread_name = (uint8_t *)thread_name;
2028                for (int i = 0; i < thread_name_len; i++)
2029                    ostrm << RAWHEX8(u_thread_name[i]);
2030                ostrm << ';';
2031            }
2032        }
2033
2034        thread_identifier_info_data_t thread_ident_info;
2035        if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
2036        {
2037            if (thread_ident_info.dispatch_qaddr != 0)
2038                ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
2039        }
2040        if (g_num_reg_entries == 0)
2041            InitializeRegisters ();
2042
2043        DNBRegisterValue reg_value;
2044        for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2045        {
2046            if (g_reg_entries[reg].expedite)
2047            {
2048                if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
2049                    continue;
2050
2051                gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg]);
2052            }
2053        }
2054
2055        if (tid_stop_info.details.exception.type)
2056        {
2057            ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";";
2058            ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";";
2059            for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
2060                ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";";
2061        }
2062        return SendPacket (ostrm.str ());
2063    }
2064    return SendPacket("E51");
2065}
2066
2067/* `?'
2068 The stop reply packet - tell gdb what the status of the inferior is.
2069 Often called the questionmark_packet.  */
2070
2071rnb_err_t
2072RNBRemote::HandlePacket_last_signal (const char *unused)
2073{
2074    if (!m_ctx.HasValidProcessID())
2075    {
2076        // Inferior is not yet specified/running
2077        return SendPacket ("E02");
2078    }
2079
2080    nub_process_t pid = m_ctx.ProcessID();
2081    nub_state_t pid_state = DNBProcessGetState (pid);
2082
2083    switch (pid_state)
2084    {
2085        case eStateAttaching:
2086        case eStateLaunching:
2087        case eStateRunning:
2088        case eStateStepping:
2089        case eStateDetached:
2090            return rnb_success;  // Ignore
2091
2092        case eStateSuspended:
2093        case eStateStopped:
2094        case eStateCrashed:
2095            {
2096                nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2097                // Make sure we set the current thread so g and p packets return
2098                // the data the gdb will expect.
2099                SetCurrentThread (tid);
2100
2101                SendStopReplyPacketForThread (tid);
2102            }
2103            break;
2104
2105        case eStateInvalid:
2106        case eStateUnloaded:
2107        case eStateExited:
2108            {
2109                char pid_exited_packet[16] = "";
2110                int pid_status = 0;
2111                // Process exited with exit status
2112                if (!DNBProcessGetExitStatus(pid, &pid_status))
2113                    pid_status = 0;
2114
2115                if (pid_status)
2116                {
2117                    if (WIFEXITED (pid_status))
2118                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2119                    else if (WIFSIGNALED (pid_status))
2120                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2121                    else if (WIFSTOPPED (pid_status))
2122                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2123                }
2124
2125                // If we have an empty exit packet, lets fill one in to be safe.
2126                if (!pid_exited_packet[0])
2127                {
2128                    strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2129                    pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2130                }
2131
2132                return SendPacket (pid_exited_packet);
2133            }
2134            break;
2135    }
2136    return rnb_success;
2137}
2138
2139rnb_err_t
2140RNBRemote::HandlePacket_M (const char *p)
2141{
2142    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2143    {
2144        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2145    }
2146
2147    char *c;
2148    p++;
2149    errno = 0;
2150    nub_addr_t addr = strtoull (p, &c, 16);
2151    if (errno != 0 && addr == 0)
2152    {
2153        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2154    }
2155    if (*c != ',')
2156    {
2157        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2158    }
2159
2160    /* Advance 'p' to the length part of the packet.  */
2161    p += (c - p) + 1;
2162
2163    errno = 0;
2164    uint32_t length = strtoul (p, &c, 16);
2165    if (errno != 0 && length == 0)
2166    {
2167        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2168    }
2169    if (length == 0)
2170    {
2171        return SendPacket ("OK");
2172    }
2173
2174    if (*c != ':')
2175    {
2176        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2177    }
2178    /* Advance 'p' to the data part of the packet.  */
2179    p += (c - p) + 1;
2180
2181    int datalen = strlen (p);
2182    if (datalen & 0x1)
2183    {
2184        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2185    }
2186    if (datalen == 0)
2187    {
2188        return SendPacket ("OK");
2189    }
2190
2191    uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2192    uint8_t *i = buf;
2193
2194    while (*p != '\0' && *(p + 1) != '\0')
2195    {
2196        char hexbuf[3];
2197        hexbuf[0] = *p;
2198        hexbuf[1] = *(p + 1);
2199        hexbuf[2] = '\0';
2200        errno = 0;
2201        uint8_t byte = strtoul (hexbuf, NULL, 16);
2202        if (errno != 0 && byte == 0)
2203        {
2204            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2205        }
2206        *i++ = byte;
2207        p += 2;
2208    }
2209
2210    nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2211    if (wrote != length)
2212        return SendPacket ("E09");
2213    else
2214        return SendPacket ("OK");
2215}
2216
2217
2218rnb_err_t
2219RNBRemote::HandlePacket_m (const char *p)
2220{
2221    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2222    {
2223        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
2224    }
2225
2226    char *c;
2227    p++;
2228    errno = 0;
2229    nub_addr_t addr = strtoull (p, &c, 16);
2230    if (errno != 0 && addr == 0)
2231    {
2232        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
2233    }
2234    if (*c != ',')
2235    {
2236        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
2237    }
2238
2239    /* Advance 'p' to the length part of the packet.  */
2240    p += (c - p) + 1;
2241
2242    errno = 0;
2243    uint32_t length = strtoul (p, NULL, 16);
2244    if (errno != 0 && length == 0)
2245    {
2246        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2247    }
2248    if (length == 0)
2249    {
2250        return SendPacket ("");
2251    }
2252
2253    uint8_t buf[length];
2254    int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf);
2255    if (bytes_read == 0)
2256    {
2257        return SendPacket ("E08");
2258    }
2259
2260    // "The reply may contain fewer bytes than requested if the server was able
2261    //  to read only part of the region of memory."
2262    length = bytes_read;
2263
2264    std::ostringstream ostrm;
2265    for (int i = 0; i < length; i++)
2266        ostrm << RAWHEX8(buf[i]);
2267    return SendPacket (ostrm.str ());
2268}
2269
2270rnb_err_t
2271RNBRemote::HandlePacket_X (const char *p)
2272{
2273    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2274    {
2275        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
2276    }
2277
2278    char *c;
2279    p++;
2280    errno = 0;
2281    nub_addr_t addr = strtoull (p, &c, 16);
2282    if (errno != 0 && addr == 0)
2283    {
2284        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
2285    }
2286    if (*c != ',')
2287    {
2288        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
2289    }
2290
2291    /* Advance 'p' to the length part of the packet.  */
2292    p += (c - p) + 1;
2293
2294    errno = 0;
2295    int length = strtoul (p, NULL, 16);
2296    if (errno != 0 && length == 0)
2297    {
2298        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2299    }
2300
2301    // I think gdb sends a zero length write request to test whether this
2302    // packet is accepted.
2303    if (length == 0)
2304    {
2305        return SendPacket ("OK");
2306    }
2307
2308    std::vector<uint8_t> data = decode_binary_data (c, -1);
2309    std::vector<uint8_t>::const_iterator it;
2310    uint8_t *buf = (uint8_t *) alloca (data.size ());
2311    uint8_t *i = buf;
2312    for (it = data.begin (); it != data.end (); ++it)
2313    {
2314        *i++ = *it;
2315    }
2316
2317    nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
2318    if (wrote != data.size ())
2319        return SendPacket ("E08");
2320    return SendPacket ("OK");
2321}
2322
2323/* `g' -- read registers
2324 Get the contents of the registers for the current thread,
2325 send them to gdb.
2326 Should the setting of the Hg packet determine which thread's registers
2327 are returned?  */
2328
2329rnb_err_t
2330RNBRemote::HandlePacket_g (const char *p)
2331{
2332    std::ostringstream ostrm;
2333    if (!m_ctx.HasValidProcessID())
2334    {
2335        return SendPacket ("E11");
2336    }
2337
2338    if (g_num_reg_entries == 0)
2339        InitializeRegisters ();
2340
2341    nub_process_t pid = m_ctx.ProcessID ();
2342    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
2343    if (tid == INVALID_NUB_THREAD)
2344        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2345
2346    if (m_use_native_regs)
2347    {
2348        // Get the register context size first by calling with NULL buffer
2349        nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2350        if (reg_ctx_size)
2351        {
2352            // Now allocate enough space for the entire register context
2353            std::vector<uint8_t> reg_ctx;
2354            reg_ctx.resize(reg_ctx_size);
2355            // Now read the register context
2356            reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
2357            if (reg_ctx_size)
2358            {
2359                append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
2360                return SendPacket (ostrm.str ());
2361            }
2362        }
2363    }
2364
2365    for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2366        register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg]);
2367
2368    return SendPacket (ostrm.str ());
2369}
2370
2371/* `G XXX...' -- write registers
2372 How is the thread for these specified, beyond "the current thread"?
2373 Does gdb actually use the Hg packet to set this?  */
2374
2375rnb_err_t
2376RNBRemote::HandlePacket_G (const char *p)
2377{
2378    if (!m_ctx.HasValidProcessID())
2379    {
2380        return SendPacket ("E11");
2381    }
2382
2383    if (g_num_reg_entries == 0)
2384        InitializeRegisters ();
2385
2386    StringExtractor packet(p);
2387    packet.SetFilePos(1); // Skip the 'G'
2388
2389    nub_process_t pid = m_ctx.ProcessID();
2390    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2391    if (tid == INVALID_NUB_THREAD)
2392        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2393
2394    if (m_use_native_regs)
2395    {
2396        // Get the register context size first by calling with NULL buffer
2397        nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2398        if (reg_ctx_size)
2399        {
2400            // Now allocate enough space for the entire register context
2401            std::vector<uint8_t> reg_ctx;
2402            reg_ctx.resize(reg_ctx_size);
2403
2404            if (packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc) == reg_ctx.size())
2405            {
2406                // Now write the register context
2407                reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
2408                if (reg_ctx_size == reg_ctx.size())
2409                    return SendPacket ("OK");
2410                else
2411                    return SendPacket ("E55");
2412            }
2413        }
2414    }
2415
2416
2417    DNBRegisterValue reg_value;
2418    for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2419    {
2420        const register_map_entry_t *reg_entry = &g_reg_entries[reg];
2421
2422        reg_value.info = reg_entry->nub_info;
2423        if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size)
2424            break;
2425
2426        if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
2427            return SendPacket ("E15");
2428    }
2429    return SendPacket ("OK");
2430}
2431
2432static bool
2433RNBRemoteShouldCancelCallback (void *not_used)
2434{
2435    RNBRemoteSP remoteSP(g_remoteSP);
2436    if (remoteSP.get() != NULL)
2437    {
2438        RNBRemote* remote = remoteSP.get();
2439        if (remote->Comm().IsConnected())
2440            return false;
2441        else
2442            return true;
2443    }
2444    return true;
2445}
2446
2447
2448// FORMAT: _MXXXXXX,PPP
2449//      XXXXXX: big endian hex chars
2450//      PPP: permissions can be any combo of r w x chars
2451//
2452// RESPONSE: XXXXXX
2453//      XXXXXX: hex address of the newly allocated memory
2454//      EXX: error code
2455//
2456// EXAMPLES:
2457//      _M123000,rw
2458//      _M123000,rwx
2459//      _M123000,xw
2460
2461rnb_err_t
2462RNBRemote::HandlePacket_AllocateMemory (const char *p)
2463{
2464    StringExtractor packet (p);
2465    packet.SetFilePos(2); // Skip the "_M"
2466
2467    nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
2468    if (size != 0)
2469    {
2470        if (packet.GetChar() == ',')
2471        {
2472            uint32_t permissions = 0;
2473            char ch;
2474            bool success = true;
2475            while (success && (ch = packet.GetChar()) != '\0')
2476            {
2477                switch (ch)
2478                {
2479                case 'r':   permissions |= eMemoryPermissionsReadable; break;
2480                case 'w':   permissions |= eMemoryPermissionsWritable; break;
2481                case 'x':   permissions |= eMemoryPermissionsExecutable; break;
2482                default:    success = false; break;
2483                }
2484            }
2485
2486            if (success)
2487            {
2488                nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
2489                if (addr != INVALID_NUB_ADDRESS)
2490                {
2491                    std::ostringstream ostrm;
2492                    ostrm << RAW_HEXBASE << addr;
2493                    return SendPacket (ostrm.str ());
2494                }
2495            }
2496        }
2497    }
2498    return SendPacket ("E53");
2499}
2500
2501// FORMAT: _mXXXXXX
2502//      XXXXXX: address that was previosly allocated
2503//
2504// RESPONSE: XXXXXX
2505//      OK: address was deallocated
2506//      EXX: error code
2507//
2508// EXAMPLES:
2509//      _m123000
2510
2511rnb_err_t
2512RNBRemote::HandlePacket_DeallocateMemory (const char *p)
2513{
2514    StringExtractor packet (p);
2515    packet.SetFilePos(2); // Skip the "_m"
2516    nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
2517
2518    if (addr != INVALID_NUB_ADDRESS)
2519    {
2520        if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
2521            return SendPacket ("OK");
2522    }
2523    return SendPacket ("E54");
2524}
2525
2526/*
2527 vAttach;pid
2528
2529 Attach to a new process with the specified process ID. pid is a hexadecimal integer
2530 identifying the process. If the stub is currently controlling a process, it is
2531 killed. The attached process is stopped.This packet is only available in extended
2532 mode (see extended mode).
2533
2534 Reply:
2535 "ENN"                      for an error
2536 "Any Stop Reply Packet"     for success
2537 */
2538
2539rnb_err_t
2540RNBRemote::HandlePacket_v (const char *p)
2541{
2542    if (strcmp (p, "vCont;c") == 0)
2543    {
2544        // Simple continue
2545        return RNBRemote::HandlePacket_c("c");
2546    }
2547    else if (strcmp (p, "vCont;s") == 0)
2548    {
2549        // Simple step
2550        return RNBRemote::HandlePacket_s("s");
2551    }
2552    else if (strstr (p, "vCont") == p)
2553    {
2554        rnb_err_t rnb_err = rnb_success;
2555        typedef struct
2556        {
2557            nub_thread_t tid;
2558            char action;
2559            int signal;
2560        } vcont_action_t;
2561
2562        DNBThreadResumeActions thread_actions;
2563        char *c = (char *)(p += strlen("vCont"));
2564        char *c_end = c + strlen(c);
2565        if (*c == '?')
2566            return SendPacket ("vCont;c;C;s;S");
2567
2568        while (c < c_end && *c == ';')
2569        {
2570            ++c;    // Skip the semi-colon
2571            DNBThreadResumeAction thread_action;
2572            thread_action.tid = INVALID_NUB_THREAD;
2573            thread_action.state = eStateInvalid;
2574            thread_action.signal = 0;
2575            thread_action.addr = INVALID_NUB_ADDRESS;
2576
2577            char action = *c++;
2578
2579            switch (action)
2580            {
2581                case 'C':
2582                    errno = 0;
2583                    thread_action.signal = strtoul (c, &c, 16);
2584                    if (errno != 0)
2585                        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2586                    // Fall through to next case...
2587
2588                case 'c':
2589                    // Continue
2590                    thread_action.state = eStateRunning;
2591                    break;
2592
2593                case 'S':
2594                    errno = 0;
2595                    thread_action.signal = strtoul (c, &c, 16);
2596                    if (errno != 0)
2597                        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2598                    // Fall through to next case...
2599
2600                case 's':
2601                    // Step
2602                    thread_action.state = eStateStepping;
2603                    break;
2604
2605                    break;
2606
2607                default:
2608                    rnb_err = HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
2609                    break;
2610            }
2611            if (*c == ':')
2612            {
2613                errno = 0;
2614                thread_action.tid = strtoul (++c, &c, 16);
2615                if (errno != 0)
2616                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
2617            }
2618
2619            thread_actions.Append (thread_action);
2620        }
2621
2622        // If a default action for all other threads wasn't mentioned
2623        // then we should stop the threads
2624        thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
2625        DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
2626        return rnb_success;
2627    }
2628    else if (strstr (p, "vAttach") == p)
2629    {
2630        nub_process_t attach_pid = INVALID_NUB_PROCESS;
2631        char err_str[1024]={'\0'};
2632        if (strstr (p, "vAttachWait;") == p)
2633        {
2634            p += strlen("vAttachWait;");
2635            std::string attach_name;
2636            while (*p != '\0')
2637            {
2638                char smallbuf[3];
2639                smallbuf[0] = *p;
2640                smallbuf[1] = *(p + 1);
2641                smallbuf[2] = '\0';
2642
2643                errno = 0;
2644                int ch = strtoul (smallbuf, NULL, 16);
2645                if (errno != 0 && ch == 0)
2646                {
2647                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2648                }
2649
2650                attach_name.push_back(ch);
2651                p += 2;
2652            }
2653
2654            attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2655
2656        }
2657        else if (strstr (p, "vAttachName;") == p)
2658        {
2659            p += strlen("vAttachName;");
2660            std::string attach_name;
2661            while (*p != '\0')
2662            {
2663                char smallbuf[3];
2664                smallbuf[0] = *p;
2665                smallbuf[1] = *(p + 1);
2666                smallbuf[2] = '\0';
2667
2668                errno = 0;
2669                int ch = strtoul (smallbuf, NULL, 16);
2670                if (errno != 0 && ch == 0)
2671                {
2672                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2673                }
2674
2675                attach_name.push_back(ch);
2676                p += 2;
2677            }
2678
2679            attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
2680
2681        }
2682        else if (strstr (p, "vAttach;") == p)
2683        {
2684            p += strlen("vAttach;");
2685            char *end = NULL;
2686            attach_pid = strtoul (p, &end, 16);    // PID will be in hex, so use base 16 to decode
2687            if (p != end && *end == '\0')
2688            {
2689                // Wait at most 30 second for attach
2690                struct timespec attach_timeout_abstime;
2691                DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
2692                attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
2693            }
2694        }
2695        else
2696            return HandlePacket_UNIMPLEMENTED(p);
2697
2698
2699        if (attach_pid != INVALID_NUB_PROCESS)
2700        {
2701            if (m_ctx.ProcessID() != attach_pid)
2702                m_ctx.SetProcessID(attach_pid);
2703            // Send a stop reply packet to indicate we successfully attached!
2704            NotifyThatProcessStopped ();
2705            return rnb_success;
2706        }
2707        else
2708        {
2709            m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
2710            if (err_str[0])
2711                m_ctx.LaunchStatus().SetErrorString(err_str);
2712            else
2713                m_ctx.LaunchStatus().SetErrorString("attach failed");
2714            return SendPacket ("E01");  // E01 is our magic error value for attach failed.
2715        }
2716    }
2717
2718    // All other failures come through here
2719    return HandlePacket_UNIMPLEMENTED(p);
2720}
2721
2722/* `T XX' -- status of thread
2723 Check if the specified thread is alive.
2724 The thread number is in hex?  */
2725
2726rnb_err_t
2727RNBRemote::HandlePacket_T (const char *p)
2728{
2729    p++;
2730    if (p == NULL || *p == '\0')
2731    {
2732        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
2733    }
2734    if (!m_ctx.HasValidProcessID())
2735    {
2736        return SendPacket ("E15");
2737    }
2738    errno = 0;
2739    nub_thread_t tid = strtoul (p, NULL, 16);
2740    if (errno != 0 && tid == 0)
2741    {
2742        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
2743    }
2744
2745    nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
2746    if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
2747    {
2748        return SendPacket ("E16");
2749    }
2750
2751    return SendPacket ("OK");
2752}
2753
2754
2755rnb_err_t
2756RNBRemote::HandlePacket_z (const char *p)
2757{
2758    if (p == NULL || *p == '\0')
2759        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
2760
2761    if (!m_ctx.HasValidProcessID())
2762        return SendPacket ("E15");
2763
2764    char packet_cmd = *p++;
2765    char break_type = *p++;
2766
2767    if (*p++ != ',')
2768        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
2769
2770    char *c = NULL;
2771    nub_process_t pid = m_ctx.ProcessID();
2772    errno = 0;
2773    nub_addr_t addr = strtoull (p, &c, 16);
2774    if (errno != 0 && addr == 0)
2775        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
2776    p = c;
2777    if (*p++ != ',')
2778        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
2779
2780    errno = 0;
2781    uint32_t byte_size = strtoul (p, &c, 16);
2782    if (errno != 0 && byte_size == 0)
2783        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
2784
2785    if (packet_cmd == 'Z')
2786    {
2787        // set
2788        switch (break_type)
2789        {
2790            case '0':   // set software breakpoint
2791            case '1':   // set hardware breakpoint
2792            {
2793                // gdb can send multiple Z packets for the same address and
2794                // these calls must be ref counted.
2795                bool hardware = (break_type == '1');
2796
2797                // Check if we currently have a breakpoint already set at this address
2798                BreakpointMapIter pos = m_breakpoints.find(addr);
2799                if (pos != m_breakpoints.end())
2800                {
2801                    // We do already have a breakpoint at this address, increment
2802                    // its reference count and return OK
2803                    pos->second.Retain();
2804                    return SendPacket ("OK");
2805                }
2806                else
2807                {
2808                    // We do NOT already have a breakpoint at this address, So lets
2809                    // create one.
2810                    nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware);
2811                    if (break_id != INVALID_NUB_BREAK_ID)
2812                    {
2813                        // We successfully created a breakpoint, now lets full out
2814                        // a ref count structure with the breakID and add it to our
2815                        // map.
2816                        Breakpoint rnbBreakpoint(break_id);
2817                        m_breakpoints[addr] = rnbBreakpoint;
2818                        return SendPacket ("OK");
2819                    }
2820                    else
2821                    {
2822                        // We failed to set the software breakpoint
2823                        return SendPacket ("E09");
2824                    }
2825                }
2826            }
2827                break;
2828
2829            case '2':   // set write watchpoint
2830            case '3':   // set read watchpoint
2831            case '4':   // set access watchpoint
2832            {
2833                bool hardware = true;
2834                uint32_t watch_flags = 0;
2835                if (break_type == '2')
2836                    watch_flags = WATCH_TYPE_WRITE;
2837                else if (break_type == '3')
2838                    watch_flags = WATCH_TYPE_READ;
2839                else
2840                    watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
2841
2842                // Check if we currently have a watchpoint already set at this address
2843                BreakpointMapIter pos = m_watchpoints.find(addr);
2844                if (pos != m_watchpoints.end())
2845                {
2846                    // We do already have a watchpoint at this address, increment
2847                    // its reference count and return OK
2848                    pos->second.Retain();
2849                    return SendPacket ("OK");
2850                }
2851                else
2852                {
2853                    // We do NOT already have a breakpoint at this address, So lets
2854                    // create one.
2855                    nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware);
2856                    if (watch_id != INVALID_NUB_BREAK_ID)
2857                    {
2858                        // We successfully created a watchpoint, now lets full out
2859                        // a ref count structure with the watch_id and add it to our
2860                        // map.
2861                        Breakpoint rnbWatchpoint(watch_id);
2862                        m_watchpoints[addr] = rnbWatchpoint;
2863                        return SendPacket ("OK");
2864                    }
2865                    else
2866                    {
2867                        // We failed to set the watchpoint
2868                        return SendPacket ("E09");
2869                    }
2870                }
2871            }
2872                break;
2873
2874            default:
2875                break;
2876        }
2877    }
2878    else if (packet_cmd == 'z')
2879    {
2880        // remove
2881        switch (break_type)
2882        {
2883            case '0':   // remove software breakpoint
2884            case '1':   // remove hardware breakpoint
2885            {
2886                // gdb can send multiple z packets for the same address and
2887                // these calls must be ref counted.
2888                BreakpointMapIter pos = m_breakpoints.find(addr);
2889                if (pos != m_breakpoints.end())
2890                {
2891                    // We currently have a breakpoint at address ADDR. Decrement
2892                    // its reference count, and it that count is now zero we
2893                    // can clear the breakpoint.
2894                    pos->second.Release();
2895                    if (pos->second.RefCount() == 0)
2896                    {
2897                        if (DNBBreakpointClear (pid, pos->second.BreakID()))
2898                        {
2899                            m_breakpoints.erase(pos);
2900                            return SendPacket ("OK");
2901                        }
2902                        else
2903                        {
2904                            return SendPacket ("E08");
2905                        }
2906                    }
2907                    else
2908                    {
2909                        // We still have references to this breakpoint don't
2910                        // delete it, just decrementing the reference count
2911                        // is enough.
2912                        return SendPacket ("OK");
2913                    }
2914                }
2915                else
2916                {
2917                    // We don't know about any breakpoints at this address
2918                    return SendPacket ("E08");
2919                }
2920            }
2921                break;
2922
2923            case '2':   // remove write watchpoint
2924            case '3':   // remove read watchpoint
2925            case '4':   // remove access watchpoint
2926            {
2927                // gdb can send multiple z packets for the same address and
2928                // these calls must be ref counted.
2929                BreakpointMapIter pos = m_watchpoints.find(addr);
2930                if (pos != m_watchpoints.end())
2931                {
2932                    // We currently have a watchpoint at address ADDR. Decrement
2933                    // its reference count, and it that count is now zero we
2934                    // can clear the watchpoint.
2935                    pos->second.Release();
2936                    if (pos->second.RefCount() == 0)
2937                    {
2938                        if (DNBWatchpointClear (pid, pos->second.BreakID()))
2939                        {
2940                            m_watchpoints.erase(pos);
2941                            return SendPacket ("OK");
2942                        }
2943                        else
2944                        {
2945                            return SendPacket ("E08");
2946                        }
2947                    }
2948                    else
2949                    {
2950                        // We still have references to this watchpoint don't
2951                        // delete it, just decrementing the reference count
2952                        // is enough.
2953                        return SendPacket ("OK");
2954                    }
2955                }
2956                else
2957                {
2958                    // We don't know about any watchpoints at this address
2959                    return SendPacket ("E08");
2960                }
2961            }
2962                break;
2963
2964            default:
2965                break;
2966        }
2967    }
2968    return HandlePacket_UNIMPLEMENTED(p);
2969}
2970
2971// Extract the thread number from the thread suffix that might be appended to
2972// thread specific packets. This will only be enabled if m_thread_suffix_supported
2973// is true.
2974nub_thread_t
2975RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
2976{
2977    if (m_thread_suffix_supported)
2978    {
2979        nub_thread_t tid = INVALID_NUB_THREAD;
2980        if (p)
2981        {
2982            const char *tid_cstr = strstr (p, "thread:");
2983            if (tid_cstr)
2984            {
2985                tid_cstr += strlen ("thread:");
2986                tid = strtoul(tid_cstr, NULL, 16);
2987            }
2988        }
2989        return tid;
2990    }
2991    return GetCurrentThread();
2992
2993}
2994
2995/* `p XX'
2996 print the contents of register X */
2997
2998rnb_err_t
2999RNBRemote::HandlePacket_p (const char *p)
3000{
3001    if (g_num_reg_entries == 0)
3002        InitializeRegisters ();
3003
3004    if (p == NULL || *p == '\0')
3005    {
3006        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3007    }
3008    if (!m_ctx.HasValidProcessID())
3009    {
3010        return SendPacket ("E15");
3011    }
3012    nub_process_t pid = m_ctx.ProcessID();
3013    errno = 0;
3014    char *tid_cstr = NULL;
3015    uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
3016    if (errno != 0 && reg == 0)
3017    {
3018        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
3019    }
3020
3021    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
3022    if (tid == INVALID_NUB_THREAD)
3023        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3024
3025    const register_map_entry_t *reg_entry;
3026
3027    if (reg < g_num_reg_entries)
3028        reg_entry = &g_reg_entries[reg];
3029    else
3030        reg_entry = NULL;
3031
3032    std::ostringstream ostrm;
3033    if (reg_entry == NULL)
3034    {
3035        DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
3036        ostrm << "00000000";
3037    }
3038    else if (reg_entry->nub_info.reg == -1)
3039    {
3040        if (reg_entry->gdb_size > 0)
3041        {
3042            if (reg_entry->fail_value != NULL)
3043            {
3044                append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false);
3045            }
3046            else
3047            {
3048                std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0');
3049                append_hex_value(ostrm, zeros.data(), zeros.size(), false);
3050            }
3051        }
3052    }
3053    else
3054    {
3055        register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry);
3056    }
3057    return SendPacket (ostrm.str());
3058}
3059
3060/* `Pnn=rrrrr'
3061 Set register number n to value r.
3062 n and r are hex strings.  */
3063
3064rnb_err_t
3065RNBRemote::HandlePacket_P (const char *p)
3066{
3067    if (g_num_reg_entries == 0)
3068        InitializeRegisters ();
3069
3070    if (p == NULL || *p == '\0')
3071    {
3072        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
3073    }
3074    if (!m_ctx.HasValidProcessID())
3075    {
3076        return SendPacket ("E28");
3077    }
3078
3079    nub_process_t pid = m_ctx.ProcessID();
3080
3081    StringExtractor packet (p);
3082
3083    const char cmd_char = packet.GetChar();
3084    // Register ID is always in big endian
3085    const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
3086    const char equal_char = packet.GetChar();
3087
3088    if (cmd_char != 'P')
3089        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
3090
3091    if (reg == UINT32_MAX)
3092        return SendPacket ("E29");
3093
3094    if (equal_char != '=')
3095        return SendPacket ("E30");
3096
3097    const register_map_entry_t *reg_entry;
3098
3099    if (reg >= g_num_reg_entries)
3100        return SendPacket("E47");
3101
3102    reg_entry = &g_reg_entries[reg];
3103
3104    if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3105    {
3106        DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3107        return SendPacket("E48");
3108    }
3109
3110    DNBRegisterValue reg_value;
3111    reg_value.info = reg_entry->nub_info;
3112    packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
3113
3114    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3115    if (tid == INVALID_NUB_THREAD)
3116        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3117
3118    if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3119    {
3120        return SendPacket ("E32");
3121    }
3122    return SendPacket ("OK");
3123}
3124
3125/* `c [addr]'
3126 Continue, optionally from a specified address. */
3127
3128rnb_err_t
3129RNBRemote::HandlePacket_c (const char *p)
3130{
3131    const nub_process_t pid = m_ctx.ProcessID();
3132
3133    if (pid == INVALID_NUB_PROCESS)
3134        return SendPacket ("E23");
3135
3136    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3137
3138    if (*(p + 1) != '\0')
3139    {
3140        action.tid = GetContinueThread();
3141        errno = 0;
3142        action.addr = strtoull (p + 1, NULL, 16);
3143        if (errno != 0 && action.addr == 0)
3144            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
3145    }
3146
3147    DNBThreadResumeActions thread_actions;
3148    thread_actions.Append(action);
3149    thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3150    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3151        return SendPacket ("E25");
3152    // Don't send an "OK" packet; response is the stopped/exited message.
3153    return rnb_success;
3154}
3155
3156/* `C sig [;addr]'
3157 Resume with signal sig, optionally at address addr.  */
3158
3159rnb_err_t
3160RNBRemote::HandlePacket_C (const char *p)
3161{
3162    const nub_process_t pid = m_ctx.ProcessID();
3163
3164    if (pid == INVALID_NUB_PROCESS)
3165        return SendPacket ("E36");
3166
3167    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3168    int process_signo = -1;
3169    if (*(p + 1) != '\0')
3170    {
3171        action.tid = GetContinueThread();
3172        char *end = NULL;
3173        errno = 0;
3174        process_signo = strtoul (p + 1, &end, 16);
3175        if (errno != 0)
3176            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
3177        else if (*end == ';')
3178        {
3179            errno = 0;
3180            action.addr = strtoull (end + 1, NULL, 16);
3181            if (errno != 0 && action.addr == 0)
3182                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
3183        }
3184    }
3185
3186    DNBThreadResumeActions thread_actions;
3187    thread_actions.Append (action);
3188    thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
3189    if (!DNBProcessSignal(pid, process_signo))
3190        return SendPacket ("E52");
3191    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3192        return SendPacket ("E38");
3193    /* Don't send an "OK" packet; response is the stopped/exited message.  */
3194    return rnb_success;
3195}
3196
3197//----------------------------------------------------------------------
3198// 'D' packet
3199// Detach from gdb.
3200//----------------------------------------------------------------------
3201rnb_err_t
3202RNBRemote::HandlePacket_D (const char *p)
3203{
3204    // We are not supposed to send a response for deatch.
3205    //SendPacket ("OK");
3206    if (m_ctx.HasValidProcessID())
3207        DNBProcessDetach(m_ctx.ProcessID());
3208    return rnb_success;
3209}
3210
3211/* `k'
3212 Kill the inferior process.  */
3213
3214rnb_err_t
3215RNBRemote::HandlePacket_k (const char *p)
3216{
3217    // No response to should be sent to the kill packet
3218    if (m_ctx.HasValidProcessID())
3219        DNBProcessKill (m_ctx.ProcessID());
3220    SendPacket ("W09");
3221    return rnb_success;
3222}
3223
3224rnb_err_t
3225RNBRemote::HandlePacket_stop_process (const char *p)
3226{
3227    DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
3228    //DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
3229    // Do not send any response packet! Wait for the stop reply packet to naturally happen
3230    return rnb_success;
3231}
3232
3233/* `s'
3234 Step the inferior process.  */
3235
3236rnb_err_t
3237RNBRemote::HandlePacket_s (const char *p)
3238{
3239    const nub_process_t pid = m_ctx.ProcessID();
3240    if (pid == INVALID_NUB_PROCESS)
3241        return SendPacket ("E32");
3242
3243    // Hardware supported stepping not supported on arm
3244    nub_thread_t tid = GetContinueThread ();
3245    if (tid == 0 || tid == -1)
3246        tid = GetCurrentThread();
3247
3248    if (tid == INVALID_NUB_THREAD)
3249        return SendPacket ("E33");
3250
3251    DNBThreadResumeActions thread_actions;
3252    thread_actions.AppendAction(tid, eStateStepping);
3253
3254    // Make all other threads stop when we are stepping
3255    thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3256    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3257        return SendPacket ("E49");
3258    // Don't send an "OK" packet; response is the stopped/exited message.
3259    return rnb_success;
3260}
3261
3262/* `S sig [;addr]'
3263 Step with signal sig, optionally at address addr.  */
3264
3265rnb_err_t
3266RNBRemote::HandlePacket_S (const char *p)
3267{
3268    const nub_process_t pid = m_ctx.ProcessID();
3269    if (pid == INVALID_NUB_PROCESS)
3270        return SendPacket ("E36");
3271
3272    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
3273
3274    if (*(p + 1) != '\0')
3275    {
3276        char *end = NULL;
3277        errno = 0;
3278        action.signal = strtoul (p + 1, &end, 16);
3279        if (errno != 0)
3280            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
3281        else if (*end == ';')
3282        {
3283            errno = 0;
3284            action.addr = strtoull (end + 1, NULL, 16);
3285            if (errno != 0 && action.addr == 0)
3286            {
3287                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
3288            }
3289        }
3290    }
3291
3292    action.tid = GetContinueThread ();
3293    if (action.tid == 0 || action.tid == -1)
3294        return SendPacket ("E40");
3295
3296    nub_state_t tstate = DNBThreadGetState (pid, action.tid);
3297    if (tstate == eStateInvalid || tstate == eStateExited)
3298        return SendPacket ("E37");
3299
3300
3301    DNBThreadResumeActions thread_actions;
3302    thread_actions.Append (action);
3303
3304    // Make all other threads stop when we are stepping
3305    thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
3306    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3307        return SendPacket ("E39");
3308
3309    // Don't send an "OK" packet; response is the stopped/exited message.
3310    return rnb_success;
3311}
3312
3313rnb_err_t
3314RNBRemote::HandlePacket_qHostInfo (const char *p)
3315{
3316    std::ostringstream strm;
3317
3318    uint32_t cputype, is_64_bit_capable;
3319    size_t len = sizeof(cputype);
3320    bool promoted_to_64 = false;
3321    if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
3322    {
3323        len = sizeof (is_64_bit_capable);
3324        if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
3325        {
3326            if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
3327            {
3328                promoted_to_64 = true;
3329                cputype |= CPU_ARCH_ABI64;
3330            }
3331        }
3332
3333        strm << "cputype:" << std::dec << cputype << ';';
3334    }
3335
3336    uint32_t cpusubtype;
3337    len = sizeof(cpusubtype);
3338    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
3339    {
3340        if (promoted_to_64 &&
3341            cputype == CPU_TYPE_X86_64 &&
3342            cpusubtype == CPU_SUBTYPE_486)
3343            cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3344
3345        strm << "cpusubtype:" << std::dec << cpusubtype << ';';
3346    }
3347
3348    char ostype[64];
3349    len = sizeof(ostype);
3350    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
3351    {
3352        len = strlen(ostype);
3353        std::transform (ostype, ostype + len, ostype, tolower);
3354        strm << "ostype:" << std::dec << ostype << ';';
3355    }
3356
3357    strm << "vendor:apple;";
3358
3359#if defined (__LITTLE_ENDIAN__)
3360    strm << "endian:little;";
3361#elif defined (__BIG_ENDIAN__)
3362    strm << "endian:big;";
3363#elif defined (__PDP_ENDIAN__)
3364    strm << "endian:pdp;";
3365#endif
3366
3367    if (promoted_to_64)
3368        strm << "ptrsize:8;";
3369    else
3370        strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
3371    return SendPacket (strm.str());
3372}
3373