blob: 30ab7e67302cf79dcadb032b9c7cb71afaf8dfc1 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
27class RNBSocket;
28class RNBContext;
29class PThreadEvents;
30
31enum event_loop_mode { debug_nub, gdb_remote_protocol, done };
32
33class RNBRemote
34{
35public:
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'
Greg Claytonc1d37752010-10-18 01:45:30 +000064 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
Chris Lattner24943d22010-06-08 16:52:24 +000067 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 set_logging_mode, // 'QSetLogging:'
97 set_max_packet_size, // 'QSetMaxPacketSize:'
98 set_max_payload_size, // 'QSetMaxPayloadSize:'
99 set_environment_variable, // 'QEnvironment:'
Greg Clayton0a7f75f2010-09-09 06:32:46 +0000100 set_disable_aslr, // 'QSetDisableASLR:'
Chris Lattner24943d22010-06-08 16:52:24 +0000101 allocate_memory, // '_M'
102 deallocate_memory, // '_m'
103
104 unknown_type,
105 } PacketEnum;
106
107 typedef rnb_err_t (RNBRemote::*HandlePacketCallback)(const char *p);
108
109 RNBRemote(bool use_native_regs);
110 ~RNBRemote();
111
112 static void InitializeRegisters (int use_native);
113
114 rnb_err_t HandleAsyncPacket(PacketEnum *type = NULL);
115 rnb_err_t HandleReceivedPacket(PacketEnum *type = NULL);
116
117 nub_thread_t GetContinueThread () const
118 {
119 return m_continue_thread;
120 }
121
122 void SetContinueThread (nub_thread_t tid)
123 {
124 m_continue_thread = tid;
125 }
126
127 nub_thread_t GetCurrentThread () const
128 {
129 if (m_thread == 0 || m_thread == -1)
130 return DNBProcessGetCurrentThread (m_ctx.ProcessID());
131 return m_thread;
132 }
133
134 void SetCurrentThread (nub_thread_t tid)
135 {
136 DNBProcessSetCurrentThread (m_ctx.ProcessID(), tid);
137 m_thread = tid;
138 }
139
140 static void* ThreadFunctionReadRemoteData(void *arg);
141 void StartReadRemoteDataThread ();
142 void StopReadRemoteDataThread ();
143
144 void NotifyThatProcessStopped (void);
145
146 rnb_err_t HandlePacket_A (const char *p);
147 rnb_err_t HandlePacket_H (const char *p);
148 rnb_err_t HandlePacket_qC (const char *p);
149 rnb_err_t HandlePacket_qLaunchSuccess (const char *p);
150 rnb_err_t HandlePacket_qRegisterInfo (const char *p);
151 rnb_err_t HandlePacket_qShlibInfoAddr (const char *p);
152 rnb_err_t HandlePacket_qStepPacketSupported (const char *p);
153 rnb_err_t HandlePacket_qThreadInfo (const char *p);
154 rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
155 rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
156 rnb_err_t HandlePacket_qHostInfo (const char *p);
157 rnb_err_t HandlePacket_Q (const char *p);
158 rnb_err_t HandlePacket_last_signal (const char *p);
159 rnb_err_t HandlePacket_m (const char *p);
160 rnb_err_t HandlePacket_M (const char *p);
161 rnb_err_t HandlePacket_X (const char *p);
162 rnb_err_t HandlePacket_g (const char *p);
163 rnb_err_t HandlePacket_G (const char *p);
164 rnb_err_t HandlePacket_z (const char *p);
165 rnb_err_t HandlePacket_T (const char *p);
166 rnb_err_t HandlePacket_p (const char *p);
167 rnb_err_t HandlePacket_P (const char *p);
168 rnb_err_t HandlePacket_c (const char *p);
169 rnb_err_t HandlePacket_C (const char *p);
170 rnb_err_t HandlePacket_D (const char *p);
171 rnb_err_t HandlePacket_k (const char *p);
172 rnb_err_t HandlePacket_s (const char *p);
173 rnb_err_t HandlePacket_S (const char *p);
174 rnb_err_t HandlePacket_v (const char *p);
175 rnb_err_t HandlePacket_UNIMPLEMENTED (const char *p);
176 rnb_err_t HandlePacket_ILLFORMED (const char *description);
177 rnb_err_t HandlePacket_AllocateMemory (const char *p);
178 rnb_err_t HandlePacket_DeallocateMemory (const char *p);
179
180 rnb_err_t HandlePacket_stop_process (const char *p);
181
182 rnb_err_t SendStopReplyPacketForThread (nub_thread_t tid);
183 rnb_err_t SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer);
184 rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size);
185 rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size);
186 void FlushSTDIO ();
187
188 RNBContext& Context() { return m_ctx; }
189 RNBSocket& Comm() { return m_comm; }
190
191private:
192 // Outlaw some contructors
193 RNBRemote (const RNBRemote &);
194
195protected:
196
197 static void
198 InitializeNativeRegisters ();
199
200 rnb_err_t GetCommData ();
201 void CommDataReceived(const std::string& data);
202 struct Packet
203 {
204 typedef std::vector<Packet> collection;
205 typedef collection::iterator iterator;
206 typedef collection::const_iterator const_iterator;
207 PacketEnum type;
208 HandlePacketCallback normal; // Function to call when inferior is halted
209 HandlePacketCallback async; // Function to call when inferior is running
210 std::string abbrev;
211 std::string printable_name;
212 Packet() :
213 type(invalid_packet),
214 normal (NULL),
215 async (NULL),
216 abbrev (),
217 printable_name ()
218 {
219 }
220
221 Packet( PacketEnum in_type,
222 HandlePacketCallback in_normal,
223 HandlePacketCallback in_async,
224 const char *in_abbrev,
225 const char *in_printable_name) :
226 type (in_type),
227 normal (in_normal),
228 async (in_async),
229 abbrev (in_abbrev),
230 printable_name (in_printable_name)
231 {
232 }
233 };
234
235 rnb_err_t GetPacket (std::string &packet_data, RNBRemote::Packet& packet_info, bool wait);
236 rnb_err_t SendPacket (const std::string &);
237
238 void CreatePacketTable ();
239 rnb_err_t GetPacketPayload (std::string &);
240
241 // gdb can send multiple Z/z packets for the same address and
242 // these calls must be ref counted.
Johnny Chenfa150242010-09-28 16:34:56 +0000243 struct Breakpoint
Chris Lattner24943d22010-06-08 16:52:24 +0000244 {
245 Breakpoint(nub_break_t breakID) :
246 m_breakID(breakID),
247 m_refCount(1)
248 {
249 }
250
251 Breakpoint() :
252 m_breakID(INVALID_NUB_BREAK_ID),
253 m_refCount(0)
254 {
255 }
256
257 Breakpoint(const Breakpoint& rhs) :
258 m_breakID(rhs.m_breakID),
259 m_refCount(rhs.m_refCount)
260 {
261 }
262
263 nub_break_t BreakID() const { return m_breakID; }
264 uint32_t RefCount() const { return m_refCount; }
265 void Release() { if (m_refCount > 0) --m_refCount; }
266 void Retain() { ++m_refCount; }
267
268 nub_break_t m_breakID;
269 uint32_t m_refCount;
270 };
271 typedef std::map<nub_addr_t, Breakpoint> BreakpointMap;
272 typedef BreakpointMap::iterator BreakpointMapIter;
273 typedef BreakpointMap::const_iterator BreakpointMapConstIter;
274 RNBContext m_ctx; // process context
275 RNBSocket m_comm; // communication port
276 bool m_extended_mode; // are we in extended mode?
277 bool m_noack_mode; // are we in no-ack mode?
278 nub_thread_t m_continue_thread; // thread to continue; 0 for any, -1 for all
279 nub_thread_t m_thread; // thread for other ops; 0 for any, -1 for all
280 PThreadMutex m_mutex; // Mutex that protects
281 uint32_t m_packets_recvd;
282 Packet::collection m_packets;
283 std::deque<std::string> m_rx_packets;
284 std::string m_rx_partial_data; // For packets that may come in more than one batch, anything left over can be left here
285 pthread_t m_rx_pthread;
286 BreakpointMap m_breakpoints;
287 BreakpointMap m_watchpoints;
288 uint32_t m_max_payload_size; // the maximum sized payload we should send to gdb
289 bool m_use_native_regs;
290};
291
292/* We translate the /usr/include/mach/exception_types.h exception types
293 (e.g. EXC_BAD_ACCESS) to the fake BSD signal numbers that gdb uses
294 in include/gdb/signals.h (e.g. TARGET_EXC_BAD_ACCESS). These hard
295 coded values for TARGET_EXC_BAD_ACCESS et al must match the gdb
296 values in its include/gdb/signals.h. */
297
298#define TARGET_EXC_BAD_ACCESS 0x91
299#define TARGET_EXC_BAD_INSTRUCTION 0x92
300#define TARGET_EXC_ARITHMETIC 0x93
301#define TARGET_EXC_EMULATION 0x94
302#define TARGET_EXC_SOFTWARE 0x95
303#define TARGET_EXC_BREAKPOINT 0x96
304
305/* Generally speaking, you can't assume gdb can receive more than 399 bytes
306 at a time with a random gdb. This bufsize constant is only specifying
307 how many bytes gdb can *receive* from debugserver -- it tells us nothing
308 about how many bytes gdb might try to send in a single packet. */
309#define DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE 399
310
311#endif // #ifndef __RNBRemote_h__