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