• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetContinueThread()137     nub_thread_t    GetContinueThread () const
138                     {
139                         return m_continue_thread;
140                     }
141 
SetContinueThread(nub_thread_t tid)142     void            SetContinueThread (nub_thread_t tid)
143                     {
144                         m_continue_thread = tid;
145                     }
146 
GetCurrentThread()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 
SetCurrentThread(nub_thread_t tid)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 
Context()232     RNBContext&     Context() { return m_ctx; }
Comm()233     RNBSocket&      Comm() { return m_comm; }
234 
235     void
SetUseNativeRegisters(bool b)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
IsPlatformPacketPacket260         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         }
PacketPacket272         Packet() :
273             type(invalid_packet),
274             normal (NULL),
275             async (NULL),
276             abbrev (),
277             printable_name ()
278         {
279         }
280 
PacketPacket281         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