Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1096)

Side by Side Diff: experimental/windows_debugger/debugger/rsp/rsp_packet.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 #include "debugger/rsp/rsp_packet.h"
5
6 #pragma warning(disable : 4996) // Disable _snprintf warning.
7
8 namespace {
9 bool HexStringToInt(const std::string& str, int* number);
10 void RemoveSpacesFromBothEnds(std::deque<debug::Blob>* tokens);
11
12 void InitFactory();
13 std::map<std::string, rsp::Packet*> packet_factory_;
14 } // namespace
15
16 namespace rsp {
17 /// Note: this method modifies |message|.
18 /// Note: returned obj shall be deleted.
19 ///
20 /// Why |type_hint|? Because some RSP packets don't carry type field.
21 /// Examples:
22 /// 1. replies to 'm' (read memory) command:
23 /// H>[mc000202e0,12]
24 /// T>[554889e583ec204c01fc897dec8975e8c745]
25 /// => supply "blob$Reply" as a |type_hint|
26 ///
27 /// 2. replies to 'g' (read registers) command:
28 /// H>[g]
29 /// T>[00000000000000000000000000000000d85123...
30 /// => supply "blob$Reply" as a |type_hint|
31 ///
32 /// 3. replies to 'qSupported' command:
33 /// H>[qSupported:xmlRegisters=i386;qRelocInsn+]
34 /// T>[PacketSize=7cf;qXfer:libraries:read+;qXfer:features:read+]
35 /// => supply "qSupported$Reply" as a |type_hint|
36 ///
37 /// 4. replies to 'qXfer' command:
38 /// supply "qXfer$Reply" as a |type_hint|
39 ///
40 Packet* Packet::CreateFromBlob(debug::Blob* message, const char* type_hint) {
41 if (packet_factory_.size() == 0)
42 InitFactory();
43
44 // defferentiate [Xc00020304,0:] from [X05]
45 if ((message->size() > 0) && ('X' == message->Front())) {
46 if (message->size() > 3)
47 return NULL;
48 }
49
50 message->PopSpacesFromBothEnds();
51
52 // Empty message can be a reply to 'm' command, or
53 // can indicate that command is not supported.
54 if ((0 == message->size()) && (NULL == type_hint))
55 return new EmptyPacket;
56
57 std::string type;
58 bool general_query = false;
59 /*
60 if (message->size() > 0)
61 general_query = (('g' == message->Front()) || ('Q' == message->Front()));
62 if (message->HasPrefix("qC") || message->HasPrefix("QC"))
63 general_query = false;
64 */
65
66 if (NULL != type_hint) {
67 type = type_hint;
68 } else {
69 while (message->size() != 0) {
70 char c = message->Front();
71 message->PopFront();
72 if (general_query && ((0 == c) || (':' == c)))
73 break;
74 type.append(1, c);
75
76 // Commands starting from 'q' or 'Q' are 'general query', and full command
77 // name is terminated by ':' or <eom>.
78 // All other commands have no termination, i.e. they are prefixes,
79 // and they should be looked up as we scan characters. The shortest comman d
80 // to match wins.
81 if (!general_query) {
82 if (packet_factory_.find(type) != packet_factory_.end())
83 break;
84 }
85 }
86 }
87
88 Packet* packet_template = packet_factory_[type];
89 if (NULL != packet_template) {
90 Packet* packet = packet_template->Create();
91 if (NULL != packet) {
92 message->PopMatchingCharsFromFront(" :");
93 if (packet->FromBlob(type, message))
94 return packet;
95 else
96 delete packet;
97 }
98 }
99 return NULL;
100 }
101
102 //----------------------------------------------------------//
103 void EmptyPacket::AcceptVisitor(PacketVisitor* vis) {
104 vis->Visit(this);
105 }
106
107 Packet* EmptyPacket::Create() const {
108 return new EmptyPacket;
109 }
110
111 bool EmptyPacket::FromBlob(const std::string& type, debug::Blob* message) {
112 return true;
113 }
114
115 void EmptyPacket::ToBlob(debug::Blob* message) const {
116 message->Clear();
117 }
118
119 //----------------------------------------------------------//
120 Packet* QuerySupportedCommand::Create() const {
121 return new QuerySupportedCommand;
122 }
123
124 void QuerySupportedCommand::AcceptVisitor(PacketVisitor* vis) {
125 vis->Visit(this);
126 }
127
128 void QuerySupportedCommand::AddFeature(const std::string& name,
129 const std::string& value) {
130 features_.push_back(std::pair<std::string, std::string>(name, value));
131 }
132
133 bool QuerySupportedCommand::FromBlob(const std::string& type,
134 debug::Blob* message) {
135 std::deque<debug::Blob> statements;
136 message->Split(";", &statements);
137 std::deque<debug::Blob>::iterator it = statements.begin();
138 while (it != statements.end()) {
139 std::deque<debug::Blob> tokens;
140 it->Split("=", &tokens);
141 it++;
142 RemoveSpacesFromBothEnds(&tokens);
143 if (tokens.size() >= 2) {
144 AddFeature(tokens[0].ToString(), tokens[1].ToString());
145 } else if (tokens.size() > 0) {
146 debug::Blob& name = tokens[0];
147 if (name.size() > 0) {
148 char last_char = name.Back();
149 name.PopBack();
150 std::string value;
151 value.append(1, last_char);
152 AddFeature(name.ToString(), value);
153 }
154 }
155 }
156 return true;
157 }
158
159 size_t QuerySupportedCommand::GetFeaturesNum() const {
160 return features_.size();
161 }
162
163 std::string QuerySupportedCommand::GetFeatureName(size_t pos) const {
164 if (pos >= GetFeaturesNum())
165 return "";
166 return features_[pos].first;
167 }
168
169 std::string QuerySupportedCommand::GetFeature(const std::string& name) const {
170 for (size_t i = 0; i < GetFeaturesNum(); i++) {
171 if (name == GetFeatureName(i))
172 return features_[i].second;
173 }
174 return "";
175 }
176
177 void QuerySupportedCommand::SaveFeaturesToBlob(debug::Blob* message) const {
178 size_t num = features_.size();
179 for (size_t i = 0; i < num; i++ ) {
180 const std::pair<std::string, std::string>& feature = features_[i];
181 if (0 != i)
182 message->Append(";");
183 message->Append(feature.first);
184 if (("+" != feature.second) && ("-" != feature.second) && ("?" != feature.se cond))
185 message->Append("=");
186 message->Append(feature.second);
187 }
188 }
189
190 void QuerySupportedCommand::ToBlob(debug::Blob* message) const {
191 message->Append("qSupported:");
192 SaveFeaturesToBlob(message);
193 }
194
195 //----------------------------------------------------------//
196 Packet* QuerySupportedReply::Create() const {
197 return new QuerySupportedReply;
198 }
199
200 void QuerySupportedReply::AcceptVisitor(PacketVisitor* vis) {
201 vis->Visit(this);
202 }
203
204 void QuerySupportedReply::ToBlob(debug::Blob* message) const {
205 SaveFeaturesToBlob(message);
206 }
207
208 //----------------------------------------------------------//
209 StopReply::StopReply()
210 : stop_reason_(STILL_RUNNING),
211 signal_number_(0),
212 exit_code_(0),
213 pid_(0) {
214 }
215
216 StopReply :: StopReply(StopReason stop_reason)
217 : stop_reason_(stop_reason),
218 signal_number_(0),
219 exit_code_(0),
220 pid_(0) {
221 }
222
223 Packet* StopReply::Create() const {
224 return new StopReply(stop_reason_);
225 }
226
227 void StopReply::AcceptVisitor(PacketVisitor* vis) {
228 vis->Visit(this);
229 }
230
231 bool StopReply::FromBlob(const std::string& type, debug::Blob* message) {
232 if ("S" == type) {
233 stop_reason_ = SIGNALED;
234 std::string s = message->ToString();
235 signal_number_ = message->PopInt8FromFront();
236 } else if ("W" == type) {
237 stop_reason_ = StopReply::EXITED;
238 exit_code_ = message->PopInt8FromFront();
239 } else if ("X" == type) {
240 stop_reason_ = StopReply::TERMINATED;
241 signal_number_ = message->PopInt8FromFront();
242 } else if ("O" == type) {
243 stop_reason_ = StopReply::STILL_RUNNING;
244 } else {
245 return false;
246 }
247
248 if (("W" == type) || ("X" == type)) {
249 message->PopMatchingCharsFromFront(";");
250 std::deque<debug::Blob> tokens;
251 message->Split(":", &tokens);
252 if ((tokens.size() >= 2) && (tokens[0] == "process")) {
253 std::string s = tokens[1].ToString();
254 pid_ = tokens[1].PopInt32FromFront();
255 }
256 }
257
258 return true;
259 }
260
261 void StopReply::ToBlob(debug::Blob* message) const {
262 message->Clear();
263 switch (stop_reason_) {
264 case SIGNALED: {
265 message->Format("S%0.2x", signal_number_);
266 break;
267 }
268 case TERMINATED: {
269 message->Format("X%0.2x;process:%x", signal_number_, pid_);
270 break;
271 }
272 case EXITED: {
273 message->Format("W%0.2x;process:%x", exit_code_, pid_);
274 break;
275 }
276 case STILL_RUNNING: {
277 *message = "O";
278 break;
279 }
280 }
281 }
282
283 //------------------------------------------------//
284 ReadMemoryCommand::ReadMemoryCommand()
285 : addr_(0),
286 num_of_bytes_(0) {
287 }
288
289 Packet* ReadMemoryCommand::Create() const {
290 return new ReadMemoryCommand;
291 }
292
293 void ReadMemoryCommand::AcceptVisitor(PacketVisitor* vis) {
294 vis->Visit(this);
295 }
296
297 bool ReadMemoryCommand::FromBlob(const std::string& type,
298 debug::Blob* message) {
299 // example: H>[mcffffff80,40] (with first 'm' removed)
300 std::deque<debug::Blob> tokens;
301 message->Split(",", &tokens);
302 if (tokens.size() < 2)
303 return false;
304
305 addr_ = tokens[0].PopInt64FromFront();
306 num_of_bytes_ = static_cast<int>(tokens[1].PopInt32FromFront());
307 return true;
308 }
309
310 void ReadMemoryCommand::ToBlob(debug::Blob* message) const {
311 message->Format("m%I64x,%x", addr_, num_of_bytes_);
312 }
313
314 WriteMemoryCommand::WriteMemoryCommand()
315 : addr_(0) {
316 }
317
318 Packet* WriteMemoryCommand::Create() const {
319 return new WriteMemoryCommand;
320 }
321
322 void WriteMemoryCommand::AcceptVisitor(PacketVisitor* vis) {
323 vis->Visit(this);
324 }
325
326 bool WriteMemoryCommand::FromBlob(const std::string& type, debug::Blob* message) {
327 // example: H>[Mc00020304,1:8b]
328 std::deque<debug::Blob> tokens;
329 message->Split(",", &tokens);
330 if (tokens.size() < 2)
331 return false;
332
333 addr_ = tokens[0].PopInt64FromFront();
334 debug::Blob len_and_data = tokens[1];
335 len_and_data.Split(":", &tokens);
336 if (tokens.size() < 2)
337 return false;
338 return data_.LoadFromHexString(tokens[1].ToString());
339 }
340
341 void WriteMemoryCommand::ToBlob(debug::Blob* message) const {
342 std::string hex_blob = data_.ToHexString();
343 message->Format("M%I64x,%x:%s",
344 addr_,
345 data_.size(),
346 hex_blob.c_str());
347 }
348
349 Packet* BlobReply::Create() const {
350 return new BlobReply;
351 }
352
353 void BlobReply::AcceptVisitor(PacketVisitor* vis) {
354 vis->Visit(this);
355 }
356
357 bool BlobReply::FromBlob(const std::string& type, debug::Blob* message) {
358 return data_.LoadFromHexString(message->ToString());
359 }
360
361 void BlobReply::ToBlob(debug::Blob* message) const {
362 *message = data_.ToHexString(false);
363 }
364
365 bool WriteRegistersCommand::FromBlob(const std::string& type,
366 debug::Blob* message) {
367 return data_.LoadFromHexString(message->ToString());
368 }
369
370 void WriteRegistersCommand::ToBlob(debug::Blob* message) const {
371 *message = "G";
372 message->Append(data_.ToHexString(false));
373 }
374
375 bool SetCurrentThreadCommand::FromBlob(const std::string& type, debug::Blob* mes sage) {
376 if ((message->size() > 0) &&
377 ('-' == message->GetAt(0)) &&
378 ('1' == message->GetAt(1)))
379 thread_id_ = -1; // all threads
380 else
381 thread_id_ = message->PopInt32FromFront();
382 return true;
383 }
384
385 void SetCurrentThreadCommand::ToBlob(debug::Blob* message) const {
386 if (FOR_READ == subtype_)
387 *message = "Hg";
388 else
389 *message = "Hc";
390
391 if (0 == thread_id_) {
392 message->Append("0");
393 } else if (-1 == thread_id_) {
394 message->Append("-1");
395 } else {
396 debug::Blob tmp;
397 tmp.Format("%x", thread_id_);
398 message->Append(tmp);
399 }
400 }
401
402 const char* QXferFeaturesReadCommand::kPrefix = "qXfer:features:read:";
403
404 QXferFeaturesReadCommand::QXferFeaturesReadCommand()
405 : offset_(0),
406 length_(0) {
407 }
408
409 bool QXferFeaturesReadCommand::FromBlob(const std::string& type,
410 debug::Blob* message) {
411 // example: target.xml:0,7ca
412 debug::Blob file_name = message->PopBlobFromFrontUnilChars(":");
413 debug::Blob offs = message->PopBlobFromFrontUnilChars(",");
414
415 file_name_ = file_name.ToString();
416 offset_ = offs.PopInt32FromFront();
417 length_ = message->PopInt32FromFront();
418 return true;
419 }
420
421 void QXferFeaturesReadCommand::ToBlob(debug::Blob* message) const {
422 message->Format("%s%s:%x,%x", kPrefix, file_name_.c_str(), offset_, length_);
423 }
424
425 bool QXferReply::FromBlob(const std::string& type, debug::Blob* message) {
426 if (message->size() < 1)
427 return false;
428 char cmd = message->PopFront();
429 eom_ = ('l' == cmd);
430 body_ = message->ToString();
431 return true;
432 }
433
434 void QXferReply::ToBlob(debug::Blob* message) const {
435 message->Format((eom_ ? "l%s" : "m%s"), body_.c_str());
436 }
437
438 bool GetThreadInfoCommand::FromBlob(const std::string& type,
439 debug::Blob* message) {
440 get_more_ = ("qsThreadInfo" == type);
441 return true;
442 }
443
444 void GetThreadInfoCommand::ToBlob(debug::Blob* message) const {
445 if (get_more_)
446 *message = "qsThreadInfo";
447 else
448 *message = "qfThreadInfo";
449 }
450
451 bool GetThreadInfoReply::FromBlob(const std::string& type, debug::Blob* message) {
452 if (message->size() < 1)
453 return false;
454 char cmd = message->PopFront();
455 eom_ = ('l' == cmd);
456
457 std::deque<debug::Blob> tokens;
458 message->Split(",", &tokens);
459
460 for (size_t i = 0; i < tokens.size(); i++) {
461 u_int32_t id = tokens[i].PopInt32FromFront();
462 threads_ids_.push_back(static_cast<int>(id));
463 }
464 return true;
465 }
466
467 void GetThreadInfoReply::ToBlob(debug::Blob* message) const {
468 if (eom_ || (0 == threads_ids_.size()))
469 *message = "l";
470 else
471 *message = "m";
472 size_t num = threads_ids_.size();
473 for (size_t i = 0; i < num; i++) {
474 debug::Blob tmp;
475 tmp.Format("%x", threads_ids_[i]);
476 message->Append(tmp);
477 if ((i + 1) != num)
478 message->Append(",");
479 }
480 }
481 } // namespace rsp
482
483 namespace {
484 bool HexStringToInt(const std::string& str, int* number) {
485 debug::Blob blob;
486 if (!blob.LoadFromHexString(str))
487 return false;
488
489 if (NULL != number)
490 *number = blob.ToInt();
491 return true;
492 }
493
494 void RemoveSpacesFromBothEnds(std::deque<debug::Blob>* tokens) {
495 std::deque<debug::Blob>::iterator it = tokens->begin();
496 while (it != tokens->end()) {
497 debug::Blob& token = *it++;
498 token.PopSpacesFromBothEnds();
499 }
500 }
501
502 void InitFactory() {
503 packet_factory_["qSupported"] = new rsp::QuerySupportedCommand;
504 packet_factory_["qSupported$Reply"] = new rsp::QuerySupportedReply;
505 packet_factory_["?"] = new rsp::GetStopReasonCommand;
506 packet_factory_["S"] = new rsp::StopReply(rsp::StopReply::SIGNALED);
507 packet_factory_["X"] = new rsp::StopReply(rsp::StopReply::TERMINATED);
508 packet_factory_["W"] = new rsp::StopReply(rsp::StopReply::EXITED);
509 packet_factory_["O"] = new rsp::StopReply(rsp::StopReply::STILL_RUNNING);
510 packet_factory_["m"] = new rsp::ReadMemoryCommand;
511 packet_factory_["M"] = new rsp::WriteMemoryCommand;
512 packet_factory_["blob$Reply"] = new rsp::BlobReply;
513 packet_factory_["g"] = new rsp::ReadRegistersCommand;
514 packet_factory_["G"] = new rsp::WriteRegistersCommand;
515 packet_factory_["E"] = new rsp::ErrorReply;
516 packet_factory_["OK"] = new rsp::OkReply;
517 packet_factory_["Hg"] =
518 new rsp::SetCurrentThreadCommand(rsp::SetCurrentThreadCommand::FOR_READ);
519 packet_factory_["Hc"] =
520 new rsp::SetCurrentThreadCommand(rsp::SetCurrentThreadCommand::FOR_CONTINU E);
521 packet_factory_["qC"] = new rsp::GetCurrentThreadCommand;
522 packet_factory_["QC"] = new rsp::GetCurrentThreadReply;
523 packet_factory_["c"] = new rsp::ContinueCommand;
524 packet_factory_["s"] = new rsp::StepCommand;
525 packet_factory_["T"] = new rsp::IsThreadAliveCommand;
526 packet_factory_["qXfer:features:read:"] = new rsp::QXferFeaturesReadCommand;
527 packet_factory_["qXfer$Reply"] = new rsp::QXferReply;
528 packet_factory_["qfThreadInfo"] = new rsp::GetThreadInfoCommand;
529 packet_factory_["qsThreadInfo"] = new rsp::GetThreadInfoCommand;
530 packet_factory_["GetThreadInfo$Reply"] = new rsp::GetThreadInfoReply;
531 }
532 } // namespace
OLDNEW
« no previous file with comments | « experimental/windows_debugger/debugger/rsp/rsp_packet.h ('k') | experimental/windows_debugger/debugger/rsp/rsp_packet_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698