RNBRemote.h revision e1f50b9df1299f6b9181b5ac2699ed4a3ad38a59
127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//===-- RNBRemote.h ---------------------------------------------*- C++ -*-===//
227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//
327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//                     The LLVM Compiler Infrastructure
427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//
527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// This file is distributed under the University of Illinois Open Source
627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn// License. See LICENSE.TXT for details.
727aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//
827aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//===----------------------------------------------------------------------===//
927aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//
1027aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//  Created by Greg Clayton on 12/12/07.
1127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//
1227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn//===----------------------------------------------------------------------===//
1327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn
1427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#ifndef __RNBRemote_h__
1527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#define __RNBRemote_h__
1627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn
1727aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "RNBDefs.h"
1827aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "DNB.h"
1927aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "RNBContext.h"
2027aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "RNBSocket.h"
2127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include "PThreadMutex.h"
2227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <string>
2327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <vector>
2427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <deque>
2527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn#include <map>
2627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn
2727aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass RNBSocket;
2827aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass RNBContext;
2927aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass PThreadEvents;
3027aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn
3127aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornenum event_loop_mode { debug_nub, gdb_remote_protocol, done };
3227aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn
3327aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornclass RNBRemote
3427aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn{
3527aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackbornpublic:
3627aea04b07c1fafa0f815aa4f80374a9e051b41cDianne Hackborn
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        vattachname,                    // 'vAttachName:XX...' where XX is one or more hex encoded process name ASCII bytes
67        vcont,                          // 'vCont'
68        vcont_list_actions,             // 'vCont?'
69        write_data_to_memory,           // 'X'
70        insert_mem_bp,                  // 'Z0'
71        remove_mem_bp,                  // 'z0'
72        insert_hardware_bp,             // 'Z1'
73        remove_hardware_bp,             // 'z1'
74        insert_write_watch_bp,          // 'Z2'
75        remove_write_watch_bp,          // 'z2'
76        insert_read_watch_bp,           // 'Z3'
77        remove_read_watch_bp,           // 'z3'
78        insert_access_watch_bp,         // 'Z4'
79        remove_access_watch_bp,         // 'z4'
80
81        query_current_thread_id,        // 'qC'
82        query_memory_crc,               // 'qCRC:'
83        query_thread_ids_first,         // 'qfThreadInfo'
84        query_thread_ids_subsequent,    // 'qsThreadInfo'
85        query_thread_extra_info,        // 'qThreadExtraInfo'
86        query_thread_stop_info,         // 'qThreadStopInfo'
87        query_image_offsets,            // 'qOffsets'
88        query_symbol_lookup,            // 'gSymbols'
89        query_launch_success,           // 'qLaunchSuccess'
90        query_register_info,            // 'qRegisterInfo'
91        query_shlib_notify_info_addr,   // 'qShlibInfoAddr'
92        query_step_packet_supported,    // 'qStepPacketSupported'
93        query_host_info,                // 'qHostInfo'
94        pass_signals_to_inferior,       // 'QPassSignals'
95        start_noack_mode,               // 'QStartNoAckMode'
96        prefix_reg_packets_with_tid,    // 'QPrefixRegisterPacketsWithThreadID
97        set_logging_mode,               // 'QSetLogging:'
98        set_max_packet_size,            // 'QSetMaxPacketSize:'
99        set_max_payload_size,           // 'QSetMaxPayloadSize:'
100        set_environment_variable,       // 'QEnvironment:'
101        set_disable_aslr,               // 'QSetDisableASLR:'
102        set_stdin,                      // 'QSetSTDIN:'
103        set_stdout,                     // 'QSetSTDOUT:'
104        set_stderr,                     // 'QSetSTDERR:'
105        set_working_dir,                // 'QSetWorkingDir:'
106        allocate_memory,                // '_M'
107        deallocate_memory,              // '_m'
108
109        unknown_type,
110    } PacketEnum;
111
112    typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
113
114    RNBRemote ();
115    ~RNBRemote ();
116
117    void            Initialize();
118
119    bool            InitializeRegisters ();
120
121    rnb_err_t       HandleAsyncPacket(PacketEnum *type = NULL);
122    rnb_err_t       HandleReceivedPacket(PacketEnum *type = NULL);
123
124    nub_thread_t    GetContinueThread () const
125                    {
126                        return m_continue_thread;
127                    }
128
129    void            SetContinueThread (nub_thread_t tid)
130                    {
131                        m_continue_thread = tid;
132                    }
133
134    nub_thread_t    GetCurrentThread () const
135                    {
136                        if (m_thread == 0 || m_thread == -1)
137                            return DNBProcessGetCurrentThread (m_ctx.ProcessID());
138                        return m_thread;
139                    }
140
141    void            SetCurrentThread (nub_thread_t tid)
142                    {
143                        DNBProcessSetCurrentThread (m_ctx.ProcessID(), tid);
144                        m_thread = tid;
145                    }
146
147    static void*    ThreadFunctionReadRemoteData(void *arg);
148    void            StartReadRemoteDataThread ();
149    void            StopReadRemoteDataThread ();
150
151    void NotifyThatProcessStopped (void);
152
153    rnb_err_t HandlePacket_A (const char *p);
154    rnb_err_t HandlePacket_H (const char *p);
155    rnb_err_t HandlePacket_qC (const char *p);
156    rnb_err_t HandlePacket_qLaunchSuccess (const char *p);
157    rnb_err_t HandlePacket_qRegisterInfo (const char *p);
158    rnb_err_t HandlePacket_qShlibInfoAddr (const char *p);
159    rnb_err_t HandlePacket_qStepPacketSupported (const char *p);
160    rnb_err_t HandlePacket_qThreadInfo (const char *p);
161    rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
162    rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
163    rnb_err_t HandlePacket_qHostInfo (const char *p);
164    rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
165    rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
166    rnb_err_t HandlePacket_QSetLogging (const char *p);
167    rnb_err_t HandlePacket_QSetDisableASLR (const char *p);
168    rnb_err_t HandlePacket_QSetSTDIO (const char *p);
169    rnb_err_t HandlePacket_QSetWorkingDir (const char *p);
170    rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p);
171    rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p);
172    rnb_err_t HandlePacket_QEnvironment (const char *p);
173    rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
174    rnb_err_t HandlePacket_last_signal (const char *p);
175    rnb_err_t HandlePacket_m (const char *p);
176    rnb_err_t HandlePacket_M (const char *p);
177    rnb_err_t HandlePacket_X (const char *p);
178    rnb_err_t HandlePacket_g (const char *p);
179    rnb_err_t HandlePacket_G (const char *p);
180    rnb_err_t HandlePacket_z (const char *p);
181    rnb_err_t HandlePacket_T (const char *p);
182    rnb_err_t HandlePacket_p (const char *p);
183    rnb_err_t HandlePacket_P (const char *p);
184    rnb_err_t HandlePacket_c (const char *p);
185    rnb_err_t HandlePacket_C (const char *p);
186    rnb_err_t HandlePacket_D (const char *p);
187    rnb_err_t HandlePacket_k (const char *p);
188    rnb_err_t HandlePacket_s (const char *p);
189    rnb_err_t HandlePacket_S (const char *p);
190    rnb_err_t HandlePacket_v (const char *p);
191    rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p);
192    rnb_err_t HandlePacket_ILLFORMED (const char *file, int line, const char *p, const char *description);
193    rnb_err_t HandlePacket_AllocateMemory (const char *p);
194    rnb_err_t HandlePacket_DeallocateMemory (const char *p);
195
196    rnb_err_t HandlePacket_stop_process (const char *p);
197
198    rnb_err_t SendStopReplyPacketForThread (nub_thread_t tid);
199    rnb_err_t SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer);
200    rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size);
201    rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size);
202    void      FlushSTDIO ();
203
204    RNBContext&     Context() { return m_ctx; }
205    RNBSocket&      Comm() { return m_comm; }
206
207    void
208    SetUseNativeRegisters (bool b)
209    {
210        m_use_native_regs = b;
211    }
212private:
213    // Outlaw some contructors
214    RNBRemote (const RNBRemote &);
215
216protected:
217
218    rnb_err_t GetCommData ();
219    void CommDataReceived(const std::string& data);
220    struct Packet
221    {
222        typedef std::vector<Packet>         collection;
223        typedef collection::iterator        iterator;
224        typedef collection::const_iterator  const_iterator;
225        PacketEnum type;
226        HandlePacketCallback normal;    // Function to call when inferior is halted
227        HandlePacketCallback async;     // Function to call when inferior is running
228        std::string abbrev;
229        std::string printable_name;
230
231        bool
232        IsPlatformPacket () const
233        {
234            switch (type)
235            {
236            case set_logging_mode:
237            case query_host_info:
238                return true;
239            default:
240                    break;
241            }
242            return false;
243        }
244        Packet() :
245            type(invalid_packet),
246            normal (NULL),
247            async (NULL),
248            abbrev (),
249            printable_name ()
250        {
251        }
252
253        Packet( PacketEnum in_type,
254                HandlePacketCallback in_normal,
255                HandlePacketCallback in_async,
256                const char *in_abbrev,
257                const char *in_printable_name) :
258            type    (in_type),
259            normal  (in_normal),
260            async   (in_async),
261            abbrev  (in_abbrev),
262            printable_name (in_printable_name)
263        {
264        }
265    };
266
267    rnb_err_t       GetPacket (std::string &packet_data, RNBRemote::Packet& packet_info, bool wait);
268    rnb_err_t       SendPacket (const std::string &);
269
270    void CreatePacketTable ();
271    rnb_err_t GetPacketPayload (std::string &);
272
273    nub_thread_t
274    ExtractThreadIDFromThreadSuffix (const char *p);
275
276    // gdb can send multiple Z/z packets for the same address and
277    // these calls must be ref counted.
278    struct Breakpoint
279    {
280        Breakpoint(nub_break_t breakID) :
281            m_breakID(breakID),
282            m_refCount(1)
283        {
284        }
285
286        Breakpoint() :
287            m_breakID(INVALID_NUB_BREAK_ID),
288            m_refCount(0)
289        {
290        }
291
292        Breakpoint(const Breakpoint& rhs) :
293            m_breakID(rhs.m_breakID),
294            m_refCount(rhs.m_refCount)
295        {
296        }
297
298        nub_break_t BreakID() const { return m_breakID; }
299        uint32_t RefCount() const { return m_refCount; }
300        void Release() { if (m_refCount > 0) --m_refCount; }
301        void Retain() { ++m_refCount; }
302
303        nub_break_t m_breakID;
304        uint32_t m_refCount;
305    };
306    typedef std::map<nub_addr_t, Breakpoint> BreakpointMap;
307    typedef BreakpointMap::iterator          BreakpointMapIter;
308    typedef BreakpointMap::const_iterator    BreakpointMapConstIter;
309    RNBContext      m_ctx;              // process context
310    RNBSocket       m_comm;             // communication port
311    std::string     m_arch;
312    nub_thread_t    m_continue_thread;  // thread to continue; 0 for any, -1 for all
313    nub_thread_t    m_thread;           // thread for other ops; 0 for any, -1 for all
314    PThreadMutex    m_mutex;            // Mutex that protects
315    uint32_t        m_packets_recvd;
316    Packet::collection m_packets;
317    std::deque<std::string> m_rx_packets;
318    std::string     m_rx_partial_data;  // For packets that may come in more than one batch, anything left over can be left here
319    pthread_t       m_rx_pthread;
320    BreakpointMap   m_breakpoints;
321    BreakpointMap   m_watchpoints;
322    uint32_t        m_max_payload_size;  // the maximum sized payload we should send to gdb
323    bool            m_extended_mode:1,   // are we in extended mode?
324                    m_noack_mode:1,      // are we in no-ack mode?
325                    m_noack_mode_just_enabled:1, // Did we just enable this and need to compute one more checksum?
326                    m_use_native_regs:1, // Use native registers by querying DNB layer for register definitions?
327                    m_thread_suffix_supported:1; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon:
328                                                                // "$pRR;thread:TTTT;" instead of "$pRR"
329                                                                // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
330                                                                // "$g;thread:TTTT" instead of "$g"
331                                                                // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
332};
333
334/* We translate the /usr/include/mach/exception_types.h exception types
335   (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
336   in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS).  These hard
337   coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
338   values in its include/gdb/signals.h.  */
339
340#define TARGET_EXC_BAD_ACCESS      0x91
341#define TARGET_EXC_BAD_INSTRUCTION 0x92
342#define TARGET_EXC_ARITHMETIC      0x93
343#define TARGET_EXC_EMULATION       0x94
344#define TARGET_EXC_SOFTWARE        0x95
345#define TARGET_EXC_BREAKPOINT      0x96
346
347/* Generally speaking, you can't assume gdb can receive more than 399 bytes
348   at a time with a random gdb.  This bufsize constant is only specifying
349   how many bytes gdb can *receive* from debugserver -- it tells us nothing
350   about how many bytes gdb might try to send in a single packet.  */
351#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399
352
353#endif // #ifndef __RNBRemote_h__
354