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