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