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