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