1 //===-- StringExtractorGDBRemote.cpp --------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Utility/StringExtractorGDBRemote.h"
10
11 #include <cctype>
12 #include <cstring>
13
14 constexpr lldb::pid_t StringExtractorGDBRemote::AllProcesses;
15 constexpr lldb::tid_t StringExtractorGDBRemote::AllThreads;
16
17 StringExtractorGDBRemote::ResponseType
GetResponseType() const18 StringExtractorGDBRemote::GetResponseType() const {
19 if (m_packet.empty())
20 return eUnsupported;
21
22 switch (m_packet[0]) {
23 case 'E':
24 if (isxdigit(m_packet[1]) && isxdigit(m_packet[2])) {
25 if (m_packet.size() == 3)
26 return eError;
27 llvm::StringRef packet_ref(m_packet);
28 if (packet_ref[3] == ';') {
29 auto err_string = packet_ref.substr(4);
30 for (auto e : err_string)
31 if (!isxdigit(e))
32 return eResponse;
33 return eError;
34 }
35 }
36 break;
37
38 case 'O':
39 if (m_packet.size() == 2 && m_packet[1] == 'K')
40 return eOK;
41 break;
42
43 case '+':
44 if (m_packet.size() == 1)
45 return eAck;
46 break;
47
48 case '-':
49 if (m_packet.size() == 1)
50 return eNack;
51 break;
52 }
53 return eResponse;
54 }
55
56 StringExtractorGDBRemote::ServerPacketType
GetServerPacketType() const57 StringExtractorGDBRemote::GetServerPacketType() const {
58 #define PACKET_MATCHES(s) \
59 ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0))
60 #define PACKET_STARTS_WITH(s) \
61 ((packet_size >= (sizeof(s) - 1)) && \
62 ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0)
63
64 // Empty is not a supported packet...
65 if (m_packet.empty())
66 return eServerPacketType_invalid;
67
68 const size_t packet_size = m_packet.size();
69 const char *packet_cstr = m_packet.c_str();
70 switch (m_packet[0]) {
71
72 case '%':
73 return eServerPacketType_notify;
74
75 case '\x03':
76 if (packet_size == 1)
77 return eServerPacketType_interrupt;
78 break;
79
80 case '-':
81 if (packet_size == 1)
82 return eServerPacketType_nack;
83 break;
84
85 case '+':
86 if (packet_size == 1)
87 return eServerPacketType_ack;
88 break;
89
90 case 'A':
91 return eServerPacketType_A;
92
93 case 'Q':
94
95 switch (packet_cstr[1]) {
96 case 'E':
97 if (PACKET_STARTS_WITH("QEnvironment:"))
98 return eServerPacketType_QEnvironment;
99 if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:"))
100 return eServerPacketType_QEnvironmentHexEncoded;
101 if (PACKET_STARTS_WITH("QEnableErrorStrings"))
102 return eServerPacketType_QEnableErrorStrings;
103 break;
104
105 case 'P':
106 if (PACKET_STARTS_WITH("QPassSignals:"))
107 return eServerPacketType_QPassSignals;
108 break;
109
110 case 'S':
111 if (PACKET_MATCHES("QStartNoAckMode"))
112 return eServerPacketType_QStartNoAckMode;
113 if (PACKET_STARTS_WITH("QSaveRegisterState"))
114 return eServerPacketType_QSaveRegisterState;
115 if (PACKET_STARTS_WITH("QSetDisableASLR:"))
116 return eServerPacketType_QSetDisableASLR;
117 if (PACKET_STARTS_WITH("QSetDetachOnError:"))
118 return eServerPacketType_QSetDetachOnError;
119 if (PACKET_STARTS_WITH("QSetSTDIN:"))
120 return eServerPacketType_QSetSTDIN;
121 if (PACKET_STARTS_WITH("QSetSTDOUT:"))
122 return eServerPacketType_QSetSTDOUT;
123 if (PACKET_STARTS_WITH("QSetSTDERR:"))
124 return eServerPacketType_QSetSTDERR;
125 if (PACKET_STARTS_WITH("QSetWorkingDir:"))
126 return eServerPacketType_QSetWorkingDir;
127 if (PACKET_STARTS_WITH("QSetLogging:"))
128 return eServerPacketType_QSetLogging;
129 if (PACKET_STARTS_WITH("QSetMaxPacketSize:"))
130 return eServerPacketType_QSetMaxPacketSize;
131 if (PACKET_STARTS_WITH("QSetMaxPayloadSize:"))
132 return eServerPacketType_QSetMaxPayloadSize;
133 if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;"))
134 return eServerPacketType_QSetEnableAsyncProfiling;
135 if (PACKET_STARTS_WITH("QSyncThreadState:"))
136 return eServerPacketType_QSyncThreadState;
137 break;
138
139 case 'L':
140 if (PACKET_STARTS_WITH("QLaunchArch:"))
141 return eServerPacketType_QLaunchArch;
142 if (PACKET_MATCHES("QListThreadsInStopReply"))
143 return eServerPacketType_QListThreadsInStopReply;
144 break;
145
146 case 'M':
147 if (PACKET_STARTS_WITH("QMemTags"))
148 return eServerPacketType_QMemTags;
149 break;
150
151 case 'R':
152 if (PACKET_STARTS_WITH("QRestoreRegisterState:"))
153 return eServerPacketType_QRestoreRegisterState;
154 break;
155
156 case 'T':
157 if (PACKET_MATCHES("QThreadSuffixSupported"))
158 return eServerPacketType_QThreadSuffixSupported;
159 break;
160 }
161 break;
162
163 case 'q':
164 switch (packet_cstr[1]) {
165 case 's':
166 if (PACKET_MATCHES("qsProcessInfo"))
167 return eServerPacketType_qsProcessInfo;
168 if (PACKET_MATCHES("qsThreadInfo"))
169 return eServerPacketType_qsThreadInfo;
170 break;
171
172 case 'f':
173 if (PACKET_STARTS_WITH("qfProcessInfo"))
174 return eServerPacketType_qfProcessInfo;
175 if (PACKET_STARTS_WITH("qfThreadInfo"))
176 return eServerPacketType_qfThreadInfo;
177 break;
178
179 case 'C':
180 if (packet_size == 2)
181 return eServerPacketType_qC;
182 break;
183
184 case 'E':
185 if (PACKET_STARTS_WITH("qEcho:"))
186 return eServerPacketType_qEcho;
187 break;
188
189 case 'F':
190 if (PACKET_STARTS_WITH("qFileLoadAddress:"))
191 return eServerPacketType_qFileLoadAddress;
192 break;
193
194 case 'G':
195 if (PACKET_STARTS_WITH("qGroupName:"))
196 return eServerPacketType_qGroupName;
197 if (PACKET_MATCHES("qGetWorkingDir"))
198 return eServerPacketType_qGetWorkingDir;
199 if (PACKET_MATCHES("qGetPid"))
200 return eServerPacketType_qGetPid;
201 if (PACKET_STARTS_WITH("qGetProfileData;"))
202 return eServerPacketType_qGetProfileData;
203 if (PACKET_MATCHES("qGDBServerVersion"))
204 return eServerPacketType_qGDBServerVersion;
205 break;
206
207 case 'H':
208 if (PACKET_MATCHES("qHostInfo"))
209 return eServerPacketType_qHostInfo;
210 break;
211
212 case 'K':
213 if (PACKET_STARTS_WITH("qKillSpawnedProcess"))
214 return eServerPacketType_qKillSpawnedProcess;
215 break;
216
217 case 'L':
218 if (PACKET_STARTS_WITH("qLaunchGDBServer"))
219 return eServerPacketType_qLaunchGDBServer;
220 if (PACKET_MATCHES("qLaunchSuccess"))
221 return eServerPacketType_qLaunchSuccess;
222 break;
223
224 case 'M':
225 if (PACKET_STARTS_WITH("qMemoryRegionInfo:"))
226 return eServerPacketType_qMemoryRegionInfo;
227 if (PACKET_MATCHES("qMemoryRegionInfo"))
228 return eServerPacketType_qMemoryRegionInfoSupported;
229 if (PACKET_STARTS_WITH("qModuleInfo:"))
230 return eServerPacketType_qModuleInfo;
231 if (PACKET_STARTS_WITH("qMemTags:"))
232 return eServerPacketType_qMemTags;
233 break;
234
235 case 'P':
236 if (PACKET_STARTS_WITH("qProcessInfoPID:"))
237 return eServerPacketType_qProcessInfoPID;
238 if (PACKET_STARTS_WITH("qPlatform_shell:"))
239 return eServerPacketType_qPlatform_shell;
240 if (PACKET_STARTS_WITH("qPlatform_mkdir:"))
241 return eServerPacketType_qPlatform_mkdir;
242 if (PACKET_STARTS_WITH("qPlatform_chmod:"))
243 return eServerPacketType_qPlatform_chmod;
244 if (PACKET_MATCHES("qProcessInfo"))
245 return eServerPacketType_qProcessInfo;
246 if (PACKET_STARTS_WITH("qPathComplete:"))
247 return eServerPacketType_qPathComplete;
248 break;
249
250 case 'Q':
251 if (PACKET_MATCHES("qQueryGDBServer"))
252 return eServerPacketType_qQueryGDBServer;
253 break;
254
255 case 'R':
256 if (PACKET_STARTS_WITH("qRcmd,"))
257 return eServerPacketType_qRcmd;
258 if (PACKET_STARTS_WITH("qRegisterInfo"))
259 return eServerPacketType_qRegisterInfo;
260 break;
261
262 case 'S':
263 if (PACKET_STARTS_WITH("qSpeedTest:"))
264 return eServerPacketType_qSpeedTest;
265 if (PACKET_MATCHES("qShlibInfoAddr"))
266 return eServerPacketType_qShlibInfoAddr;
267 if (PACKET_MATCHES("qStepPacketSupported"))
268 return eServerPacketType_qStepPacketSupported;
269 if (PACKET_STARTS_WITH("qSupported"))
270 return eServerPacketType_qSupported;
271 if (PACKET_MATCHES("qSyncThreadStateSupported"))
272 return eServerPacketType_qSyncThreadStateSupported;
273 break;
274
275 case 'T':
276 if (PACKET_STARTS_WITH("qThreadExtraInfo,"))
277 return eServerPacketType_qThreadExtraInfo;
278 if (PACKET_STARTS_WITH("qThreadStopInfo"))
279 return eServerPacketType_qThreadStopInfo;
280 break;
281
282 case 'U':
283 if (PACKET_STARTS_WITH("qUserName:"))
284 return eServerPacketType_qUserName;
285 break;
286
287 case 'V':
288 if (PACKET_MATCHES("qVAttachOrWaitSupported"))
289 return eServerPacketType_qVAttachOrWaitSupported;
290 break;
291
292 case 'W':
293 if (PACKET_STARTS_WITH("qWatchpointSupportInfo:"))
294 return eServerPacketType_qWatchpointSupportInfo;
295 if (PACKET_MATCHES("qWatchpointSupportInfo"))
296 return eServerPacketType_qWatchpointSupportInfoSupported;
297 break;
298
299 case 'X':
300 if (PACKET_STARTS_WITH("qXfer:"))
301 return eServerPacketType_qXfer;
302 break;
303 }
304 break;
305
306 case 'j':
307 if (PACKET_STARTS_WITH("jModulesInfo:"))
308 return eServerPacketType_jModulesInfo;
309 if (PACKET_MATCHES("jSignalsInfo"))
310 return eServerPacketType_jSignalsInfo;
311 if (PACKET_MATCHES("jThreadsInfo"))
312 return eServerPacketType_jThreadsInfo;
313
314 if (PACKET_MATCHES("jLLDBTraceSupported"))
315 return eServerPacketType_jLLDBTraceSupported;
316 if (PACKET_STARTS_WITH("jLLDBTraceStop:"))
317 return eServerPacketType_jLLDBTraceStop;
318 if (PACKET_STARTS_WITH("jLLDBTraceStart:"))
319 return eServerPacketType_jLLDBTraceStart;
320 if (PACKET_STARTS_WITH("jLLDBTraceGetState:"))
321 return eServerPacketType_jLLDBTraceGetState;
322 if (PACKET_STARTS_WITH("jLLDBTraceGetBinaryData:"))
323 return eServerPacketType_jLLDBTraceGetBinaryData;
324 break;
325
326 case 'v':
327 if (PACKET_STARTS_WITH("vFile:")) {
328 if (PACKET_STARTS_WITH("vFile:open:"))
329 return eServerPacketType_vFile_open;
330 else if (PACKET_STARTS_WITH("vFile:close:"))
331 return eServerPacketType_vFile_close;
332 else if (PACKET_STARTS_WITH("vFile:pread"))
333 return eServerPacketType_vFile_pread;
334 else if (PACKET_STARTS_WITH("vFile:pwrite"))
335 return eServerPacketType_vFile_pwrite;
336 else if (PACKET_STARTS_WITH("vFile:size"))
337 return eServerPacketType_vFile_size;
338 else if (PACKET_STARTS_WITH("vFile:exists"))
339 return eServerPacketType_vFile_exists;
340 else if (PACKET_STARTS_WITH("vFile:stat"))
341 return eServerPacketType_vFile_stat;
342 else if (PACKET_STARTS_WITH("vFile:mode"))
343 return eServerPacketType_vFile_mode;
344 else if (PACKET_STARTS_WITH("vFile:MD5"))
345 return eServerPacketType_vFile_md5;
346 else if (PACKET_STARTS_WITH("vFile:symlink"))
347 return eServerPacketType_vFile_symlink;
348 else if (PACKET_STARTS_WITH("vFile:unlink"))
349 return eServerPacketType_vFile_unlink;
350
351 } else {
352 if (PACKET_STARTS_WITH("vAttach;"))
353 return eServerPacketType_vAttach;
354 if (PACKET_STARTS_WITH("vAttachWait;"))
355 return eServerPacketType_vAttachWait;
356 if (PACKET_STARTS_WITH("vAttachOrWait;"))
357 return eServerPacketType_vAttachOrWait;
358 if (PACKET_STARTS_WITH("vAttachName;"))
359 return eServerPacketType_vAttachName;
360 if (PACKET_STARTS_WITH("vCont;"))
361 return eServerPacketType_vCont;
362 if (PACKET_MATCHES("vCont?"))
363 return eServerPacketType_vCont_actions;
364 }
365 break;
366 case '_':
367 switch (packet_cstr[1]) {
368 case 'M':
369 return eServerPacketType__M;
370
371 case 'm':
372 return eServerPacketType__m;
373 }
374 break;
375
376 case '?':
377 if (packet_size == 1)
378 return eServerPacketType_stop_reason;
379 break;
380
381 case 'c':
382 return eServerPacketType_c;
383
384 case 'C':
385 return eServerPacketType_C;
386
387 case 'D':
388 return eServerPacketType_D;
389
390 case 'g':
391 return eServerPacketType_g;
392
393 case 'G':
394 return eServerPacketType_G;
395
396 case 'H':
397 return eServerPacketType_H;
398
399 case 'I':
400 return eServerPacketType_I;
401
402 case 'k':
403 if (packet_size == 1)
404 return eServerPacketType_k;
405 break;
406
407 case 'm':
408 return eServerPacketType_m;
409
410 case 'M':
411 return eServerPacketType_M;
412
413 case 'p':
414 return eServerPacketType_p;
415
416 case 'P':
417 return eServerPacketType_P;
418
419 case 's':
420 if (packet_size == 1)
421 return eServerPacketType_s;
422 break;
423
424 case 'S':
425 return eServerPacketType_S;
426
427 case 'x':
428 return eServerPacketType_x;
429
430 case 'X':
431 return eServerPacketType_X;
432
433 case 'T':
434 return eServerPacketType_T;
435
436 case 'z':
437 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
438 return eServerPacketType_z;
439 break;
440
441 case 'Z':
442 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
443 return eServerPacketType_Z;
444 break;
445 }
446 return eServerPacketType_unimplemented;
447 }
448
IsOKResponse() const449 bool StringExtractorGDBRemote::IsOKResponse() const {
450 return GetResponseType() == eOK;
451 }
452
IsUnsupportedResponse() const453 bool StringExtractorGDBRemote::IsUnsupportedResponse() const {
454 return GetResponseType() == eUnsupported;
455 }
456
IsNormalResponse() const457 bool StringExtractorGDBRemote::IsNormalResponse() const {
458 return GetResponseType() == eResponse;
459 }
460
IsErrorResponse() const461 bool StringExtractorGDBRemote::IsErrorResponse() const {
462 return GetResponseType() == eError && isxdigit(m_packet[1]) &&
463 isxdigit(m_packet[2]);
464 }
465
GetError()466 uint8_t StringExtractorGDBRemote::GetError() {
467 if (GetResponseType() == eError) {
468 SetFilePos(1);
469 return GetHexU8(255);
470 }
471 return 0;
472 }
473
GetStatus()474 lldb_private::Status StringExtractorGDBRemote::GetStatus() {
475 lldb_private::Status error;
476 if (GetResponseType() == eError) {
477 SetFilePos(1);
478 uint8_t errc = GetHexU8(255);
479 error.SetError(errc, lldb::eErrorTypeGeneric);
480
481 error.SetErrorStringWithFormat("Error %u", errc);
482 std::string error_messg;
483 if (GetChar() == ';') {
484 GetHexByteString(error_messg);
485 error.SetErrorString(error_messg);
486 }
487 }
488 return error;
489 }
490
GetEscapedBinaryData(std::string & str)491 size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
492 // Just get the data bytes in the string as
493 // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped
494 // characters. If any 0x7d characters are left in the packet, then they are
495 // supposed to be there...
496 str.clear();
497 const size_t bytes_left = GetBytesLeft();
498 if (bytes_left > 0) {
499 str.assign(m_packet, m_index, bytes_left);
500 m_index += bytes_left;
501 }
502 return str.size();
503 }
504
505 static bool
OKErrorNotSupportedResponseValidator(void *,const StringExtractorGDBRemote & response)506 OKErrorNotSupportedResponseValidator(void *,
507 const StringExtractorGDBRemote &response) {
508 switch (response.GetResponseType()) {
509 case StringExtractorGDBRemote::eOK:
510 case StringExtractorGDBRemote::eError:
511 case StringExtractorGDBRemote::eUnsupported:
512 return true;
513
514 case StringExtractorGDBRemote::eAck:
515 case StringExtractorGDBRemote::eNack:
516 case StringExtractorGDBRemote::eResponse:
517 break;
518 }
519 return false;
520 }
521
JSONResponseValidator(void *,const StringExtractorGDBRemote & response)522 static bool JSONResponseValidator(void *,
523 const StringExtractorGDBRemote &response) {
524 switch (response.GetResponseType()) {
525 case StringExtractorGDBRemote::eUnsupported:
526 case StringExtractorGDBRemote::eError:
527 return true; // Accept unsupported or EXX as valid responses
528
529 case StringExtractorGDBRemote::eOK:
530 case StringExtractorGDBRemote::eAck:
531 case StringExtractorGDBRemote::eNack:
532 break;
533
534 case StringExtractorGDBRemote::eResponse:
535 // JSON that is returned in from JSON query packets is currently always
536 // either a dictionary which starts with a '{', or an array which starts
537 // with a '['. This is a quick validator to just make sure the response
538 // could be valid JSON without having to validate all of the
539 // JSON content.
540 switch (response.GetStringRef()[0]) {
541 case '{':
542 return true;
543 case '[':
544 return true;
545 default:
546 break;
547 }
548 break;
549 }
550 return false;
551 }
552
553 static bool
ASCIIHexBytesResponseValidator(void *,const StringExtractorGDBRemote & response)554 ASCIIHexBytesResponseValidator(void *,
555 const StringExtractorGDBRemote &response) {
556 switch (response.GetResponseType()) {
557 case StringExtractorGDBRemote::eUnsupported:
558 case StringExtractorGDBRemote::eError:
559 return true; // Accept unsupported or EXX as valid responses
560
561 case StringExtractorGDBRemote::eOK:
562 case StringExtractorGDBRemote::eAck:
563 case StringExtractorGDBRemote::eNack:
564 break;
565
566 case StringExtractorGDBRemote::eResponse: {
567 uint32_t valid_count = 0;
568 for (const char ch : response.GetStringRef()) {
569 if (!isxdigit(ch)) {
570 return false;
571 }
572 if (++valid_count >= 16)
573 break; // Don't validate all the characters in case the packet is very
574 // large
575 }
576 return true;
577 } break;
578 }
579 return false;
580 }
581
CopyResponseValidator(const StringExtractorGDBRemote & rhs)582 void StringExtractorGDBRemote::CopyResponseValidator(
583 const StringExtractorGDBRemote &rhs) {
584 m_validator = rhs.m_validator;
585 m_validator_baton = rhs.m_validator_baton;
586 }
587
SetResponseValidator(ResponseValidatorCallback callback,void * baton)588 void StringExtractorGDBRemote::SetResponseValidator(
589 ResponseValidatorCallback callback, void *baton) {
590 m_validator = callback;
591 m_validator_baton = baton;
592 }
593
SetResponseValidatorToOKErrorNotSupported()594 void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() {
595 m_validator = OKErrorNotSupportedResponseValidator;
596 m_validator_baton = nullptr;
597 }
598
SetResponseValidatorToASCIIHexBytes()599 void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() {
600 m_validator = ASCIIHexBytesResponseValidator;
601 m_validator_baton = nullptr;
602 }
603
SetResponseValidatorToJSON()604 void StringExtractorGDBRemote::SetResponseValidatorToJSON() {
605 m_validator = JSONResponseValidator;
606 m_validator_baton = nullptr;
607 }
608
ValidateResponse() const609 bool StringExtractorGDBRemote::ValidateResponse() const {
610 // If we have a validator callback, try to validate the callback
611 if (m_validator)
612 return m_validator(m_validator_baton, *this);
613 else
614 return true; // No validator, so response is valid
615 }
616
617 llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>>
GetPidTid(lldb::pid_t default_pid)618 StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) {
619 llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index);
620 size_t initial_length = view.size();
621 lldb::pid_t pid = default_pid;
622 lldb::tid_t tid;
623
624 if (view.consume_front("p")) {
625 // process identifier
626 if (view.consume_front("-1")) {
627 // -1 is a special case
628 pid = AllProcesses;
629 } else if (view.consumeInteger(16, pid) || pid == 0) {
630 // not a valid hex integer OR unsupported pid 0
631 m_index = UINT64_MAX;
632 return llvm::None;
633 }
634
635 // "." must follow if we expect TID too; otherwise, we assume -1
636 if (!view.consume_front(".")) {
637 // update m_index
638 m_index += initial_length - view.size();
639
640 return {{pid, AllThreads}};
641 }
642 }
643
644 // thread identifier
645 if (view.consume_front("-1")) {
646 // -1 is a special case
647 tid = AllThreads;
648 } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) {
649 // not a valid hex integer OR tid 0 OR pid -1 + a specific tid
650 m_index = UINT64_MAX;
651 return llvm::None;
652 }
653
654 // update m_index
655 m_index += initial_length - view.size();
656
657 return {{pid, tid}};
658 }
659