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