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