RNBRemote.cpp revision 8ec8d64110a5879e4e544dc09e9849498fecb044
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_SetAsyncEnableProfiling, NULL, "QSetAsyncEnableProfiling", "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        return SendPacket (ostrm.str ());
1557    }
1558    return SendPacket ("E45");
1559}
1560
1561
1562/* This expects a packet formatted like
1563
1564 QSetLogging:bitmask=LOG_ALL|LOG_RNB_REMOTE;
1565
1566 with the "QSetLogging:" already removed from the start.  Maybe in the
1567 future this packet will include other keyvalue pairs like
1568
1569 QSetLogging:bitmask=LOG_ALL;mode=asl;
1570 */
1571
1572rnb_err_t
1573set_logging (const char *p)
1574{
1575    int bitmask = 0;
1576    while (p && *p != '\0')
1577    {
1578        if (strncmp (p, "bitmask=", sizeof ("bitmask=") - 1) == 0)
1579        {
1580            p += sizeof ("bitmask=") - 1;
1581            while (p && *p != '\0' && *p != ';')
1582            {
1583                if (*p == '|')
1584                    p++;
1585                if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
1586                {
1587                    p += sizeof ("LOG_VERBOSE") - 1;
1588                    bitmask |= LOG_VERBOSE;
1589                }
1590                else if (strncmp (p, "LOG_PROCESS", sizeof ("LOG_PROCESS") - 1) == 0)
1591                {
1592                    p += sizeof ("LOG_PROCESS") - 1;
1593                    bitmask |= LOG_PROCESS;
1594                }
1595                else if (strncmp (p, "LOG_THREAD", sizeof ("LOG_THREAD") - 1) == 0)
1596                {
1597                    p += sizeof ("LOG_THREAD") - 1;
1598                    bitmask |= LOG_THREAD;
1599                }
1600                else if (strncmp (p, "LOG_EXCEPTIONS", sizeof ("LOG_EXCEPTIONS") - 1) == 0)
1601                {
1602                    p += sizeof ("LOG_EXCEPTIONS") - 1;
1603                    bitmask |= LOG_EXCEPTIONS;
1604                }
1605                else if (strncmp (p, "LOG_SHLIB", sizeof ("LOG_SHLIB") - 1) == 0)
1606                {
1607                    p += sizeof ("LOG_SHLIB") - 1;
1608                    bitmask |= LOG_SHLIB;
1609                }
1610                else if (strncmp (p, "LOG_MEMORY", sizeof ("LOG_MEMORY") - 1) == 0)
1611                {
1612                    p += sizeof ("LOG_MEMORY") - 1;
1613                    bitmask |= LOG_MEMORY;
1614                }
1615                else if (strncmp (p, "LOG_MEMORY_DATA_SHORT", sizeof ("LOG_MEMORY_DATA_SHORT") - 1) == 0)
1616                {
1617                    p += sizeof ("LOG_MEMORY_DATA_SHORT") - 1;
1618                    bitmask |= LOG_MEMORY_DATA_SHORT;
1619                }
1620                else if (strncmp (p, "LOG_MEMORY_DATA_LONG", sizeof ("LOG_MEMORY_DATA_LONG") - 1) == 0)
1621                {
1622                    p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
1623                    bitmask |= LOG_MEMORY_DATA_LONG;
1624                }
1625                else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
1626                {
1627                    p += sizeof ("LOG_BREAKPOINTS") - 1;
1628                    bitmask |= LOG_BREAKPOINTS;
1629                }
1630                else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
1631                {
1632                    p += sizeof ("LOG_ALL") - 1;
1633                    bitmask |= LOG_ALL;
1634                }
1635                else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
1636                {
1637                    p += sizeof ("LOG_EVENTS") - 1;
1638                    bitmask |= LOG_EVENTS;
1639                }
1640                else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
1641                {
1642                    p += sizeof ("LOG_DEFAULT") - 1;
1643                    bitmask |= LOG_DEFAULT;
1644                }
1645                else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
1646                {
1647                    p += sizeof ("LOG_NONE") - 1;
1648                    bitmask = 0;
1649                }
1650                else if (strncmp (p, "LOG_RNB_MINIMAL", sizeof ("LOG_RNB_MINIMAL") - 1) == 0)
1651                {
1652                    p += sizeof ("LOG_RNB_MINIMAL") - 1;
1653                    bitmask |= LOG_RNB_MINIMAL;
1654                }
1655                else if (strncmp (p, "LOG_RNB_MEDIUM", sizeof ("LOG_RNB_MEDIUM") - 1) == 0)
1656                {
1657                    p += sizeof ("LOG_RNB_MEDIUM") - 1;
1658                    bitmask |= LOG_RNB_MEDIUM;
1659                }
1660                else if (strncmp (p, "LOG_RNB_MAX", sizeof ("LOG_RNB_MAX") - 1) == 0)
1661                {
1662                    p += sizeof ("LOG_RNB_MAX") - 1;
1663                    bitmask |= LOG_RNB_MAX;
1664                }
1665                else if (strncmp (p, "LOG_RNB_COMM", sizeof ("LOG_RNB_COMM") - 1) == 0)
1666                {
1667                    p += sizeof ("LOG_RNB_COMM") - 1;
1668                    bitmask |= LOG_RNB_COMM;
1669                }
1670                else if (strncmp (p, "LOG_RNB_REMOTE", sizeof ("LOG_RNB_REMOTE") - 1) == 0)
1671                {
1672                    p += sizeof ("LOG_RNB_REMOTE") - 1;
1673                    bitmask |= LOG_RNB_REMOTE;
1674                }
1675                else if (strncmp (p, "LOG_RNB_EVENTS", sizeof ("LOG_RNB_EVENTS") - 1) == 0)
1676                {
1677                    p += sizeof ("LOG_RNB_EVENTS") - 1;
1678                    bitmask |= LOG_RNB_EVENTS;
1679                }
1680                else if (strncmp (p, "LOG_RNB_PROC", sizeof ("LOG_RNB_PROC") - 1) == 0)
1681                {
1682                    p += sizeof ("LOG_RNB_PROC") - 1;
1683                    bitmask |= LOG_RNB_PROC;
1684                }
1685                else if (strncmp (p, "LOG_RNB_PACKETS", sizeof ("LOG_RNB_PACKETS") - 1) == 0)
1686                {
1687                    p += sizeof ("LOG_RNB_PACKETS") - 1;
1688                    bitmask |= LOG_RNB_PACKETS;
1689                }
1690                else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0)
1691                {
1692                    p += sizeof ("LOG_WATCHPOINTS") - 1;
1693                    bitmask |= LOG_WATCHPOINTS;
1694                }
1695                else if (strncmp (p, "LOG_RNB_ALL", sizeof ("LOG_RNB_ALL") - 1) == 0)
1696                {
1697                    p += sizeof ("LOG_RNB_ALL") - 1;
1698                    bitmask |= LOG_RNB_ALL;
1699                }
1700                else if (strncmp (p, "LOG_RNB_DEFAULT", sizeof ("LOG_RNB_DEFAULT") - 1) == 0)
1701                {
1702                    p += sizeof ("LOG_RNB_DEFAULT") - 1;
1703                    bitmask |= LOG_RNB_DEFAULT;
1704                }
1705                else if (strncmp (p, "LOG_RNB_NONE", sizeof ("LOG_RNB_NONE") - 1) == 0)
1706                {
1707                    p += sizeof ("LOG_RNB_NONE") - 1;
1708                    bitmask = 0;
1709                }
1710                else
1711                {
1712                    /* Unrecognized logging bit; ignore it.  */
1713                    const char *c = strchr (p, '|');
1714                    if (c)
1715                    {
1716                        p = c;
1717                    }
1718                    else
1719                    {
1720                        c = strchr (p, ';');
1721                        if (c)
1722                        {
1723                            p = c;
1724                        }
1725                        else
1726                        {
1727                            // Improperly terminated word; just go to end of str
1728                            p = strchr (p, '\0');
1729                        }
1730                    }
1731                }
1732            }
1733            // Did we get a properly formatted logging bitmask?
1734            if (p && *p == ';')
1735            {
1736                // Enable DNB logging
1737                DNBLogSetLogCallback(ASLLogCallback, NULL);
1738                DNBLogSetLogMask (bitmask);
1739                p++;
1740            }
1741        }
1742        // We're not going to support logging to a file for now.  All logging
1743        // goes through ASL.
1744#if 0
1745        else if (strncmp (p, "mode=", sizeof ("mode=") - 1) == 0)
1746        {
1747            p += sizeof ("mode=") - 1;
1748            if (strncmp (p, "asl;", sizeof ("asl;") - 1) == 0)
1749            {
1750                DNBLogToASL ();
1751                p += sizeof ("asl;") - 1;
1752            }
1753            else if (strncmp (p, "file;", sizeof ("file;") - 1) == 0)
1754            {
1755                DNBLogToFile ();
1756                p += sizeof ("file;") - 1;
1757            }
1758            else
1759            {
1760                // Ignore unknown argument
1761                const char *c = strchr (p, ';');
1762                if (c)
1763                    p = c + 1;
1764                else
1765                    p = strchr (p, '\0');
1766            }
1767        }
1768        else if (strncmp (p, "filename=", sizeof ("filename=") - 1) == 0)
1769        {
1770            p += sizeof ("filename=") - 1;
1771            const char *c = strchr (p, ';');
1772            if (c == NULL)
1773            {
1774                c = strchr (p, '\0');
1775                continue;
1776            }
1777            char *fn = (char *) alloca (c - p + 1);
1778            strncpy (fn, p, c - p);
1779            fn[c - p] = '\0';
1780
1781            // A file name of "asl" is special and is another way to indicate
1782            // that logging should be done via ASL, not by file.
1783            if (strcmp (fn, "asl") == 0)
1784            {
1785                DNBLogToASL ();
1786            }
1787            else
1788            {
1789                FILE *f = fopen (fn, "w");
1790                if (f)
1791                {
1792                    DNBLogSetLogFile (f);
1793                    DNBEnableLogging (f, DNBLogGetLogMask ());
1794                    DNBLogToFile ();
1795                }
1796            }
1797            p = c + 1;
1798        }
1799#endif /* #if 0 to enforce ASL logging only.  */
1800        else
1801        {
1802            // Ignore unknown argument
1803            const char *c = strchr (p, ';');
1804            if (c)
1805                p = c + 1;
1806            else
1807                p = strchr (p, '\0');
1808        }
1809    }
1810
1811    return rnb_success;
1812}
1813
1814rnb_err_t
1815RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
1816{
1817    m_thread_suffix_supported = true;
1818    return SendPacket ("OK");
1819}
1820
1821rnb_err_t
1822RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
1823{
1824    // Send the OK packet first so the correct checksum is appended...
1825    rnb_err_t result = SendPacket ("OK");
1826    m_noack_mode = true;
1827    return result;
1828}
1829
1830
1831rnb_err_t
1832RNBRemote::HandlePacket_QSetLogging (const char *p)
1833{
1834    p += sizeof ("QSetLogging:") - 1;
1835    rnb_err_t result = set_logging (p);
1836    if (result == rnb_success)
1837        return SendPacket ("OK");
1838    else
1839        return SendPacket ("E35");
1840}
1841
1842rnb_err_t
1843RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
1844{
1845    extern int g_disable_aslr;
1846    p += sizeof ("QSetDisableASLR:") - 1;
1847    switch (*p)
1848    {
1849    case '0': g_disable_aslr = 0; break;
1850    case '1': g_disable_aslr = 1; break;
1851    default:
1852        return SendPacket ("E56");
1853    }
1854    return SendPacket ("OK");
1855}
1856
1857rnb_err_t
1858RNBRemote::HandlePacket_QSetSTDIO (const char *p)
1859{
1860    // Only set stdin/out/err if we don't already have a process
1861    if (!m_ctx.HasValidProcessID())
1862    {
1863        bool success = false;
1864        // Check the seventh character since the packet will be one of:
1865        // QSetSTDIN
1866        // QSetSTDOUT
1867        // QSetSTDERR
1868        StringExtractor packet(p);
1869        packet.SetFilePos (7);
1870        char ch = packet.GetChar();
1871        while (packet.GetChar() != ':')
1872            /* Do nothing. */;
1873
1874        switch (ch)
1875        {
1876            case 'I': // STDIN
1877                packet.GetHexByteString (m_ctx.GetSTDIN());
1878                success = !m_ctx.GetSTDIN().empty();
1879                break;
1880
1881            case 'O': // STDOUT
1882                packet.GetHexByteString (m_ctx.GetSTDOUT());
1883                success = !m_ctx.GetSTDOUT().empty();
1884                break;
1885
1886            case 'E': // STDERR
1887                packet.GetHexByteString (m_ctx.GetSTDERR());
1888                success = !m_ctx.GetSTDERR().empty();
1889                break;
1890
1891            default:
1892                break;
1893        }
1894        if (success)
1895            return SendPacket ("OK");
1896        return SendPacket ("E57");
1897    }
1898    return SendPacket ("E58");
1899}
1900
1901rnb_err_t
1902RNBRemote::HandlePacket_QSetWorkingDir (const char *p)
1903{
1904    // Only set the working directory if we don't already have a process
1905    if (!m_ctx.HasValidProcessID())
1906    {
1907        StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);
1908        if (packet.GetHexByteString (m_ctx.GetWorkingDir()))
1909        {
1910            struct stat working_dir_stat;
1911            if (::stat(m_ctx.GetWorkingDirPath(), &working_dir_stat) == -1)
1912            {
1913                m_ctx.GetWorkingDir().clear();
1914                return SendPacket ("E61");    // Working directory doesn't exist...
1915            }
1916            else if ((working_dir_stat.st_mode & S_IFMT) == S_IFDIR)
1917            {
1918                return SendPacket ("OK");
1919            }
1920            else
1921            {
1922                m_ctx.GetWorkingDir().clear();
1923                return SendPacket ("E62");    // Working directory isn't a directory...
1924            }
1925        }
1926        return SendPacket ("E59");  // Invalid path
1927    }
1928    return SendPacket ("E60"); // Already had a process, too late to set working dir
1929}
1930
1931rnb_err_t
1932RNBRemote::HandlePacket_QSyncThreadState (const char *p)
1933{
1934    if (!m_ctx.HasValidProcessID())
1935    {
1936        // We allow gdb to connect to a server that hasn't started running
1937        // the target yet.  gdb still wants to ask questions about it and
1938        // freaks out if it gets an error.  So just return OK here.
1939        return SendPacket ("OK");
1940    }
1941
1942    errno = 0;
1943    p += strlen("QSyncThreadState:");
1944    nub_thread_t tid = strtoul (p, NULL, 16);
1945    if (errno != 0 && tid == 0)
1946    {
1947        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid thread number in QSyncThreadState packet");
1948    }
1949    if (DNBProcessSyncThreadState(m_ctx.ProcessID(), tid))
1950        return SendPacket("OK");
1951    else
1952        return SendPacket ("E61");
1953}
1954
1955rnb_err_t
1956RNBRemote::HandlePacket_QListThreadsInStopReply (const char *p)
1957{
1958    // If this packet is received, it allows us to send an extra key/value
1959    // pair in the stop reply packets where we will list all of the thread IDs
1960    // separated by commas:
1961    //
1962    //  "threads:10a,10b,10c;"
1963    //
1964    // This will get included in the stop reply packet as something like:
1965    //
1966    //  "T11thread:10a;00:00000000;01:00010203:threads:10a,10b,10c;"
1967    //
1968    // This can save two packets on each stop: qfThreadInfo/qsThreadInfo and
1969    // speed things up a bit.
1970    //
1971    // Send the OK packet first so the correct checksum is appended...
1972    rnb_err_t result = SendPacket ("OK");
1973    m_list_threads_in_stop_reply = true;
1974    return result;
1975}
1976
1977
1978rnb_err_t
1979RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
1980{
1981    /* The number of characters in a packet payload that gdb is
1982     prepared to accept.  The packet-start char, packet-end char,
1983     2 checksum chars and terminating null character are not included
1984     in this size.  */
1985    p += sizeof ("QSetMaxPayloadSize:") - 1;
1986    errno = 0;
1987    uint32_t size = strtoul (p, NULL, 16);
1988    if (errno != 0 && size == 0)
1989    {
1990        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPayloadSize packet");
1991    }
1992    m_max_payload_size = size;
1993    return SendPacket ("OK");
1994}
1995
1996rnb_err_t
1997RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
1998{
1999    /* This tells us the largest packet that gdb can handle.
2000     i.e. the size of gdb's packet-reading buffer.
2001     QSetMaxPayloadSize is preferred because it is less ambiguous.  */
2002    p += sizeof ("QSetMaxPacketSize:") - 1;
2003    errno = 0;
2004    uint32_t size = strtoul (p, NULL, 16);
2005    if (errno != 0 && size == 0)
2006    {
2007        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in QSetMaxPacketSize packet");
2008    }
2009    m_max_payload_size = size - 5;
2010    return SendPacket ("OK");
2011}
2012
2013
2014
2015
2016rnb_err_t
2017RNBRemote::HandlePacket_QEnvironment (const char *p)
2018{
2019    /* This sets the environment for the target program.  The packet is of the form:
2020
2021     QEnvironment:VARIABLE=VALUE
2022
2023     */
2024
2025    DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
2026                      (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2027
2028    p += sizeof ("QEnvironment:") - 1;
2029    RNBContext& ctx = Context();
2030
2031    ctx.PushEnvironment (p);
2032    return SendPacket ("OK");
2033}
2034
2035rnb_err_t
2036RNBRemote::HandlePacket_QEnvironmentHexEncoded (const char *p)
2037{
2038    /* This sets the environment for the target program.  The packet is of the form:
2039
2040        QEnvironmentHexEncoded:VARIABLE=VALUE
2041
2042        The VARIABLE=VALUE part is sent hex-encoded so chracters like '#' with special
2043        meaning in the remote protocol won't break it.
2044    */
2045
2046    DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironmentHexEncoded: \"%s\"",
2047        (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
2048
2049    p += sizeof ("QEnvironmentHexEncoded:") - 1;
2050
2051    std::string arg;
2052    const char *c;
2053    c = p;
2054    while (*c != '\0')
2055      {
2056        if (*(c + 1) == '\0')
2057        {
2058            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2059        }
2060        char smallbuf[3];
2061        smallbuf[0] = *c;
2062        smallbuf[1] = *(c + 1);
2063        smallbuf[2] = '\0';
2064        errno = 0;
2065        int ch = strtoul (smallbuf, NULL, 16);
2066        if (errno != 0 && ch == 0)
2067          {
2068            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'QEnvironmentHexEncoded' pkt");
2069          }
2070        arg.push_back(ch);
2071        c += 2;
2072      }
2073
2074    RNBContext& ctx = Context();
2075    if (arg.length() > 0)
2076      ctx.PushEnvironment (arg.c_str());
2077
2078    return SendPacket ("OK");
2079}
2080
2081
2082rnb_err_t
2083RNBRemote::HandlePacket_QLaunchArch (const char *p)
2084{
2085    p += sizeof ("QLaunchArch:") - 1;
2086    if (DNBSetArchitecture(p))
2087        return SendPacket ("OK");
2088    return SendPacket ("E63");
2089}
2090
2091void
2092append_hex_value (std::ostream& ostrm, const uint8_t* buf, size_t buf_size, bool swap)
2093{
2094    int i;
2095    if (swap)
2096    {
2097        for (i = buf_size-1; i >= 0; i--)
2098            ostrm << RAWHEX8(buf[i]);
2099    }
2100    else
2101    {
2102        for (i = 0; i < buf_size; i++)
2103            ostrm << RAWHEX8(buf[i]);
2104    }
2105}
2106
2107
2108void
2109register_value_in_hex_fixed_width (std::ostream& ostrm,
2110                                   nub_process_t pid,
2111                                   nub_thread_t tid,
2112                                   const register_map_entry_t* reg,
2113                                   const DNBRegisterValue *reg_value_ptr)
2114{
2115    if (reg != NULL)
2116    {
2117        DNBRegisterValue reg_value;
2118        if (reg_value_ptr == NULL)
2119        {
2120            if (DNBThreadGetRegisterValueByID (pid, tid, reg->nub_info.set, reg->nub_info.reg, &reg_value))
2121                reg_value_ptr = &reg_value;
2122        }
2123
2124        if (reg_value_ptr)
2125        {
2126            append_hex_value (ostrm, reg_value_ptr->value.v_uint8, reg->gdb_size, false);
2127        }
2128        else
2129        {
2130            // If we fail to read a regiser value, check if it has a default
2131            // fail value. If it does, return this instead in case some of
2132            // the registers are not available on the current system.
2133            if (reg->gdb_size > 0)
2134            {
2135                if (reg->fail_value != NULL)
2136                {
2137                    append_hex_value (ostrm, reg->fail_value, reg->gdb_size, false);
2138                }
2139                else
2140                {
2141                    std::basic_string<uint8_t> zeros(reg->gdb_size, '\0');
2142                    append_hex_value (ostrm, zeros.data(), zeros.size(), false);
2143                }
2144            }
2145        }
2146    }
2147}
2148
2149
2150void
2151gdb_regnum_with_fixed_width_hex_register_value (std::ostream& ostrm,
2152                                                nub_process_t pid,
2153                                                nub_thread_t tid,
2154                                                const register_map_entry_t* reg,
2155                                                const DNBRegisterValue *reg_value_ptr)
2156{
2157    // Output the register number as 'NN:VVVVVVVV;' where NN is a 2 bytes HEX
2158    // gdb register number, and VVVVVVVV is the correct number of hex bytes
2159    // as ASCII for the register value.
2160    if (reg != NULL)
2161    {
2162        ostrm << RAWHEX8(reg->gdb_regnum) << ':';
2163        register_value_in_hex_fixed_width (ostrm, pid, tid, reg, reg_value_ptr);
2164        ostrm << ';';
2165    }
2166}
2167
2168rnb_err_t
2169RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
2170{
2171    const nub_process_t pid = m_ctx.ProcessID();
2172    if (pid == INVALID_NUB_PROCESS)
2173        return SendPacket("E50");
2174
2175    struct DNBThreadStopInfo tid_stop_info;
2176
2177    /* Fill the remaining space in this packet with as many registers
2178     as we can stuff in there.  */
2179
2180    if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
2181    {
2182        std::ostringstream ostrm;
2183        // Output the T packet with the thread
2184        ostrm << 'T';
2185        int signum = tid_stop_info.details.signal.signo;
2186        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);
2187
2188        // Translate any mach exceptions to gdb versions, unless they are
2189        // common exceptions like a breakpoint or a soft signal.
2190        switch (tid_stop_info.details.exception.type)
2191        {
2192            default:                    signum = 0; break;
2193            case EXC_BREAKPOINT:        signum = SIGTRAP; break;
2194            case EXC_BAD_ACCESS:        signum = TARGET_EXC_BAD_ACCESS; break;
2195            case EXC_BAD_INSTRUCTION:   signum = TARGET_EXC_BAD_INSTRUCTION; break;
2196            case EXC_ARITHMETIC:        signum = TARGET_EXC_ARITHMETIC; break;
2197            case EXC_EMULATION:         signum = TARGET_EXC_EMULATION; break;
2198            case EXC_SOFTWARE:
2199                if (tid_stop_info.details.exception.data_count == 2 &&
2200                    tid_stop_info.details.exception.data[0] == EXC_SOFT_SIGNAL)
2201                    signum = tid_stop_info.details.exception.data[1];
2202                else
2203                    signum = TARGET_EXC_SOFTWARE;
2204                break;
2205        }
2206
2207        ostrm << RAWHEX8(signum & 0xff);
2208
2209        ostrm << std::hex << "thread:" << tid << ';';
2210
2211        const char *thread_name = DNBThreadGetName (pid, tid);
2212        if (thread_name && thread_name[0])
2213        {
2214            size_t thread_name_len = strlen(thread_name);
2215
2216            if (::strcspn (thread_name, "$#+-;:") == thread_name_len)
2217                ostrm << std::hex << "name:" << thread_name << ';';
2218            else
2219            {
2220                // the thread name contains special chars, send as hex bytes
2221                ostrm << std::hex << "hexname:";
2222                uint8_t *u_thread_name = (uint8_t *)thread_name;
2223                for (int i = 0; i < thread_name_len; i++)
2224                    ostrm << RAWHEX8(u_thread_name[i]);
2225                ostrm << ';';
2226            }
2227        }
2228
2229        thread_identifier_info_data_t thread_ident_info;
2230        if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
2231        {
2232            if (thread_ident_info.dispatch_qaddr != 0)
2233                ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
2234        }
2235
2236        // If a 'QListThreadsInStopReply' was sent to enable this feature, we
2237        // will send all thread IDs back in the "threads" key whose value is
2238        // a listc of hex thread IDs separated by commas:
2239        //  "threads:10a,10b,10c;"
2240        // This will save the debugger from having to send a pair of qfThreadInfo
2241        // and qsThreadInfo packets, but it also might take a lot of room in the
2242        // stop reply packet, so it must be enabled only on systems where there
2243        // are no limits on packet lengths.
2244
2245        if (m_list_threads_in_stop_reply)
2246        {
2247            const nub_size_t numthreads = DNBProcessGetNumThreads (pid);
2248            if (numthreads > 0)
2249            {
2250                ostrm << std::hex << "threads:";
2251                for (nub_size_t i = 0; i < numthreads; ++i)
2252                {
2253                    nub_thread_t th = DNBProcessGetThreadAtIndex (pid, i);
2254                    if (i > 0)
2255                        ostrm << ',';
2256                    ostrm << std::hex << th;
2257                }
2258                ostrm << ';';
2259            }
2260        }
2261
2262        if (g_num_reg_entries == 0)
2263            InitializeRegisters ();
2264
2265        if (g_reg_entries != NULL)
2266        {
2267            DNBRegisterValue reg_value;
2268            for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2269            {
2270                if (g_reg_entries[reg].expedite)
2271                {
2272                    if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
2273                        continue;
2274
2275                    gdb_regnum_with_fixed_width_hex_register_value (ostrm, pid, tid, &g_reg_entries[reg], &reg_value);
2276                }
2277            }
2278        }
2279
2280        if (tid_stop_info.details.exception.type)
2281        {
2282            ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";";
2283            ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";";
2284            for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
2285                ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";";
2286        }
2287        return SendPacket (ostrm.str ());
2288    }
2289    return SendPacket("E51");
2290}
2291
2292/* '?'
2293 The stop reply packet - tell gdb what the status of the inferior is.
2294 Often called the questionmark_packet.  */
2295
2296rnb_err_t
2297RNBRemote::HandlePacket_last_signal (const char *unused)
2298{
2299    if (!m_ctx.HasValidProcessID())
2300    {
2301        // Inferior is not yet specified/running
2302        return SendPacket ("E02");
2303    }
2304
2305    nub_process_t pid = m_ctx.ProcessID();
2306    nub_state_t pid_state = DNBProcessGetState (pid);
2307
2308    switch (pid_state)
2309    {
2310        case eStateAttaching:
2311        case eStateLaunching:
2312        case eStateRunning:
2313        case eStateStepping:
2314        case eStateDetached:
2315            return rnb_success;  // Ignore
2316
2317        case eStateSuspended:
2318        case eStateStopped:
2319        case eStateCrashed:
2320            {
2321                nub_thread_t tid = DNBProcessGetCurrentThread (pid);
2322                // Make sure we set the current thread so g and p packets return
2323                // the data the gdb will expect.
2324                SetCurrentThread (tid);
2325
2326                SendStopReplyPacketForThread (tid);
2327            }
2328            break;
2329
2330        case eStateInvalid:
2331        case eStateUnloaded:
2332        case eStateExited:
2333            {
2334                char pid_exited_packet[16] = "";
2335                int pid_status = 0;
2336                // Process exited with exit status
2337                if (!DNBProcessGetExitStatus(pid, &pid_status))
2338                    pid_status = 0;
2339
2340                if (pid_status)
2341                {
2342                    if (WIFEXITED (pid_status))
2343                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
2344                    else if (WIFSIGNALED (pid_status))
2345                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
2346                    else if (WIFSTOPPED (pid_status))
2347                        snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
2348                }
2349
2350                // If we have an empty exit packet, lets fill one in to be safe.
2351                if (!pid_exited_packet[0])
2352                {
2353                    strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
2354                    pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
2355                }
2356
2357                return SendPacket (pid_exited_packet);
2358            }
2359            break;
2360    }
2361    return rnb_success;
2362}
2363
2364rnb_err_t
2365RNBRemote::HandlePacket_M (const char *p)
2366{
2367    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2368    {
2369        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short M packet");
2370    }
2371
2372    char *c;
2373    p++;
2374    errno = 0;
2375    nub_addr_t addr = strtoull (p, &c, 16);
2376    if (errno != 0 && addr == 0)
2377    {
2378        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in M packet");
2379    }
2380    if (*c != ',')
2381    {
2382        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in M packet");
2383    }
2384
2385    /* Advance 'p' to the length part of the packet.  */
2386    p += (c - p) + 1;
2387
2388    errno = 0;
2389    uint32_t length = strtoul (p, &c, 16);
2390    if (errno != 0 && length == 0)
2391    {
2392        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in M packet");
2393    }
2394    if (length == 0)
2395    {
2396        return SendPacket ("OK");
2397    }
2398
2399    if (*c != ':')
2400    {
2401        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Missing colon in M packet");
2402    }
2403    /* Advance 'p' to the data part of the packet.  */
2404    p += (c - p) + 1;
2405
2406    int datalen = strlen (p);
2407    if (datalen & 0x1)
2408    {
2409        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Uneven # of hex chars for data in M packet");
2410    }
2411    if (datalen == 0)
2412    {
2413        return SendPacket ("OK");
2414    }
2415
2416    uint8_t *buf = (uint8_t *) alloca (datalen / 2);
2417    uint8_t *i = buf;
2418
2419    while (*p != '\0' && *(p + 1) != '\0')
2420    {
2421        char hexbuf[3];
2422        hexbuf[0] = *p;
2423        hexbuf[1] = *(p + 1);
2424        hexbuf[2] = '\0';
2425        errno = 0;
2426        uint8_t byte = strtoul (hexbuf, NULL, 16);
2427        if (errno != 0 && byte == 0)
2428        {
2429            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid hex byte in M packet");
2430        }
2431        *i++ = byte;
2432        p += 2;
2433    }
2434
2435    nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, length, buf);
2436    if (wrote != length)
2437        return SendPacket ("E09");
2438    else
2439        return SendPacket ("OK");
2440}
2441
2442
2443rnb_err_t
2444RNBRemote::HandlePacket_m (const char *p)
2445{
2446    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2447    {
2448        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short m packet");
2449    }
2450
2451    char *c;
2452    p++;
2453    errno = 0;
2454    nub_addr_t addr = strtoull (p, &c, 16);
2455    if (errno != 0 && addr == 0)
2456    {
2457        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in m packet");
2458    }
2459    if (*c != ',')
2460    {
2461        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in m packet");
2462    }
2463
2464    /* Advance 'p' to the length part of the packet.  */
2465    p += (c - p) + 1;
2466
2467    errno = 0;
2468    uint32_t length = strtoul (p, NULL, 16);
2469    if (errno != 0 && length == 0)
2470    {
2471        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2472    }
2473    if (length == 0)
2474    {
2475        return SendPacket ("");
2476    }
2477
2478    uint8_t buf[length];
2479    int bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID(), addr, length, buf);
2480    if (bytes_read == 0)
2481    {
2482        return SendPacket ("E08");
2483    }
2484
2485    // "The reply may contain fewer bytes than requested if the server was able
2486    //  to read only part of the region of memory."
2487    length = bytes_read;
2488
2489    std::ostringstream ostrm;
2490    for (int i = 0; i < length; i++)
2491        ostrm << RAWHEX8(buf[i]);
2492    return SendPacket (ostrm.str ());
2493}
2494
2495rnb_err_t
2496RNBRemote::HandlePacket_X (const char *p)
2497{
2498    if (p == NULL || p[0] == '\0' || strlen (p) < 3)
2499    {
2500        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Too short X packet");
2501    }
2502
2503    char *c;
2504    p++;
2505    errno = 0;
2506    nub_addr_t addr = strtoull (p, &c, 16);
2507    if (errno != 0 && addr == 0)
2508    {
2509        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in X packet");
2510    }
2511    if (*c != ',')
2512    {
2513        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma sep missing in X packet");
2514    }
2515
2516    /* Advance 'p' to the length part of the packet.  */
2517    p += (c - p) + 1;
2518
2519    errno = 0;
2520    int length = strtoul (p, NULL, 16);
2521    if (errno != 0 && length == 0)
2522    {
2523        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in m packet");
2524    }
2525
2526    // I think gdb sends a zero length write request to test whether this
2527    // packet is accepted.
2528    if (length == 0)
2529    {
2530        return SendPacket ("OK");
2531    }
2532
2533    std::vector<uint8_t> data = decode_binary_data (c, -1);
2534    std::vector<uint8_t>::const_iterator it;
2535    uint8_t *buf = (uint8_t *) alloca (data.size ());
2536    uint8_t *i = buf;
2537    for (it = data.begin (); it != data.end (); ++it)
2538    {
2539        *i++ = *it;
2540    }
2541
2542    nub_size_t wrote = DNBProcessMemoryWrite (m_ctx.ProcessID(), addr, data.size(), buf);
2543    if (wrote != data.size ())
2544        return SendPacket ("E08");
2545    return SendPacket ("OK");
2546}
2547
2548/* 'g' -- read registers
2549 Get the contents of the registers for the current thread,
2550 send them to gdb.
2551 Should the setting of the Hg packet determine which thread's registers
2552 are returned?  */
2553
2554rnb_err_t
2555RNBRemote::HandlePacket_g (const char *p)
2556{
2557    std::ostringstream ostrm;
2558    if (!m_ctx.HasValidProcessID())
2559    {
2560        return SendPacket ("E11");
2561    }
2562
2563    if (g_num_reg_entries == 0)
2564        InitializeRegisters ();
2565
2566    nub_process_t pid = m_ctx.ProcessID ();
2567    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
2568    if (tid == INVALID_NUB_THREAD)
2569        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2570
2571    if (m_use_native_regs)
2572    {
2573        // Get the register context size first by calling with NULL buffer
2574        nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2575        if (reg_ctx_size)
2576        {
2577            // Now allocate enough space for the entire register context
2578            std::vector<uint8_t> reg_ctx;
2579            reg_ctx.resize(reg_ctx_size);
2580            // Now read the register context
2581            reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, &reg_ctx[0], reg_ctx.size());
2582            if (reg_ctx_size)
2583            {
2584                append_hex_value (ostrm, reg_ctx.data(), reg_ctx.size(), false);
2585                return SendPacket (ostrm.str ());
2586            }
2587        }
2588    }
2589
2590    for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2591        register_value_in_hex_fixed_width (ostrm, pid, tid, &g_reg_entries[reg], NULL);
2592
2593    return SendPacket (ostrm.str ());
2594}
2595
2596/* 'G XXX...' -- write registers
2597 How is the thread for these specified, beyond "the current thread"?
2598 Does gdb actually use the Hg packet to set this?  */
2599
2600rnb_err_t
2601RNBRemote::HandlePacket_G (const char *p)
2602{
2603    if (!m_ctx.HasValidProcessID())
2604    {
2605        return SendPacket ("E11");
2606    }
2607
2608    if (g_num_reg_entries == 0)
2609        InitializeRegisters ();
2610
2611    StringExtractor packet(p);
2612    packet.SetFilePos(1); // Skip the 'G'
2613
2614    nub_process_t pid = m_ctx.ProcessID();
2615    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
2616    if (tid == INVALID_NUB_THREAD)
2617        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
2618
2619    if (m_use_native_regs)
2620    {
2621        // Get the register context size first by calling with NULL buffer
2622        nub_size_t reg_ctx_size = DNBThreadGetRegisterContext(pid, tid, NULL, 0);
2623        if (reg_ctx_size)
2624        {
2625            // Now allocate enough space for the entire register context
2626            std::vector<uint8_t> reg_ctx;
2627            reg_ctx.resize(reg_ctx_size);
2628
2629            const nub_size_t bytes_extracted = packet.GetHexBytes (&reg_ctx[0], reg_ctx.size(), 0xcc);
2630            if (bytes_extracted == reg_ctx.size())
2631            {
2632                // Now write the register context
2633                reg_ctx_size = DNBThreadSetRegisterContext(pid, tid, reg_ctx.data(), reg_ctx.size());
2634                if (reg_ctx_size == reg_ctx.size())
2635                    return SendPacket ("OK");
2636                else
2637                    return SendPacket ("E55");
2638            }
2639            else
2640            {
2641                DNBLogError("RNBRemote::HandlePacket_G(%s): extracted %llu of %llu bytes, size mismatch\n", p, (uint64_t)bytes_extracted, (uint64_t)reg_ctx_size);
2642                return SendPacket ("E64");
2643            }
2644        }
2645        else
2646            return SendPacket ("E65");
2647    }
2648
2649
2650    DNBRegisterValue reg_value;
2651    for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
2652    {
2653        const register_map_entry_t *reg_entry = &g_reg_entries[reg];
2654
2655        reg_value.info = reg_entry->nub_info;
2656        if (packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc) != reg_entry->gdb_size)
2657            break;
2658
2659        if (reg_entry->fail_value == NULL)
2660        {
2661            if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
2662                return SendPacket ("E15");
2663        }
2664    }
2665    return SendPacket ("OK");
2666}
2667
2668static bool
2669RNBRemoteShouldCancelCallback (void *not_used)
2670{
2671    RNBRemoteSP remoteSP(g_remoteSP);
2672    if (remoteSP.get() != NULL)
2673    {
2674        RNBRemote* remote = remoteSP.get();
2675        if (remote->Comm().IsConnected())
2676            return false;
2677        else
2678            return true;
2679    }
2680    return true;
2681}
2682
2683
2684// FORMAT: _MXXXXXX,PPP
2685//      XXXXXX: big endian hex chars
2686//      PPP: permissions can be any combo of r w x chars
2687//
2688// RESPONSE: XXXXXX
2689//      XXXXXX: hex address of the newly allocated memory
2690//      EXX: error code
2691//
2692// EXAMPLES:
2693//      _M123000,rw
2694//      _M123000,rwx
2695//      _M123000,xw
2696
2697rnb_err_t
2698RNBRemote::HandlePacket_AllocateMemory (const char *p)
2699{
2700    StringExtractor packet (p);
2701    packet.SetFilePos(2); // Skip the "_M"
2702
2703    nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);
2704    if (size != 0)
2705    {
2706        if (packet.GetChar() == ',')
2707        {
2708            uint32_t permissions = 0;
2709            char ch;
2710            bool success = true;
2711            while (success && (ch = packet.GetChar()) != '\0')
2712            {
2713                switch (ch)
2714                {
2715                case 'r':   permissions |= eMemoryPermissionsReadable; break;
2716                case 'w':   permissions |= eMemoryPermissionsWritable; break;
2717                case 'x':   permissions |= eMemoryPermissionsExecutable; break;
2718                default:    success = false; break;
2719                }
2720            }
2721
2722            if (success)
2723            {
2724                nub_addr_t addr = DNBProcessMemoryAllocate (m_ctx.ProcessID(), size, permissions);
2725                if (addr != INVALID_NUB_ADDRESS)
2726                {
2727                    std::ostringstream ostrm;
2728                    ostrm << RAW_HEXBASE << addr;
2729                    return SendPacket (ostrm.str ());
2730                }
2731            }
2732        }
2733    }
2734    return SendPacket ("E53");
2735}
2736
2737// FORMAT: _mXXXXXX
2738//      XXXXXX: address that was previosly allocated
2739//
2740// RESPONSE: XXXXXX
2741//      OK: address was deallocated
2742//      EXX: error code
2743//
2744// EXAMPLES:
2745//      _m123000
2746
2747rnb_err_t
2748RNBRemote::HandlePacket_DeallocateMemory (const char *p)
2749{
2750    StringExtractor packet (p);
2751    packet.SetFilePos(2); // Skip the "_m"
2752    nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);
2753
2754    if (addr != INVALID_NUB_ADDRESS)
2755    {
2756        if (DNBProcessMemoryDeallocate (m_ctx.ProcessID(), addr))
2757            return SendPacket ("OK");
2758    }
2759    return SendPacket ("E54");
2760}
2761
2762static bool
2763GetProcessNameFrom_vAttach (const char *&p, std::string &attach_name)
2764{
2765    bool return_val = true;
2766    while (*p != '\0')
2767    {
2768        char smallbuf[3];
2769        smallbuf[0] = *p;
2770        smallbuf[1] = *(p + 1);
2771        smallbuf[2] = '\0';
2772
2773        errno = 0;
2774        int ch = strtoul (smallbuf, NULL, 16);
2775        if (errno != 0 && ch == 0)
2776        {
2777            return_val = false;
2778            break;
2779        }
2780
2781        attach_name.push_back(ch);
2782        p += 2;
2783    }
2784    return return_val;
2785}
2786
2787/*
2788 vAttach;pid
2789
2790 Attach to a new process with the specified process ID. pid is a hexadecimal integer
2791 identifying the process. If the stub is currently controlling a process, it is
2792 killed. The attached process is stopped.This packet is only available in extended
2793 mode (see extended mode).
2794
2795 Reply:
2796 "ENN"                      for an error
2797 "Any Stop Reply Packet"     for success
2798 */
2799
2800rnb_err_t
2801RNBRemote::HandlePacket_v (const char *p)
2802{
2803    if (strcmp (p, "vCont;c") == 0)
2804    {
2805        // Simple continue
2806        return RNBRemote::HandlePacket_c("c");
2807    }
2808    else if (strcmp (p, "vCont;s") == 0)
2809    {
2810        // Simple step
2811        return RNBRemote::HandlePacket_s("s");
2812    }
2813    else if (strstr (p, "vCont") == p)
2814    {
2815        typedef struct
2816        {
2817            nub_thread_t tid;
2818            char action;
2819            int signal;
2820        } vcont_action_t;
2821
2822        DNBThreadResumeActions thread_actions;
2823        char *c = (char *)(p += strlen("vCont"));
2824        char *c_end = c + strlen(c);
2825        if (*c == '?')
2826            return SendPacket ("vCont;c;C;s;S");
2827
2828        while (c < c_end && *c == ';')
2829        {
2830            ++c;    // Skip the semi-colon
2831            DNBThreadResumeAction thread_action;
2832            thread_action.tid = INVALID_NUB_THREAD;
2833            thread_action.state = eStateInvalid;
2834            thread_action.signal = 0;
2835            thread_action.addr = INVALID_NUB_ADDRESS;
2836
2837            char action = *c++;
2838
2839            switch (action)
2840            {
2841                case 'C':
2842                    errno = 0;
2843                    thread_action.signal = strtoul (c, &c, 16);
2844                    if (errno != 0)
2845                        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2846                    // Fall through to next case...
2847
2848                case 'c':
2849                    // Continue
2850                    thread_action.state = eStateRunning;
2851                    break;
2852
2853                case 'S':
2854                    errno = 0;
2855                    thread_action.signal = strtoul (c, &c, 16);
2856                    if (errno != 0)
2857                        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in vCont packet");
2858                    // Fall through to next case...
2859
2860                case 's':
2861                    // Step
2862                    thread_action.state = eStateStepping;
2863                    break;
2864
2865                default:
2866                    HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Unsupported action in vCont packet");
2867                    break;
2868            }
2869            if (*c == ':')
2870            {
2871                errno = 0;
2872                thread_action.tid = strtoul (++c, &c, 16);
2873                if (errno != 0)
2874                    return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in vCont packet");
2875            }
2876
2877            thread_actions.Append (thread_action);
2878        }
2879
2880        // If a default action for all other threads wasn't mentioned
2881        // then we should stop the threads
2882        thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
2883        DNBProcessResume(m_ctx.ProcessID(), thread_actions.GetFirst (), thread_actions.GetSize());
2884        return rnb_success;
2885    }
2886    else if (strstr (p, "vAttach") == p)
2887    {
2888        nub_process_t attach_pid = INVALID_NUB_PROCESS;
2889        char err_str[1024]={'\0'};
2890
2891        if (strstr (p, "vAttachWait;") == p)
2892        {
2893            p += strlen("vAttachWait;");
2894            std::string attach_name;
2895            if (!GetProcessNameFrom_vAttach(p, attach_name))
2896            {
2897                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachWait' pkt");
2898            }
2899            const bool ignore_existing = true;
2900            attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2901
2902        }
2903        else if (strstr (p, "vAttachOrWait;") == p)
2904        {
2905            p += strlen("vAttachOrWait;");
2906            std::string attach_name;
2907            if (!GetProcessNameFrom_vAttach(p, attach_name))
2908            {
2909                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachOrWait' pkt");
2910            }
2911            const bool ignore_existing = false;
2912            attach_pid = DNBProcessAttachWait(attach_name.c_str (), m_ctx.LaunchFlavor(), ignore_existing, NULL, 1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
2913        }
2914        else if (strstr (p, "vAttachName;") == p)
2915        {
2916            p += strlen("vAttachName;");
2917            std::string attach_name;
2918            if (!GetProcessNameFrom_vAttach(p, attach_name))
2919            {
2920                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
2921            }
2922
2923            attach_pid = DNBProcessAttachByName (attach_name.c_str(), NULL, err_str, sizeof(err_str));
2924
2925        }
2926        else if (strstr (p, "vAttach;") == p)
2927        {
2928            p += strlen("vAttach;");
2929            char *end = NULL;
2930            attach_pid = strtoul (p, &end, 16);    // PID will be in hex, so use base 16 to decode
2931            if (p != end && *end == '\0')
2932            {
2933                // Wait at most 30 second for attach
2934                struct timespec attach_timeout_abstime;
2935                DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
2936                attach_pid = DNBProcessAttach(attach_pid, &attach_timeout_abstime, err_str, sizeof(err_str));
2937            }
2938        }
2939        else
2940        {
2941            return HandlePacket_UNIMPLEMENTED(p);
2942        }
2943
2944
2945        if (attach_pid != INVALID_NUB_PROCESS)
2946        {
2947            if (m_ctx.ProcessID() != attach_pid)
2948                m_ctx.SetProcessID(attach_pid);
2949            // Send a stop reply packet to indicate we successfully attached!
2950            NotifyThatProcessStopped ();
2951            return rnb_success;
2952        }
2953        else
2954        {
2955            m_ctx.LaunchStatus().SetError(-1, DNBError::Generic);
2956            if (err_str[0])
2957                m_ctx.LaunchStatus().SetErrorString(err_str);
2958            else
2959                m_ctx.LaunchStatus().SetErrorString("attach failed");
2960            return SendPacket ("E01");  // E01 is our magic error value for attach failed.
2961        }
2962    }
2963
2964    // All other failures come through here
2965    return HandlePacket_UNIMPLEMENTED(p);
2966}
2967
2968/* 'T XX' -- status of thread
2969 Check if the specified thread is alive.
2970 The thread number is in hex?  */
2971
2972rnb_err_t
2973RNBRemote::HandlePacket_T (const char *p)
2974{
2975    p++;
2976    if (p == NULL || *p == '\0')
2977    {
2978        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in T packet");
2979    }
2980    if (!m_ctx.HasValidProcessID())
2981    {
2982        return SendPacket ("E15");
2983    }
2984    errno = 0;
2985    nub_thread_t tid = strtoul (p, NULL, 16);
2986    if (errno != 0 && tid == 0)
2987    {
2988        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse thread number in T packet");
2989    }
2990
2991    nub_state_t state = DNBThreadGetState (m_ctx.ProcessID(), tid);
2992    if (state == eStateInvalid || state == eStateExited || state == eStateCrashed)
2993    {
2994        return SendPacket ("E16");
2995    }
2996
2997    return SendPacket ("OK");
2998}
2999
3000
3001rnb_err_t
3002RNBRemote::HandlePacket_z (const char *p)
3003{
3004    if (p == NULL || *p == '\0')
3005        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in z packet");
3006
3007    if (!m_ctx.HasValidProcessID())
3008        return SendPacket ("E15");
3009
3010    char packet_cmd = *p++;
3011    char break_type = *p++;
3012
3013    if (*p++ != ',')
3014        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
3015
3016    char *c = NULL;
3017    nub_process_t pid = m_ctx.ProcessID();
3018    errno = 0;
3019    nub_addr_t addr = strtoull (p, &c, 16);
3020    if (errno != 0 && addr == 0)
3021        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in z packet");
3022    p = c;
3023    if (*p++ != ',')
3024        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Comma separator missing in z packet");
3025
3026    errno = 0;
3027    uint32_t byte_size = strtoul (p, &c, 16);
3028    if (errno != 0 && byte_size == 0)
3029        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid length in z packet");
3030
3031    if (packet_cmd == 'Z')
3032    {
3033        // set
3034        switch (break_type)
3035        {
3036            case '0':   // set software breakpoint
3037            case '1':   // set hardware breakpoint
3038            {
3039                // gdb can send multiple Z packets for the same address and
3040                // these calls must be ref counted.
3041                bool hardware = (break_type == '1');
3042
3043                // Check if we currently have a breakpoint already set at this address
3044                BreakpointMapIter pos = m_breakpoints.find(addr);
3045                if (pos != m_breakpoints.end())
3046                {
3047                    // We do already have a breakpoint at this address, increment
3048                    // its reference count and return OK
3049                    pos->second.Retain();
3050                    return SendPacket ("OK");
3051                }
3052                else
3053                {
3054                    // We do NOT already have a breakpoint at this address, So lets
3055                    // create one.
3056                    nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware);
3057                    if (NUB_BREAK_ID_IS_VALID(break_id))
3058                    {
3059                        // We successfully created a breakpoint, now lets full out
3060                        // a ref count structure with the breakID and add it to our
3061                        // map.
3062                        Breakpoint rnbBreakpoint(break_id);
3063                        m_breakpoints[addr] = rnbBreakpoint;
3064                        return SendPacket ("OK");
3065                    }
3066                    else
3067                    {
3068                        // We failed to set the software breakpoint
3069                        return SendPacket ("E09");
3070                    }
3071                }
3072            }
3073                break;
3074
3075            case '2':   // set write watchpoint
3076            case '3':   // set read watchpoint
3077            case '4':   // set access watchpoint
3078            {
3079                bool hardware = true;
3080                uint32_t watch_flags = 0;
3081                if (break_type == '2')
3082                    watch_flags = WATCH_TYPE_WRITE;
3083                else if (break_type == '3')
3084                    watch_flags = WATCH_TYPE_READ;
3085                else
3086                    watch_flags = WATCH_TYPE_READ | WATCH_TYPE_WRITE;
3087
3088                // Check if we currently have a watchpoint already set at this address
3089                BreakpointMapIter pos = m_watchpoints.find(addr);
3090                if (pos != m_watchpoints.end())
3091                {
3092                    // We do already have a watchpoint at this address, increment
3093                    // its reference count and return OK
3094                    pos->second.Retain();
3095                    return SendPacket ("OK");
3096                }
3097                else
3098                {
3099                    // We do NOT already have a watchpoint at this address, So lets
3100                    // create one.
3101                    nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware);
3102                    if (NUB_WATCH_ID_IS_VALID(watch_id))
3103                    {
3104                        // We successfully created a watchpoint, now lets full out
3105                        // a ref count structure with the watch_id and add it to our
3106                        // map.
3107                        Breakpoint rnbWatchpoint(watch_id);
3108                        m_watchpoints[addr] = rnbWatchpoint;
3109                        return SendPacket ("OK");
3110                    }
3111                    else
3112                    {
3113                        // We failed to set the watchpoint
3114                        return SendPacket ("E09");
3115                    }
3116                }
3117            }
3118                break;
3119
3120            default:
3121                break;
3122        }
3123    }
3124    else if (packet_cmd == 'z')
3125    {
3126        // remove
3127        switch (break_type)
3128        {
3129            case '0':   // remove software breakpoint
3130            case '1':   // remove hardware breakpoint
3131            {
3132                // gdb can send multiple z packets for the same address and
3133                // these calls must be ref counted.
3134                BreakpointMapIter pos = m_breakpoints.find(addr);
3135                if (pos != m_breakpoints.end())
3136                {
3137                    // We currently have a breakpoint at address ADDR. Decrement
3138                    // its reference count, and it that count is now zero we
3139                    // can clear the breakpoint.
3140                    pos->second.Release();
3141                    if (pos->second.RefCount() == 0)
3142                    {
3143                        if (DNBBreakpointClear (pid, pos->second.BreakID()))
3144                        {
3145                            m_breakpoints.erase(pos);
3146                            return SendPacket ("OK");
3147                        }
3148                        else
3149                        {
3150                            return SendPacket ("E08");
3151                        }
3152                    }
3153                    else
3154                    {
3155                        // We still have references to this breakpoint don't
3156                        // delete it, just decrementing the reference count
3157                        // is enough.
3158                        return SendPacket ("OK");
3159                    }
3160                }
3161                else
3162                {
3163                    // We don't know about any breakpoints at this address
3164                    return SendPacket ("E08");
3165                }
3166            }
3167                break;
3168
3169            case '2':   // remove write watchpoint
3170            case '3':   // remove read watchpoint
3171            case '4':   // remove access watchpoint
3172            {
3173                // gdb can send multiple z packets for the same address and
3174                // these calls must be ref counted.
3175                BreakpointMapIter pos = m_watchpoints.find(addr);
3176                if (pos != m_watchpoints.end())
3177                {
3178                    // We currently have a watchpoint at address ADDR. Decrement
3179                    // its reference count, and it that count is now zero we
3180                    // can clear the watchpoint.
3181                    pos->second.Release();
3182                    if (pos->second.RefCount() == 0)
3183                    {
3184                        if (DNBWatchpointClear (pid, pos->second.BreakID()))
3185                        {
3186                            m_watchpoints.erase(pos);
3187                            return SendPacket ("OK");
3188                        }
3189                        else
3190                        {
3191                            return SendPacket ("E08");
3192                        }
3193                    }
3194                    else
3195                    {
3196                        // We still have references to this watchpoint don't
3197                        // delete it, just decrementing the reference count
3198                        // is enough.
3199                        return SendPacket ("OK");
3200                    }
3201                }
3202                else
3203                {
3204                    // We don't know about any watchpoints at this address
3205                    return SendPacket ("E08");
3206                }
3207            }
3208                break;
3209
3210            default:
3211                break;
3212        }
3213    }
3214    return HandlePacket_UNIMPLEMENTED(p);
3215}
3216
3217// Extract the thread number from the thread suffix that might be appended to
3218// thread specific packets. This will only be enabled if m_thread_suffix_supported
3219// is true.
3220nub_thread_t
3221RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
3222{
3223    if (m_thread_suffix_supported)
3224    {
3225        nub_thread_t tid = INVALID_NUB_THREAD;
3226        if (p)
3227        {
3228            const char *tid_cstr = strstr (p, "thread:");
3229            if (tid_cstr)
3230            {
3231                tid_cstr += strlen ("thread:");
3232                tid = strtoul(tid_cstr, NULL, 16);
3233            }
3234        }
3235        return tid;
3236    }
3237    return GetCurrentThread();
3238
3239}
3240
3241/* 'p XX'
3242 print the contents of register X */
3243
3244rnb_err_t
3245RNBRemote::HandlePacket_p (const char *p)
3246{
3247    if (g_num_reg_entries == 0)
3248        InitializeRegisters ();
3249
3250    if (p == NULL || *p == '\0')
3251    {
3252        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3253    }
3254    if (!m_ctx.HasValidProcessID())
3255    {
3256        return SendPacket ("E15");
3257    }
3258    nub_process_t pid = m_ctx.ProcessID();
3259    errno = 0;
3260    char *tid_cstr = NULL;
3261    uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
3262    if (errno != 0 && reg == 0)
3263    {
3264        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse register number in p packet");
3265    }
3266
3267    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
3268    if (tid == INVALID_NUB_THREAD)
3269        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3270
3271    const register_map_entry_t *reg_entry;
3272
3273    if (reg < g_num_reg_entries)
3274        reg_entry = &g_reg_entries[reg];
3275    else
3276        reg_entry = NULL;
3277
3278    std::ostringstream ostrm;
3279    if (reg_entry == NULL)
3280    {
3281        DNBLogError("RNBRemote::HandlePacket_p(%s): unknown register number %u requested\n", p, reg);
3282        ostrm << "00000000";
3283    }
3284    else if (reg_entry->nub_info.reg == -1)
3285    {
3286        if (reg_entry->gdb_size > 0)
3287        {
3288            if (reg_entry->fail_value != NULL)
3289            {
3290                append_hex_value(ostrm, reg_entry->fail_value, reg_entry->gdb_size, false);
3291            }
3292            else
3293            {
3294                std::basic_string<uint8_t> zeros(reg_entry->gdb_size, '\0');
3295                append_hex_value(ostrm, zeros.data(), zeros.size(), false);
3296            }
3297        }
3298    }
3299    else
3300    {
3301        register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry, NULL);
3302    }
3303    return SendPacket (ostrm.str());
3304}
3305
3306/* 'Pnn=rrrrr'
3307 Set register number n to value r.
3308 n and r are hex strings.  */
3309
3310rnb_err_t
3311RNBRemote::HandlePacket_P (const char *p)
3312{
3313    if (g_num_reg_entries == 0)
3314        InitializeRegisters ();
3315
3316    if (p == NULL || *p == '\0')
3317    {
3318        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Empty P packet");
3319    }
3320    if (!m_ctx.HasValidProcessID())
3321    {
3322        return SendPacket ("E28");
3323    }
3324
3325    nub_process_t pid = m_ctx.ProcessID();
3326
3327    StringExtractor packet (p);
3328
3329    const char cmd_char = packet.GetChar();
3330    // Register ID is always in big endian
3331    const uint32_t reg = packet.GetHexMaxU32 (false, UINT32_MAX);
3332    const char equal_char = packet.GetChar();
3333
3334    if (cmd_char != 'P')
3335        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Improperly formed P packet");
3336
3337    if (reg == UINT32_MAX)
3338        return SendPacket ("E29");
3339
3340    if (equal_char != '=')
3341        return SendPacket ("E30");
3342
3343    const register_map_entry_t *reg_entry;
3344
3345    if (reg >= g_num_reg_entries)
3346        return SendPacket("E47");
3347
3348    reg_entry = &g_reg_entries[reg];
3349
3350    if (reg_entry->nub_info.set == -1 && reg_entry->nub_info.reg == -1)
3351    {
3352        DNBLogError("RNBRemote::HandlePacket_P(%s): unknown register number %u requested\n", p, reg);
3353        return SendPacket("E48");
3354    }
3355
3356    DNBRegisterValue reg_value;
3357    reg_value.info = reg_entry->nub_info;
3358    packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
3359
3360    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
3361    if (tid == INVALID_NUB_THREAD)
3362        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread specified in p packet");
3363
3364    if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
3365    {
3366        return SendPacket ("E32");
3367    }
3368    return SendPacket ("OK");
3369}
3370
3371/* 'c [addr]'
3372 Continue, optionally from a specified address. */
3373
3374rnb_err_t
3375RNBRemote::HandlePacket_c (const char *p)
3376{
3377    const nub_process_t pid = m_ctx.ProcessID();
3378
3379    if (pid == INVALID_NUB_PROCESS)
3380        return SendPacket ("E23");
3381
3382    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3383
3384    if (*(p + 1) != '\0')
3385    {
3386        action.tid = GetContinueThread();
3387        errno = 0;
3388        action.addr = strtoull (p + 1, NULL, 16);
3389        if (errno != 0 && action.addr == 0)
3390            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in c packet");
3391    }
3392
3393    DNBThreadResumeActions thread_actions;
3394    thread_actions.Append(action);
3395    thread_actions.SetDefaultThreadActionIfNeeded(eStateRunning, 0);
3396    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3397        return SendPacket ("E25");
3398    // Don't send an "OK" packet; response is the stopped/exited message.
3399    return rnb_success;
3400}
3401
3402rnb_err_t
3403RNBRemote::HandlePacket_MemoryRegionInfo (const char *p)
3404{
3405    /* This packet will find memory attributes (e.g. readable, writable, executable, stack, jitted code)
3406       for the memory region containing a given address and return that information.
3407
3408       Users of this packet must be prepared for three results:
3409
3410           Region information is returned
3411           Region information is unavailable for this address because the address is in unmapped memory
3412           Region lookup cannot be performed on this platform or process is not yet launched
3413           This packet isn't implemented
3414
3415       Examples of use:
3416          qMemoryRegionInfo:3a55140
3417          start:3a50000,size:100000,permissions:rwx
3418
3419          qMemoryRegionInfo:0
3420          error:address in unmapped region
3421
3422          qMemoryRegionInfo:3a551140   (on a different platform)
3423          error:region lookup cannot be performed
3424
3425          qMemoryRegionInfo
3426          OK                   // this packet is implemented by the remote nub
3427    */
3428
3429    p += sizeof ("qMemoryRegionInfo") - 1;
3430    if (*p == '\0')
3431       return SendPacket ("OK");
3432    if (*p++ != ':')
3433       return SendPacket ("E67");
3434    if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
3435       p += 2;
3436
3437    errno = 0;
3438    uint64_t address = strtoul (p, NULL, 16);
3439    if (errno != 0 && address == 0)
3440    {
3441        return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Invalid address in qMemoryRegionInfo packet");
3442    }
3443
3444    DNBRegionInfo region_info = { 0, 0, 0 };
3445    DNBProcessMemoryRegionInfo (m_ctx.ProcessID(), address, &region_info);
3446    std::ostringstream ostrm;
3447
3448        // start:3a50000,size:100000,permissions:rwx
3449    ostrm << "start:" << std::hex << region_info.addr << ';';
3450
3451    if (region_info.size > 0)
3452        ostrm << "size:"  << std::hex << region_info.size << ';';
3453
3454    if (region_info.permissions)
3455    {
3456        ostrm << "permissions:";
3457
3458        if (region_info.permissions & eMemoryPermissionsReadable)
3459            ostrm << 'r';
3460        if (region_info.permissions & eMemoryPermissionsWritable)
3461            ostrm << 'w';
3462        if (region_info.permissions & eMemoryPermissionsExecutable)
3463            ostrm << 'x';
3464        ostrm << ';';
3465    }
3466    return SendPacket (ostrm.str());
3467}
3468
3469rnb_err_t
3470RNBRemote::HandlePacket_GetProfileData (const char *p)
3471{
3472    nub_process_t pid = m_ctx.ProcessID();
3473    if (pid == INVALID_NUB_PROCESS)
3474        return SendPacket ("OK");
3475
3476    std::string data = DNBProcessGetProfileData(pid);
3477    if (!data.empty())
3478    {
3479        return SendPacket (data.c_str());
3480    }
3481    else
3482    {
3483        return SendPacket ("OK");
3484    }
3485}
3486
3487
3488// QSetAsyncEnableProfiling;enable:[0|1]:interval_usec:XXXXXX;
3489rnb_err_t
3490RNBRemote::HandlePacket_SetAsyncEnableProfiling (const char *p)
3491{
3492    nub_process_t pid = m_ctx.ProcessID();
3493    if (pid == INVALID_NUB_PROCESS)
3494        return SendPacket ("");
3495
3496    StringExtractor packet(p += sizeof ("QSetAsyncEnableProfiling:") - 1);
3497    bool enable = false;
3498    uint64_t interval_usec = 0;
3499    std::string name;
3500    std::string value;
3501    while (packet.GetNameColonValue(name, value))
3502    {
3503        if (name.compare ("enable") == 0)
3504        {
3505            enable  = strtoul(value.c_str(), NULL, 10) > 0;
3506        }
3507        else if (name.compare ("interval_usec") == 0)
3508        {
3509            interval_usec  = strtoul(value.c_str(), NULL, 10);
3510        }
3511    }
3512
3513    if (interval_usec == 0)
3514    {
3515        enable = 0;
3516    }
3517    DNBProcessSetAsyncEnableProfiling(pid, enable, interval_usec);
3518    return SendPacket ("OK");
3519}
3520
3521rnb_err_t
3522RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p)
3523{
3524    /* This packet simply returns the number of supported hardware watchpoints.
3525
3526       Examples of use:
3527          qWatchpointSupportInfo:
3528          num:4
3529
3530          qWatchpointSupportInfo
3531          OK                   // this packet is implemented by the remote nub
3532    */
3533
3534    p += sizeof ("qWatchpointSupportInfo") - 1;
3535    if (*p == '\0')
3536       return SendPacket ("OK");
3537    if (*p++ != ':')
3538       return SendPacket ("E67");
3539
3540    errno = 0;
3541    uint32_t num = DNBWatchpointGetNumSupportedHWP (m_ctx.ProcessID());
3542    std::ostringstream ostrm;
3543
3544    // size:4
3545    ostrm << "num:" << std::dec << num << ';';
3546    return SendPacket (ostrm.str());
3547}
3548
3549/* 'C sig [;addr]'
3550 Resume with signal sig, optionally at address addr.  */
3551
3552rnb_err_t
3553RNBRemote::HandlePacket_C (const char *p)
3554{
3555    const nub_process_t pid = m_ctx.ProcessID();
3556
3557    if (pid == INVALID_NUB_PROCESS)
3558        return SendPacket ("E36");
3559
3560    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateRunning, 0, INVALID_NUB_ADDRESS };
3561    int process_signo = -1;
3562    if (*(p + 1) != '\0')
3563    {
3564        action.tid = GetContinueThread();
3565        char *end = NULL;
3566        errno = 0;
3567        process_signo = strtoul (p + 1, &end, 16);
3568        if (errno != 0)
3569            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in C packet");
3570        else if (*end == ';')
3571        {
3572            errno = 0;
3573            action.addr = strtoull (end + 1, NULL, 16);
3574            if (errno != 0 && action.addr == 0)
3575                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in C packet");
3576        }
3577    }
3578
3579    DNBThreadResumeActions thread_actions;
3580    thread_actions.Append (action);
3581    thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, action.signal);
3582    if (!DNBProcessSignal(pid, process_signo))
3583        return SendPacket ("E52");
3584    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3585        return SendPacket ("E38");
3586    /* Don't send an "OK" packet; response is the stopped/exited message.  */
3587    return rnb_success;
3588}
3589
3590//----------------------------------------------------------------------
3591// 'D' packet
3592// Detach from gdb.
3593//----------------------------------------------------------------------
3594rnb_err_t
3595RNBRemote::HandlePacket_D (const char *p)
3596{
3597    SendPacket ("OK");
3598    if (m_ctx.HasValidProcessID())
3599        DNBProcessDetach(m_ctx.ProcessID());
3600    return rnb_success;
3601}
3602
3603/* 'k'
3604 Kill the inferior process.  */
3605
3606rnb_err_t
3607RNBRemote::HandlePacket_k (const char *p)
3608{
3609    // No response to should be sent to the kill packet
3610    if (m_ctx.HasValidProcessID())
3611        DNBProcessKill (m_ctx.ProcessID());
3612    SendPacket ("W09");
3613    return rnb_success;
3614}
3615
3616rnb_err_t
3617RNBRemote::HandlePacket_stop_process (const char *p)
3618{
3619//#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt
3620#if defined(TEST_EXIT_ON_INTERRUPT)
3621    rnb_err_t err = HandlePacket_k (p);
3622    m_comm.Disconnect(true);
3623    return err;
3624#else
3625    DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
3626    //DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
3627    // Do not send any response packet! Wait for the stop reply packet to naturally happen
3628    return rnb_success;
3629#endif
3630}
3631
3632/* 's'
3633 Step the inferior process.  */
3634
3635rnb_err_t
3636RNBRemote::HandlePacket_s (const char *p)
3637{
3638    const nub_process_t pid = m_ctx.ProcessID();
3639    if (pid == INVALID_NUB_PROCESS)
3640        return SendPacket ("E32");
3641
3642    // Hardware supported stepping not supported on arm
3643    nub_thread_t tid = GetContinueThread ();
3644    if (tid == 0 || tid == -1)
3645        tid = GetCurrentThread();
3646
3647    if (tid == INVALID_NUB_THREAD)
3648        return SendPacket ("E33");
3649
3650    DNBThreadResumeActions thread_actions;
3651    thread_actions.AppendAction(tid, eStateStepping);
3652
3653    // Make all other threads stop when we are stepping
3654    thread_actions.SetDefaultThreadActionIfNeeded (eStateStopped, 0);
3655    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3656        return SendPacket ("E49");
3657    // Don't send an "OK" packet; response is the stopped/exited message.
3658    return rnb_success;
3659}
3660
3661/* 'S sig [;addr]'
3662 Step with signal sig, optionally at address addr.  */
3663
3664rnb_err_t
3665RNBRemote::HandlePacket_S (const char *p)
3666{
3667    const nub_process_t pid = m_ctx.ProcessID();
3668    if (pid == INVALID_NUB_PROCESS)
3669        return SendPacket ("E36");
3670
3671    DNBThreadResumeAction action = { INVALID_NUB_THREAD, eStateStepping, 0, INVALID_NUB_ADDRESS };
3672
3673    if (*(p + 1) != '\0')
3674    {
3675        char *end = NULL;
3676        errno = 0;
3677        action.signal = strtoul (p + 1, &end, 16);
3678        if (errno != 0)
3679            return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse signal in S packet");
3680        else if (*end == ';')
3681        {
3682            errno = 0;
3683            action.addr = strtoull (end + 1, NULL, 16);
3684            if (errno != 0 && action.addr == 0)
3685            {
3686                return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "Could not parse address in S packet");
3687            }
3688        }
3689    }
3690
3691    action.tid = GetContinueThread ();
3692    if (action.tid == 0 || action.tid == -1)
3693        return SendPacket ("E40");
3694
3695    nub_state_t tstate = DNBThreadGetState (pid, action.tid);
3696    if (tstate == eStateInvalid || tstate == eStateExited)
3697        return SendPacket ("E37");
3698
3699
3700    DNBThreadResumeActions thread_actions;
3701    thread_actions.Append (action);
3702
3703    // Make all other threads stop when we are stepping
3704    thread_actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
3705    if (!DNBProcessResume (pid, thread_actions.GetFirst(), thread_actions.GetSize()))
3706        return SendPacket ("E39");
3707
3708    // Don't send an "OK" packet; response is the stopped/exited message.
3709    return rnb_success;
3710}
3711
3712rnb_err_t
3713RNBRemote::HandlePacket_qHostInfo (const char *p)
3714{
3715    std::ostringstream strm;
3716
3717    uint32_t cputype, is_64_bit_capable;
3718    size_t len = sizeof(cputype);
3719    bool promoted_to_64 = false;
3720    if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
3721    {
3722        len = sizeof (is_64_bit_capable);
3723        if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
3724        {
3725            if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
3726            {
3727                promoted_to_64 = true;
3728                cputype |= CPU_ARCH_ABI64;
3729            }
3730        }
3731
3732        strm << "cputype:" << std::dec << cputype << ';';
3733    }
3734
3735    uint32_t cpusubtype;
3736    len = sizeof(cpusubtype);
3737    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
3738    {
3739        if (promoted_to_64 &&
3740            cputype == CPU_TYPE_X86_64 &&
3741            cpusubtype == CPU_SUBTYPE_486)
3742            cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3743
3744        strm << "cpusubtype:" << std::dec << cpusubtype << ';';
3745    }
3746
3747    // The OS in the triple should be "ios" or "macosx" which doesn't match our
3748    // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
3749    // this for now.
3750    if (cputype == CPU_TYPE_ARM)
3751    {
3752        strm << "ostype:ios;";
3753        // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes.
3754        strm << "watchpoint_exceptions_received:before;";
3755    }
3756    else
3757    {
3758        strm << "ostype:macosx;";
3759        strm << "watchpoint_exceptions_received:after;";
3760    }
3761//    char ostype[64];
3762//    len = sizeof(ostype);
3763//    if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
3764//    {
3765//        len = strlen(ostype);
3766//        std::transform (ostype, ostype + len, ostype, tolower);
3767//        strm << "ostype:" << std::dec << ostype << ';';
3768//    }
3769
3770    strm << "vendor:apple;";
3771
3772#if defined (__LITTLE_ENDIAN__)
3773    strm << "endian:little;";
3774#elif defined (__BIG_ENDIAN__)
3775    strm << "endian:big;";
3776#elif defined (__PDP_ENDIAN__)
3777    strm << "endian:pdp;";
3778#endif
3779
3780    if (promoted_to_64)
3781        strm << "ptrsize:8;";
3782    else
3783        strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
3784    return SendPacket (strm.str());
3785}
3786
3787
3788// Note that all numeric values returned by qProcessInfo are hex encoded,
3789// including the pid and the cpu type.
3790
3791rnb_err_t
3792RNBRemote::HandlePacket_qProcessInfo (const char *p)
3793{
3794    nub_process_t pid;
3795    std::ostringstream rep;
3796
3797    // If we haven't run the process yet, return an error.
3798    if (!m_ctx.HasValidProcessID())
3799        return SendPacket ("E68");
3800
3801    pid = m_ctx.ProcessID();
3802
3803    rep << "pid:" << std::hex << pid << ";";
3804
3805    int procpid_mib[4];
3806    procpid_mib[0] = CTL_KERN;
3807    procpid_mib[1] = KERN_PROC;
3808    procpid_mib[2] = KERN_PROC_PID;
3809    procpid_mib[3] = pid;
3810    struct kinfo_proc proc_kinfo;
3811    size_t proc_kinfo_size = sizeof(struct kinfo_proc);
3812
3813    if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
3814    {
3815        if (proc_kinfo_size > 0)
3816        {
3817            rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";";
3818            rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";";
3819            rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";";
3820            rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";";
3821            if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
3822                rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";";
3823        }
3824    }
3825
3826    int cputype_mib[CTL_MAXNAME]={0,};
3827    size_t cputype_mib_len = CTL_MAXNAME;
3828    cpu_type_t cputype = -1;
3829    if (::sysctlnametomib("sysctl.proc_cputype", cputype_mib, &cputype_mib_len) == 0)
3830    {
3831        cputype_mib[cputype_mib_len] = pid;
3832        cputype_mib_len++;
3833        size_t len = sizeof(cputype);
3834        if (::sysctl (cputype_mib, cputype_mib_len, &cputype, &len, 0, 0) == 0)
3835        {
3836            rep << "cputype:" << std::hex << cputype << ";";
3837        }
3838    }
3839
3840    uint32_t cpusubtype;
3841    size_t cpusubtype_len = sizeof(cpusubtype);
3842    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
3843    {
3844        if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486)
3845        {
3846            cpusubtype = CPU_SUBTYPE_X86_64_ALL;
3847        }
3848
3849        rep << "cpusubtype:" << std::hex << cpusubtype << ';';
3850    }
3851
3852    // The OS in the triple should be "ios" or "macosx" which doesn't match our
3853    // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
3854    // this for now.
3855    if (cputype == CPU_TYPE_ARM)
3856        rep << "ostype:ios;";
3857    else
3858        rep << "ostype:macosx;";
3859
3860    rep << "vendor:apple;";
3861
3862#if defined (__LITTLE_ENDIAN__)
3863    rep << "endian:little;";
3864#elif defined (__BIG_ENDIAN__)
3865    rep << "endian:big;";
3866#elif defined (__PDP_ENDIAN__)
3867    rep << "endian:pdp;";
3868#endif
3869
3870    nub_thread_t thread = DNBProcessGetCurrentThread (pid);
3871    kern_return_t kr;
3872
3873#if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
3874    x86_thread_state_t gp_regs;
3875    mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
3876    kr = thread_get_state (thread, x86_THREAD_STATE,
3877                           (thread_state_t) &gp_regs, &gp_count);
3878    if (kr == KERN_SUCCESS)
3879    {
3880        if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
3881            rep << "ptrsize:8;";
3882        else
3883            rep << "ptrsize:4;";
3884    }
3885#elif defined (__arm__)
3886    rep << "ptrsize:4;";
3887#endif
3888
3889    return SendPacket (rep.str());
3890}
3891
3892