Home | History | Annotate | Download | only in source
      1 //===-- RNBRemote.h ---------------------------------------------*- 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 #ifndef __RNBRemote_h__
     15 #define __RNBRemote_h__
     16 
     17 #include "RNBDefs.h"
     18 #include "DNB.h"
     19 #include "RNBContext.h"
     20 #include "RNBSocket.h"
     21 #include "PThreadMutex.h"
     22 #include <string>
     23 #include <vector>
     24 #include <deque>
     25 #include <map>
     26 
     27 class RNBSocket;
     28 class RNBContext;
     29 class PThreadEvents;
     30 
     31 enum event_loop_mode { debug_nub, gdb_remote_protocol, done };
     32 
     33 class RNBRemote
     34 {
     35 public:
     36 
     37     typedef enum {
     38         invalid_packet = 0,
     39         ack,                            // '+'
     40         nack,                           // '-'
     41         halt,                           // ^C  (async halt)
     42         use_extended_mode,              // '!'
     43         why_halted,                     // '?'
     44         set_argv,                       // 'A'
     45         set_bp,                         // 'B'
     46         cont,                           // 'c'
     47         continue_with_sig,              // 'C'
     48         detach,                         // 'D'
     49         read_general_regs,              // 'g'
     50         write_general_regs,             // 'G'
     51         set_thread,                     // 'H'
     52         step_inferior_one_cycle,        // 'i'
     53         signal_and_step_inf_one_cycle,  // 'I'
     54         kill,                           // 'k'
     55         read_memory,                    // 'm'
     56         write_memory,                   // 'M'
     57         read_register,                  // 'p'
     58         write_register,                 // 'P'
     59         restart,                        // 'R'
     60         single_step,                    // 's'
     61         single_step_with_sig,           // 'S'
     62         search_mem_backwards,           // 't'
     63         thread_alive_p,                 // 'T'
     64         vattach,                        // 'vAttach;pid'
     65         vattachwait,                    // 'vAttachWait:XX...' where XX is one or more hex encoded process name ASCII bytes
     66         vattachorwait,                  // 'vAttachOrWait:XX...' where XX is one or more hex encoded process name ASCII bytes
     67         vattachname,                    // 'vAttachName:XX...' where XX is one or more hex encoded process name ASCII bytes
     68         vcont,                          // 'vCont'
     69         vcont_list_actions,             // 'vCont?'
     70         write_data_to_memory,           // 'X'
     71         insert_mem_bp,                  // 'Z0'
     72         remove_mem_bp,                  // 'z0'
     73         insert_hardware_bp,             // 'Z1'
     74         remove_hardware_bp,             // 'z1'
     75         insert_write_watch_bp,          // 'Z2'
     76         remove_write_watch_bp,          // 'z2'
     77         insert_read_watch_bp,           // 'Z3'
     78         remove_read_watch_bp,           // 'z3'
     79         insert_access_watch_bp,         // 'Z4'
     80         remove_access_watch_bp,         // 'z4'
     81 
     82         query_monitor,                  // 'qRcmd'
     83         query_current_thread_id,        // 'qC'
     84         query_get_pid,                  // 'qGetPid'
     85         query_thread_ids_first,         // 'qfThreadInfo'
     86         query_thread_ids_subsequent,    // 'qsThreadInfo'
     87         query_thread_extra_info,        // 'qThreadExtraInfo'
     88         query_thread_stop_info,         // 'qThreadStopInfo'
     89         query_image_offsets,            // 'qOffsets'
     90         query_symbol_lookup,            // 'gSymbols'
     91         query_launch_success,           // 'qLaunchSuccess'
     92         query_register_info,            // 'qRegisterInfo'
     93         query_shlib_notify_info_addr,   // 'qShlibInfoAddr'
     94         query_step_packet_supported,    // 'qStepPacketSupported'
     95         query_vattachorwait_supported,  // 'qVAttachOrWaitSupported'
     96         query_sync_thread_state_supported,// 'QSyncThreadState'
     97         query_host_info,                // 'qHostInfo'
     98         query_process_info,             // 'qProcessInfo'
     99         pass_signals_to_inferior,       // 'QPassSignals'
    100         start_noack_mode,               // 'QStartNoAckMode'
    101         prefix_reg_packets_with_tid,    // 'QPrefixRegisterPacketsWithThreadID
    102         set_logging_mode,               // 'QSetLogging:'
    103         set_max_packet_size,            // 'QSetMaxPacketSize:'
    104         set_max_payload_size,           // 'QSetMaxPayloadSize:'
    105         set_environment_variable,       // 'QEnvironment:'
    106         set_environment_variable_hex,   // 'QEnvironmentHexEncoded:'
    107         set_launch_arch,                // 'QLaunchArch:'
    108         set_disable_aslr,               // 'QSetDisableASLR:'
    109         set_stdin,                      // 'QSetSTDIN:'
    110         set_stdout,                     // 'QSetSTDOUT:'
    111         set_stderr,                     // 'QSetSTDERR:'
    112         set_working_dir,                // 'QSetWorkingDir:'
    113         set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:'
    114         sync_thread_state,              // 'QSyncThreadState:'
    115         memory_region_info,             // 'qMemoryRegionInfo:'
    116         get_profile_data,               // 'qGetProfileData'
    117         set_enable_profiling,           // 'QSetEnableAsyncProfiling'
    118         watchpoint_support_info,        // 'qWatchpointSupportInfo:'
    119         allocate_memory,                // '_M'
    120         deallocate_memory,              // '_m'
    121 
    122         unknown_type
    123     } PacketEnum;
    124 
    125     typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
    126 
    127     RNBRemote ();
    128     ~RNBRemote ();
    129 
    130     void            Initialize();
    131 
    132     bool            InitializeRegisters (bool force = false);
    133 
    134     rnb_err_t       HandleAsyncPacket(PacketEnum *type = NULL);
    135     rnb_err_t       HandleReceivedPacket(PacketEnum *type = NULL);
    136 
    137     nub_thread_t    GetContinueThread () const
    138                     {
    139                         return m_continue_thread;
    140                     }
    141 
    142     void            SetContinueThread (nub_thread_t tid)
    143                     {
    144                         m_continue_thread = tid;
    145                     }
    146 
    147     nub_thread_t    GetCurrentThread () const
    148                     {
    149                         if (m_thread == 0 || m_thread == -1)
    150                             return DNBProcessGetCurrentThread (m_ctx.ProcessID());
    151                         return m_thread;
    152                     }
    153 
    154     void            SetCurrentThread (nub_thread_t tid)
    155                     {
    156                         DNBProcessSetCurrentThread (m_ctx.ProcessID(), tid);
    157                         m_thread = tid;
    158                     }
    159 
    160     static void*    ThreadFunctionReadRemoteData(void *arg);
    161     void            StartReadRemoteDataThread ();
    162     void            StopReadRemoteDataThread ();
    163 
    164     void NotifyThatProcessStopped (void);
    165 
    166     rnb_err_t HandlePacket_A (const char *p);
    167     rnb_err_t HandlePacket_H (const char *p);
    168     rnb_err_t HandlePacket_qC (const char *p);
    169     rnb_err_t HandlePacket_qRcmd (const char *p);
    170     rnb_err_t HandlePacket_qGetPid (const char *p);
    171     rnb_err_t HandlePacket_qLaunchSuccess (const char *p);
    172     rnb_err_t HandlePacket_qRegisterInfo (const char *p);
    173     rnb_err_t HandlePacket_qShlibInfoAddr (const char *p);
    174     rnb_err_t HandlePacket_qStepPacketSupported (const char *p);
    175     rnb_err_t HandlePacket_qVAttachOrWaitSupported (const char *p);
    176     rnb_err_t HandlePacket_qSyncThreadStateSupported (const char *p);
    177     rnb_err_t HandlePacket_qThreadInfo (const char *p);
    178     rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
    179     rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
    180     rnb_err_t HandlePacket_qHostInfo (const char *p);
    181     rnb_err_t HandlePacket_qProcessInfo (const char *p);
    182     rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
    183     rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
    184     rnb_err_t HandlePacket_QSetLogging (const char *p);
    185     rnb_err_t HandlePacket_QSetDisableASLR (const char *p);
    186     rnb_err_t HandlePacket_QSetSTDIO (const char *p);
    187     rnb_err_t HandlePacket_QSetWorkingDir (const char *p);
    188     rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p);
    189     rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p);
    190     rnb_err_t HandlePacket_QEnvironment (const char *p);
    191     rnb_err_t HandlePacket_QEnvironmentHexEncoded (const char *p);
    192     rnb_err_t HandlePacket_QLaunchArch (const char *p);
    193     rnb_err_t HandlePacket_QListThreadsInStopReply (const char *p);
    194     rnb_err_t HandlePacket_QSyncThreadState (const char *p);
    195     rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
    196     rnb_err_t HandlePacket_last_signal (const char *p);
    197     rnb_err_t HandlePacket_m (const char *p);
    198     rnb_err_t HandlePacket_M (const char *p);
    199     rnb_err_t HandlePacket_X (const char *p);
    200     rnb_err_t HandlePacket_g (const char *p);
    201     rnb_err_t HandlePacket_G (const char *p);
    202     rnb_err_t HandlePacket_z (const char *p);
    203     rnb_err_t HandlePacket_T (const char *p);
    204     rnb_err_t HandlePacket_p (const char *p);
    205     rnb_err_t HandlePacket_P (const char *p);
    206     rnb_err_t HandlePacket_c (const char *p);
    207     rnb_err_t HandlePacket_C (const char *p);
    208     rnb_err_t HandlePacket_D (const char *p);
    209     rnb_err_t HandlePacket_k (const char *p);
    210     rnb_err_t HandlePacket_s (const char *p);
    211     rnb_err_t HandlePacket_S (const char *p);
    212     rnb_err_t HandlePacket_v (const char *p);
    213     rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p);
    214     rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description);
    215     rnb_err_t HandlePacket_AllocateMemory (const char *p);
    216     rnb_err_t HandlePacket_DeallocateMemory (const char *p);
    217     rnb_err_t HandlePacket_MemoryRegionInfo (const char *p);
    218     rnb_err_t HandlePacket_GetProfileData(const char *p);
    219     rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
    220     rnb_err_t HandlePacket_WatchpointSupportInfo (const char *p);
    221 
    222     rnb_err_t HandlePacket_stop_process (const char *p);
    223 
    224     rnb_err_t SendStopReplyPacketForThread (nub_thread_t tid);
    225     rnb_err_t SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer);
    226     rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size);
    227     rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size);
    228     void      FlushSTDIO ();
    229     void      SendAsyncProfileData ();
    230     rnb_err_t SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size);
    231 
    232     RNBContext&     Context() { return m_ctx; }
    233     RNBSocket&      Comm() { return m_comm; }
    234 
    235     void
    236     SetUseNativeRegisters (bool b)
    237     {
    238         m_use_native_regs = b;
    239     }
    240 private:
    241     // Outlaw some contructors
    242     RNBRemote (const RNBRemote &);
    243 
    244 protected:
    245 
    246     rnb_err_t GetCommData ();
    247     void CommDataReceived(const std::string& data);
    248     struct Packet
    249     {
    250         typedef std::vector<Packet>         collection;
    251         typedef collection::iterator        iterator;
    252         typedef collection::const_iterator  const_iterator;
    253         PacketEnum type;
    254         HandlePacketCallback normal;    // Function to call when inferior is halted
    255         HandlePacketCallback async;     // Function to call when inferior is running
    256         std::string abbrev;
    257         std::string printable_name;
    258 
    259         bool
    260         IsPlatformPacket () const
    261         {
    262             switch (type)
    263             {
    264             case set_logging_mode:
    265             case query_host_info:
    266                 return true;
    267             default:
    268                     break;
    269             }
    270             return false;
    271         }
    272         Packet() :
    273             type(invalid_packet),
    274             normal (NULL),
    275             async (NULL),
    276             abbrev (),
    277             printable_name ()
    278         {
    279         }
    280 
    281         Packet( PacketEnum in_type,
    282                 HandlePacketCallback in_normal,
    283                 HandlePacketCallback in_async,
    284                 const char *in_abbrev,
    285                 const char *in_printable_name) :
    286             type    (in_type),
    287             normal  (in_normal),
    288             async   (in_async),
    289             abbrev  (in_abbrev),
    290             printable_name (in_printable_name)
    291         {
    292         }
    293     };
    294 
    295     rnb_err_t       GetPacket (std::string &packet_data, RNBRemote::Packet& packet_info, bool wait);
    296     rnb_err_t       SendPacket (const std::string &);
    297 
    298     void CreatePacketTable ();
    299     rnb_err_t GetPacketPayload (std::string &);
    300 
    301     nub_thread_t
    302     ExtractThreadIDFromThreadSuffix (const char *p);
    303 
    304     RNBContext      m_ctx;              // process context
    305     RNBSocket       m_comm;             // communication port
    306     std::string     m_arch;
    307     nub_thread_t    m_continue_thread;  // thread to continue; 0 for any, -1 for all
    308     nub_thread_t    m_thread;           // thread for other ops; 0 for any, -1 for all
    309     PThreadMutex    m_mutex;            // Mutex that protects
    310     uint32_t        m_packets_recvd;
    311     Packet::collection m_packets;
    312     std::deque<std::string> m_rx_packets;
    313     std::string     m_rx_partial_data;  // For packets that may come in more than one batch, anything left over can be left here
    314     pthread_t       m_rx_pthread;
    315     uint32_t        m_max_payload_size;  // the maximum sized payload we should send to gdb
    316     bool            m_extended_mode;   // are we in extended mode?
    317     bool            m_noack_mode;      // are we in no-ack mode?
    318     bool            m_use_native_regs; // Use native registers by querying DNB layer for register definitions?
    319     bool            m_thread_suffix_supported; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon:
    320                                                                 // "$pRR;thread:TTTT;" instead of "$pRR"
    321                                                                 // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
    322                                                                 // "$g;thread:TTTT" instead of "$g"
    323                                                                 // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
    324     bool            m_list_threads_in_stop_reply;
    325 };
    326 
    327 /* We translate the /usr/include/mach/exception_types.h exception types
    328    (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
    329    in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS).  These hard
    330    coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
    331    values in its include/gdb/signals.h.  */
    332 
    333 #define TARGET_EXC_BAD_ACCESS      0x91
    334 #define TARGET_EXC_BAD_INSTRUCTION 0x92
    335 #define TARGET_EXC_ARITHMETIC      0x93
    336 #define TARGET_EXC_EMULATION       0x94
    337 #define TARGET_EXC_SOFTWARE        0x95
    338 #define TARGET_EXC_BREAKPOINT      0x96
    339 
    340 /* Generally speaking, you can't assume gdb can receive more than 399 bytes
    341    at a time with a random gdb.  This bufsize constant is only specifying
    342    how many bytes gdb can *receive* from debugserver -- it tells us nothing
    343    about how many bytes gdb might try to send in a single packet.  */
    344 #define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399
    345 
    346 #endif // #ifndef __RNBRemote_h__
    347