OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef DEBUGGER_RSP_RSP_PACKET_H_ | |
6 #define DEBUGGER_RSP_RSP_PACKET_H_ | |
7 | |
8 #include <string> | |
9 #include <vector> | |
10 #include <deque> | |
11 #include <map> | |
12 #include "debugger/base/debug_blob.h" | |
13 | |
14 namespace rsp { | |
15 class PacketVisitor; | |
16 class EmptyPacket; | |
17 class QuerySupportedCommand; | |
18 class QuerySupportedReply; | |
19 class GetStopReasonCommand; | |
20 class StopReply; | |
21 class ReadMemoryCommand; | |
22 class WriteMemoryCommand; | |
23 class BlobReply; | |
24 class ReadRegistersCommand; | |
25 class WriteRegistersCommand; | |
26 class ErrorReply; | |
27 class OkReply; | |
28 class SetCurrentThreadCommand; | |
29 class GetCurrentThreadCommand; | |
30 class GetCurrentThreadReply; | |
31 class ContinueCommand; | |
32 class StepCommand; | |
33 class IsThreadAliveCommand; | |
34 class QXferFeaturesReadCommand; | |
35 class QXferReply; | |
36 class GetThreadInfoCommand; | |
37 class GetThreadInfoReply; | |
38 | |
39 class Packet { | |
40 public: | |
41 Packet() {} | |
42 virtual ~Packet() {} | |
43 | |
44 /// Creates a new object on the heap. | |
45 /// Shall be overwritten by descendants. | |
46 /// Used by |factory_| in the |CreateFromBlob| method. | |
47 virtual Packet* Create() const {return new Packet;} | |
48 | |
49 /// Shall be overwritten in descendants. | |
50 virtual void ToBlob(debug::Blob* message) const {} | |
51 | |
52 /// Shall be overwritten in descendants. | |
53 virtual bool FromBlob(const std::string& type, | |
54 debug::Blob* message) {return true;} | |
55 | |
56 /// Shall be overwritten in descendants. | |
57 virtual void AcceptVisitor(PacketVisitor* vis) {} | |
58 | |
59 static Packet* CreateFromBlob(debug::Blob* message, | |
60 const char* type_hint = NULL); | |
61 | |
62 protected: | |
63 }; | |
64 | |
65 class PacketVisitor { | |
66 public: | |
67 ~PacketVisitor() {} | |
68 | |
69 virtual void Visit(EmptyPacket* packet) {} | |
70 virtual void Visit(QuerySupportedCommand* packet) {} | |
71 virtual void Visit(QuerySupportedReply* packet) {} | |
72 virtual void Visit(GetStopReasonCommand* packet) {} | |
73 virtual void Visit(StopReply* packet) {} | |
74 virtual void Visit(ReadMemoryCommand* packet) {} | |
75 virtual void Visit(WriteMemoryCommand* packet) {} | |
76 virtual void Visit(BlobReply* packet) {} | |
77 virtual void Visit(ReadRegistersCommand* packet) {} | |
78 virtual void Visit(WriteRegistersCommand* packet) {} | |
79 virtual void Visit(ErrorReply* packet) {} | |
80 virtual void Visit(OkReply* packet) {} | |
81 virtual void Visit(SetCurrentThreadCommand* packet) {} | |
82 virtual void Visit(GetCurrentThreadCommand* packet) {} | |
83 virtual void Visit(GetCurrentThreadReply* packet) {} | |
84 virtual void Visit(ContinueCommand* packet) {} | |
85 virtual void Visit(StepCommand* packet) {} | |
86 virtual void Visit(IsThreadAliveCommand* packet) {} | |
87 virtual void Visit(QXferFeaturesReadCommand* packet) {} | |
88 virtual void Visit(QXferReply* packet) {} | |
89 virtual void Visit(GetThreadInfoCommand* packet) {} | |
90 virtual void Visit(GetThreadInfoReply* packet) {} | |
91 }; | |
92 | |
93 class TypingPacketVisitor : public PacketVisitor { | |
94 public: | |
95 TypingPacketVisitor() : type_(0) {} | |
96 | |
97 virtual void Visit(EmptyPacket* packet) { type_ = 1;} | |
98 virtual void Visit(QuerySupportedCommand* packet) { type_ = 2;} | |
99 virtual void Visit(QuerySupportedReply* packet) { type_ = 3;} | |
100 virtual void Visit(GetStopReasonCommand* packet) { type_ = 4;} | |
101 virtual void Visit(StopReply* packet) { type_ = 5;} | |
102 virtual void Visit(ReadMemoryCommand* packet) { type_ = 6;} | |
103 virtual void Visit(WriteMemoryCommand* packet) { type_ = 7;} | |
104 virtual void Visit(BlobReply* packet) { type_ = 8;} | |
105 virtual void Visit(ReadRegistersCommand* packet) { type_ = 9;} | |
106 virtual void Visit(WriteRegistersCommand* packet) { type_ = 10;} | |
107 virtual void Visit(ErrorReply* packet) { type_ = 11;} | |
108 virtual void Visit(OkReply* packet) { type_ = 12;} | |
109 virtual void Visit(SetCurrentThreadCommand* packet) { type_ = 13;} | |
110 virtual void Visit(GetCurrentThreadCommand* packet) { type_ = 14;} | |
111 virtual void Visit(GetCurrentThreadReply* packet) { type_ = 15;} | |
112 virtual void Visit(ContinueCommand* packet) { type_ = 16;} | |
113 virtual void Visit(StepCommand* packet) { type_ = 17;} | |
114 virtual void Visit(IsThreadAliveCommand* packet) { type_ = 18;} | |
115 virtual void Visit(QXferFeaturesReadCommand* packet) { type_ = 19;} | |
116 virtual void Visit(QXferReply* packet) { type_ = 20;} | |
117 virtual void Visit(GetThreadInfoCommand* packet) { type_ = 21;} | |
118 virtual void Visit(GetThreadInfoReply* packet) { type_ = 22;} | |
119 | |
120 int type_; | |
121 }; | |
122 | |
123 template <class T> | |
124 T* packet_cast(Packet* obj) { | |
125 if (NULL == obj) | |
126 return NULL; | |
127 | |
128 TypingPacketVisitor vis; | |
129 obj->AcceptVisitor(&vis); | |
130 int obj_type = vis.type_; | |
131 | |
132 T tmp; | |
133 tmp.AcceptVisitor(&vis); | |
134 int t_type = vis.type_; | |
135 | |
136 if (t_type == obj_type) | |
137 return reinterpret_cast<T*>(obj); | |
138 return NULL; | |
139 } | |
140 | |
141 class EmptyPacket : public Packet { | |
142 public: | |
143 EmptyPacket() {} | |
144 | |
145 virtual void AcceptVisitor(PacketVisitor* vis); | |
146 virtual Packet* Create() const; | |
147 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
148 virtual void ToBlob(debug::Blob* message) const; | |
149 }; | |
150 | |
151 class QuerySupportedCommand : public Packet { | |
152 public: | |
153 QuerySupportedCommand() {} | |
154 | |
155 virtual Packet* Create() const; | |
156 virtual void AcceptVisitor(PacketVisitor* vis); | |
157 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
158 virtual void ToBlob(debug::Blob* message) const; | |
159 | |
160 void AddFeature(const std::string& name, const std::string& value); | |
161 void SaveFeaturesToBlob(debug::Blob* message) const; | |
162 | |
163 size_t GetFeaturesNum() const; | |
164 std::string GetFeatureName(size_t pos) const; | |
165 std::string GetFeature(const std::string& name) const; | |
166 | |
167 protected: | |
168 std::deque<std::pair<std::string, std::string>> features_; | |
169 }; | |
170 | |
171 class QuerySupportedReply : public QuerySupportedCommand { | |
172 public: | |
173 QuerySupportedReply() {} | |
174 | |
175 virtual Packet* Create() const; | |
176 virtual void AcceptVisitor(PacketVisitor* vis); | |
177 virtual void ToBlob(debug::Blob* message) const; | |
178 }; | |
179 | |
180 // Abstract class - base for packets types: 'g', '?', 'qC', 's' etc. | |
181 class OneWordPacket : public Packet { | |
182 public: | |
183 OneWordPacket(const std::string& word) : word_(word) {} | |
184 | |
185 virtual Packet* Create() const = 0; | |
186 virtual bool FromBlob(const std::string& type, debug::Blob* message) { | |
187 return true; | |
188 } | |
189 virtual void ToBlob(debug::Blob* message) const { | |
190 *message = word_; | |
191 } | |
192 | |
193 protected: | |
194 std::string word_; | |
195 }; | |
196 | |
197 // Abstract class - base for packets types: | |
198 class WordWithIntPacket : public Packet { | |
199 public: | |
200 WordWithIntPacket(const std::string& word) : word_(word) {} | |
201 | |
202 virtual Packet* Create() const = 0; | |
203 virtual bool FromBlob(const std::string& type, debug::Blob* message) { | |
204 value_ = message->PopInt32FromFront(); | |
205 return true; | |
206 } | |
207 virtual void ToBlob(debug::Blob* message) const { | |
208 message->Format("%s%x", word_.c_str(), value_); | |
209 } | |
210 u_int32_t value() const { return value_; } | |
211 void set_value(u_int32_t x) { value_ = x; } | |
212 | |
213 protected: | |
214 std::string word_; | |
215 u_int32_t value_; | |
216 }; | |
217 | |
218 class GetStopReasonCommand : public OneWordPacket { | |
219 public: | |
220 GetStopReasonCommand() : OneWordPacket("?") {} | |
221 virtual Packet* Create() const { return new GetStopReasonCommand; } | |
222 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
223 }; | |
224 | |
225 class StopReply : public Packet { | |
226 public: | |
227 enum StopReason {SIGNALED, TERMINATED, EXITED, STILL_RUNNING}; | |
228 | |
229 StopReply(); | |
230 StopReply(StopReason stop_reason); | |
231 | |
232 virtual Packet* Create() const; | |
233 virtual void AcceptVisitor(PacketVisitor* vis); | |
234 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
235 virtual void ToBlob(debug::Blob* message) const; | |
236 | |
237 StopReason stop_reason() const { return stop_reason_; } | |
238 int signal_number() const { return signal_number_; } | |
239 int exit_code() const { return exit_code_; } | |
240 u_int32_t pid() const { return pid_; } | |
241 | |
242 void set_stop_reason(StopReason x) { stop_reason_ = x; } | |
243 void set_signal_number(int x) { signal_number_ = x; } | |
244 void set_exit_code(int x) { exit_code_ = x; } | |
245 void set_pid(u_int32_t x) { pid_ = x; } | |
246 | |
247 public: | |
248 StopReason stop_reason_; | |
249 int signal_number_; | |
250 int exit_code_; | |
251 u_int32_t pid_; | |
252 }; | |
253 | |
254 class ReadMemoryCommand : public Packet { | |
255 public: | |
256 ReadMemoryCommand(); | |
257 | |
258 virtual Packet* Create() const; | |
259 virtual void AcceptVisitor(PacketVisitor* vis); | |
260 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
261 virtual void ToBlob(debug::Blob* message) const; | |
262 | |
263 u_int64_t addr() const { return addr_; } | |
264 int num_of_bytes() const { return num_of_bytes_; } | |
265 | |
266 void set_addr(u_int64_t ptr) { addr_ = ptr; } | |
267 void set_num_of_bytes(int x) { num_of_bytes_ = x; } | |
268 | |
269 protected: | |
270 u_int64_t addr_; | |
271 int num_of_bytes_; | |
272 }; | |
273 | |
274 class WriteMemoryCommand : public Packet { | |
275 public: | |
276 WriteMemoryCommand(); | |
277 | |
278 virtual Packet* Create() const; | |
279 virtual void AcceptVisitor(PacketVisitor* vis); | |
280 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
281 virtual void ToBlob(debug::Blob* message) const; | |
282 | |
283 u_int64_t addr() const { return addr_; } | |
284 const debug::Blob& data() const { return data_; } | |
285 | |
286 void set_addr(u_int64_t addr) { addr_ = addr; } | |
287 void set_data(const debug::Blob& data) { data_ = data; } | |
288 void set_data(const void* data, size_t size); | |
289 | |
290 protected: | |
291 u_int64_t addr_; | |
292 debug::Blob data_; | |
293 }; | |
294 | |
295 class BlobReply : public Packet { | |
296 public: | |
297 virtual Packet* Create() const; | |
298 virtual void AcceptVisitor(PacketVisitor* vis); | |
299 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
300 virtual void ToBlob(debug::Blob* message) const; | |
301 | |
302 const debug::Blob& data() const { return data_; } | |
303 void set_data(const debug::Blob& data) { data_ = data; } | |
304 void set_data(const void* data, size_t size) { data_ = debug::Blob(data, size);
} | |
305 | |
306 protected: | |
307 debug::Blob data_; | |
308 }; | |
309 | |
310 class ReadRegistersCommand : public OneWordPacket { | |
311 public: | |
312 ReadRegistersCommand() : OneWordPacket("g") {} | |
313 virtual Packet* Create() const { return new ReadRegistersCommand; } | |
314 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
315 }; | |
316 | |
317 class WriteRegistersCommand : public Packet { | |
318 public: | |
319 virtual Packet* Create() const { return new WriteRegistersCommand; } | |
320 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
321 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
322 virtual void ToBlob(debug::Blob* message) const; | |
323 | |
324 const debug::Blob& data() const { return data_; } | |
325 void set_data(const debug::Blob& data) { data_ = data; } | |
326 | |
327 protected: | |
328 debug::Blob data_; | |
329 }; | |
330 | |
331 /// "E02" | |
332 class ErrorReply : public Packet { | |
333 public: | |
334 ErrorReply() : error_code_(0) {} | |
335 explicit ErrorReply(int code) : error_code_(code) {} | |
336 | |
337 virtual Packet* Create() const { return new ErrorReply; } | |
338 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
339 virtual bool FromBlob(const std::string& type, debug::Blob* message) { | |
340 error_code_ = message->PopInt32FromFront(); | |
341 return true; | |
342 } | |
343 virtual void ToBlob(debug::Blob* message) const { | |
344 message->Format("E%0.2x", error_code_); | |
345 } | |
346 u_int32_t error_code() const { return error_code_; } | |
347 void set_error_code(u_int32_t x) { error_code_ = x; } | |
348 | |
349 protected: | |
350 u_int32_t error_code_; | |
351 }; | |
352 | |
353 /// "OK" | |
354 class OkReply : public OneWordPacket { | |
355 public: | |
356 OkReply() : OneWordPacket("OK") {} | |
357 virtual Packet* Create() const { return new OkReply; } | |
358 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
359 }; | |
360 | |
361 /// "Hg" or "Hc" | |
362 class SetCurrentThreadCommand : public Packet { | |
363 public: | |
364 enum Subtype {FOR_READ, FOR_CONTINUE}; | |
365 | |
366 SetCurrentThreadCommand() : subtype_(FOR_CONTINUE) {} | |
367 explicit SetCurrentThreadCommand(Subtype subtype) : subtype_(subtype) {} | |
368 virtual Packet* Create() const { return new SetCurrentThreadCommand(subtype_);
} | |
369 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
370 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
371 virtual void ToBlob(debug::Blob* message) const; | |
372 | |
373 Subtype subtype() const { return subtype_; } | |
374 void set_subtype(Subtype s) { subtype_ = s; } | |
375 u_int32_t thread_id() const { return thread_id_; } | |
376 void set_thread_id(u_int32_t id) { thread_id_ = id; } | |
377 | |
378 protected: | |
379 Subtype subtype_; | |
380 u_int32_t thread_id_; | |
381 }; | |
382 | |
383 class GetCurrentThreadCommand : public OneWordPacket { | |
384 public: | |
385 GetCurrentThreadCommand() : OneWordPacket("qC") {} | |
386 virtual Packet* Create() const { return new GetCurrentThreadCommand; } | |
387 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
388 }; | |
389 | |
390 class GetCurrentThreadReply : public WordWithIntPacket { | |
391 public: | |
392 GetCurrentThreadReply() : WordWithIntPacket("QC") {} | |
393 virtual Packet* Create() const { return new GetCurrentThreadReply; } | |
394 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
395 }; | |
396 | |
397 class ContinueCommand : public OneWordPacket { | |
398 public: | |
399 ContinueCommand() : OneWordPacket("c") {} | |
400 virtual Packet* Create() const { return new ContinueCommand; } | |
401 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
402 }; | |
403 | |
404 class StepCommand : public OneWordPacket { | |
405 public: | |
406 StepCommand() : OneWordPacket("s") {} | |
407 virtual Packet* Create() const { return new StepCommand; } | |
408 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
409 }; | |
410 | |
411 class IsThreadAliveCommand : public WordWithIntPacket { | |
412 public: | |
413 IsThreadAliveCommand() : WordWithIntPacket("T") {} | |
414 virtual Packet* Create() const { return new IsThreadAliveCommand; } | |
415 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
416 }; | |
417 | |
418 /// qXfer:features:read | |
419 /// TODO: Change to 'ReadObjectCommand' + | |
420 /// 'object' | |
421 /// 'annex' | |
422 class QXferFeaturesReadCommand : public Packet { | |
423 public: | |
424 static const char* kPrefix; | |
425 | |
426 QXferFeaturesReadCommand(); | |
427 virtual Packet* Create() const { return new QXferFeaturesReadCommand; } | |
428 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
429 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
430 virtual void ToBlob(debug::Blob* message) const; | |
431 | |
432 std::string file_name() const { return file_name_; } | |
433 u_int32_t offset() const { return offset_; } | |
434 u_int32_t length() const { return length_;} | |
435 void set_file_name(std::string name) { file_name_ = name; } | |
436 void set_offset(u_int32_t x) { offset_ = x; } | |
437 void set_length(u_int32_t x) { length_ = x; } | |
438 | |
439 protected: | |
440 std::string file_name_; | |
441 u_int32_t offset_; | |
442 u_int32_t length_; | |
443 }; | |
444 | |
445 class QXferReply : public Packet { | |
446 public: | |
447 QXferReply() : eom_(true) {} | |
448 virtual Packet* Create() const { return new QXferReply; } | |
449 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
450 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
451 virtual void ToBlob(debug::Blob* message) const; | |
452 | |
453 bool eom() const { return eom_; } | |
454 std::string body() const { return body_; } | |
455 | |
456 void set_eom(bool eom) { eom_ = eom; } | |
457 void set_body(const std::string& body) { body_ = body; } | |
458 | |
459 protected: | |
460 bool eom_; | |
461 std::string body_; | |
462 }; | |
463 | |
464 class GetThreadInfoCommand : public Packet { | |
465 public: | |
466 GetThreadInfoCommand() : get_more_(false) {} | |
467 virtual Packet* Create() const { return new GetThreadInfoCommand; } | |
468 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
469 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
470 virtual void ToBlob(debug::Blob* message) const; | |
471 | |
472 bool get_more() const { return get_more_; } | |
473 void set_get_more(bool more) { get_more_ = more; } | |
474 | |
475 private: | |
476 bool get_more_; | |
477 }; | |
478 | |
479 class GetThreadInfoReply : public Packet { | |
480 public: | |
481 GetThreadInfoReply() : eom_(true) {} | |
482 virtual Packet* Create() const { return new GetThreadInfoReply; } | |
483 virtual void AcceptVisitor(PacketVisitor* vis) { vis->Visit(this); } | |
484 virtual bool FromBlob(const std::string& type, debug::Blob* message); | |
485 virtual void ToBlob(debug::Blob* message) const; | |
486 | |
487 bool eom() const { return eom_; } | |
488 const std::deque<int>& threads_ids() const { return threads_ids_; } | |
489 | |
490 void set_eom(bool eom) { eom_ = eom; } | |
491 void set_threads_ids(const std::deque<int>& threads_ids) { | |
492 threads_ids_ = threads_ids; } | |
493 | |
494 private: | |
495 bool eom_; | |
496 std::deque<int> threads_ids_; | |
497 }; | |
498 } //namespace rsp | |
499 | |
500 #endif // DEBUGGER_RSP_RSP_PACKET_H_ | |
501 | |
OLD | NEW |