xref: /llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp (revision 6c1a8039de4646f6efbb3ba404d5bee5d631be67)
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 <ctype.h>
12 #include <string.h>
13 
14 constexpr lldb::pid_t StringExtractorGDBRemote::AllProcesses;
15 constexpr lldb::tid_t StringExtractorGDBRemote::AllThreads;
16 
17 StringExtractorGDBRemote::ResponseType
18 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
57 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 'R':
147       if (PACKET_STARTS_WITH("QRestoreRegisterState:"))
148         return eServerPacketType_QRestoreRegisterState;
149       break;
150 
151     case 'T':
152       if (PACKET_MATCHES("QThreadSuffixSupported"))
153         return eServerPacketType_QThreadSuffixSupported;
154       break;
155     }
156     break;
157 
158   case 'q':
159     switch (packet_cstr[1]) {
160     case 's':
161       if (PACKET_MATCHES("qsProcessInfo"))
162         return eServerPacketType_qsProcessInfo;
163       if (PACKET_MATCHES("qsThreadInfo"))
164         return eServerPacketType_qsThreadInfo;
165       break;
166 
167     case 'f':
168       if (PACKET_STARTS_WITH("qfProcessInfo"))
169         return eServerPacketType_qfProcessInfo;
170       if (PACKET_STARTS_WITH("qfThreadInfo"))
171         return eServerPacketType_qfThreadInfo;
172       break;
173 
174     case 'C':
175       if (packet_size == 2)
176         return eServerPacketType_qC;
177       break;
178 
179     case 'E':
180       if (PACKET_STARTS_WITH("qEcho:"))
181         return eServerPacketType_qEcho;
182       break;
183 
184     case 'F':
185       if (PACKET_STARTS_WITH("qFileLoadAddress:"))
186         return eServerPacketType_qFileLoadAddress;
187       break;
188 
189     case 'G':
190       if (PACKET_STARTS_WITH("qGroupName:"))
191         return eServerPacketType_qGroupName;
192       if (PACKET_MATCHES("qGetWorkingDir"))
193         return eServerPacketType_qGetWorkingDir;
194       if (PACKET_MATCHES("qGetPid"))
195         return eServerPacketType_qGetPid;
196       if (PACKET_STARTS_WITH("qGetProfileData;"))
197         return eServerPacketType_qGetProfileData;
198       if (PACKET_MATCHES("qGDBServerVersion"))
199         return eServerPacketType_qGDBServerVersion;
200       break;
201 
202     case 'H':
203       if (PACKET_MATCHES("qHostInfo"))
204         return eServerPacketType_qHostInfo;
205       break;
206 
207     case 'K':
208       if (PACKET_STARTS_WITH("qKillSpawnedProcess"))
209         return eServerPacketType_qKillSpawnedProcess;
210       break;
211 
212     case 'L':
213       if (PACKET_STARTS_WITH("qLaunchGDBServer"))
214         return eServerPacketType_qLaunchGDBServer;
215       if (PACKET_MATCHES("qLaunchSuccess"))
216         return eServerPacketType_qLaunchSuccess;
217       break;
218 
219     case 'M':
220       if (PACKET_STARTS_WITH("qMemoryRegionInfo:"))
221         return eServerPacketType_qMemoryRegionInfo;
222       if (PACKET_MATCHES("qMemoryRegionInfo"))
223         return eServerPacketType_qMemoryRegionInfoSupported;
224       if (PACKET_STARTS_WITH("qModuleInfo:"))
225         return eServerPacketType_qModuleInfo;
226       break;
227 
228     case 'P':
229       if (PACKET_STARTS_WITH("qProcessInfoPID:"))
230         return eServerPacketType_qProcessInfoPID;
231       if (PACKET_STARTS_WITH("qPlatform_shell:"))
232         return eServerPacketType_qPlatform_shell;
233       if (PACKET_STARTS_WITH("qPlatform_mkdir:"))
234         return eServerPacketType_qPlatform_mkdir;
235       if (PACKET_STARTS_WITH("qPlatform_chmod:"))
236         return eServerPacketType_qPlatform_chmod;
237       if (PACKET_MATCHES("qProcessInfo"))
238         return eServerPacketType_qProcessInfo;
239       if (PACKET_STARTS_WITH("qPathComplete:"))
240         return eServerPacketType_qPathComplete;
241       break;
242 
243     case 'Q':
244       if (PACKET_MATCHES("qQueryGDBServer"))
245         return eServerPacketType_qQueryGDBServer;
246       break;
247 
248     case 'R':
249       if (PACKET_STARTS_WITH("qRcmd,"))
250         return eServerPacketType_qRcmd;
251       if (PACKET_STARTS_WITH("qRegisterInfo"))
252         return eServerPacketType_qRegisterInfo;
253       break;
254 
255     case 'S':
256       if (PACKET_STARTS_WITH("qSpeedTest:"))
257         return eServerPacketType_qSpeedTest;
258       if (PACKET_MATCHES("qShlibInfoAddr"))
259         return eServerPacketType_qShlibInfoAddr;
260       if (PACKET_MATCHES("qStepPacketSupported"))
261         return eServerPacketType_qStepPacketSupported;
262       if (PACKET_STARTS_WITH("qSupported"))
263         return eServerPacketType_qSupported;
264       if (PACKET_MATCHES("qSyncThreadStateSupported"))
265         return eServerPacketType_qSyncThreadStateSupported;
266       break;
267 
268     case 'T':
269       if (PACKET_STARTS_WITH("qThreadExtraInfo,"))
270         return eServerPacketType_qThreadExtraInfo;
271       if (PACKET_STARTS_WITH("qThreadStopInfo"))
272         return eServerPacketType_qThreadStopInfo;
273       break;
274 
275     case 'U':
276       if (PACKET_STARTS_WITH("qUserName:"))
277         return eServerPacketType_qUserName;
278       break;
279 
280     case 'V':
281       if (PACKET_MATCHES("qVAttachOrWaitSupported"))
282         return eServerPacketType_qVAttachOrWaitSupported;
283       break;
284 
285     case 'W':
286       if (PACKET_STARTS_WITH("qWatchpointSupportInfo:"))
287         return eServerPacketType_qWatchpointSupportInfo;
288       if (PACKET_MATCHES("qWatchpointSupportInfo"))
289         return eServerPacketType_qWatchpointSupportInfoSupported;
290       break;
291 
292     case 'X':
293       if (PACKET_STARTS_WITH("qXfer:"))
294         return eServerPacketType_qXfer;
295       break;
296     }
297     break;
298 
299   case 'j':
300     if (PACKET_STARTS_WITH("jModulesInfo:"))
301       return eServerPacketType_jModulesInfo;
302     if (PACKET_MATCHES("jSignalsInfo"))
303       return eServerPacketType_jSignalsInfo;
304     if (PACKET_MATCHES("jThreadsInfo"))
305       return eServerPacketType_jThreadsInfo;
306     if (PACKET_STARTS_WITH("jTraceBufferRead:"))
307       return eServerPacketType_jTraceBufferRead;
308     if (PACKET_STARTS_WITH("jTraceConfigRead:"))
309       return eServerPacketType_jTraceConfigRead;
310     if (PACKET_STARTS_WITH("jTraceMetaRead:"))
311       return eServerPacketType_jTraceMetaRead;
312     if (PACKET_STARTS_WITH("jTraceStart:"))
313       return eServerPacketType_jTraceStart;
314     if (PACKET_STARTS_WITH("jTraceStop:"))
315       return eServerPacketType_jTraceStop;
316     if (PACKET_MATCHES("jLLDBTraceSupportedType"))
317       return eServerPacketType_jLLDBTraceSupportedType;
318     break;
319 
320   case 'v':
321     if (PACKET_STARTS_WITH("vFile:")) {
322       if (PACKET_STARTS_WITH("vFile:open:"))
323         return eServerPacketType_vFile_open;
324       else if (PACKET_STARTS_WITH("vFile:close:"))
325         return eServerPacketType_vFile_close;
326       else if (PACKET_STARTS_WITH("vFile:pread"))
327         return eServerPacketType_vFile_pread;
328       else if (PACKET_STARTS_WITH("vFile:pwrite"))
329         return eServerPacketType_vFile_pwrite;
330       else if (PACKET_STARTS_WITH("vFile:size"))
331         return eServerPacketType_vFile_size;
332       else if (PACKET_STARTS_WITH("vFile:exists"))
333         return eServerPacketType_vFile_exists;
334       else if (PACKET_STARTS_WITH("vFile:stat"))
335         return eServerPacketType_vFile_stat;
336       else if (PACKET_STARTS_WITH("vFile:mode"))
337         return eServerPacketType_vFile_mode;
338       else if (PACKET_STARTS_WITH("vFile:MD5"))
339         return eServerPacketType_vFile_md5;
340       else if (PACKET_STARTS_WITH("vFile:symlink"))
341         return eServerPacketType_vFile_symlink;
342       else if (PACKET_STARTS_WITH("vFile:unlink"))
343         return eServerPacketType_vFile_unlink;
344 
345     } else {
346       if (PACKET_STARTS_WITH("vAttach;"))
347         return eServerPacketType_vAttach;
348       if (PACKET_STARTS_WITH("vAttachWait;"))
349         return eServerPacketType_vAttachWait;
350       if (PACKET_STARTS_WITH("vAttachOrWait;"))
351         return eServerPacketType_vAttachOrWait;
352       if (PACKET_STARTS_WITH("vAttachName;"))
353         return eServerPacketType_vAttachName;
354       if (PACKET_STARTS_WITH("vCont;"))
355         return eServerPacketType_vCont;
356       if (PACKET_MATCHES("vCont?"))
357         return eServerPacketType_vCont_actions;
358     }
359     break;
360   case '_':
361     switch (packet_cstr[1]) {
362     case 'M':
363       return eServerPacketType__M;
364 
365     case 'm':
366       return eServerPacketType__m;
367     }
368     break;
369 
370   case '?':
371     if (packet_size == 1)
372       return eServerPacketType_stop_reason;
373     break;
374 
375   case 'c':
376     return eServerPacketType_c;
377 
378   case 'C':
379     return eServerPacketType_C;
380 
381   case 'D':
382     if (packet_size == 1)
383       return eServerPacketType_D;
384     break;
385 
386   case 'g':
387     return eServerPacketType_g;
388 
389   case 'G':
390     return eServerPacketType_G;
391 
392   case 'H':
393     return eServerPacketType_H;
394 
395   case 'I':
396     return eServerPacketType_I;
397 
398   case 'k':
399     if (packet_size == 1)
400       return eServerPacketType_k;
401     break;
402 
403   case 'm':
404     return eServerPacketType_m;
405 
406   case 'M':
407     return eServerPacketType_M;
408 
409   case 'p':
410     return eServerPacketType_p;
411 
412   case 'P':
413     return eServerPacketType_P;
414 
415   case 's':
416     if (packet_size == 1)
417       return eServerPacketType_s;
418     break;
419 
420   case 'S':
421     return eServerPacketType_S;
422 
423   case 'x':
424     return eServerPacketType_x;
425 
426   case 'X':
427     return eServerPacketType_X;
428 
429   case 'T':
430     return eServerPacketType_T;
431 
432   case 'z':
433     if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
434       return eServerPacketType_z;
435     break;
436 
437   case 'Z':
438     if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
439       return eServerPacketType_Z;
440     break;
441   }
442   return eServerPacketType_unimplemented;
443 }
444 
445 bool StringExtractorGDBRemote::IsOKResponse() const {
446   return GetResponseType() == eOK;
447 }
448 
449 bool StringExtractorGDBRemote::IsUnsupportedResponse() const {
450   return GetResponseType() == eUnsupported;
451 }
452 
453 bool StringExtractorGDBRemote::IsNormalResponse() const {
454   return GetResponseType() == eResponse;
455 }
456 
457 bool StringExtractorGDBRemote::IsErrorResponse() const {
458   return GetResponseType() == eError && isxdigit(m_packet[1]) &&
459          isxdigit(m_packet[2]);
460 }
461 
462 uint8_t StringExtractorGDBRemote::GetError() {
463   if (GetResponseType() == eError) {
464     SetFilePos(1);
465     return GetHexU8(255);
466   }
467   return 0;
468 }
469 
470 lldb_private::Status StringExtractorGDBRemote::GetStatus() {
471   lldb_private::Status error;
472   if (GetResponseType() == eError) {
473     SetFilePos(1);
474     uint8_t errc = GetHexU8(255);
475     error.SetError(errc, lldb::eErrorTypeGeneric);
476 
477     error.SetErrorStringWithFormat("Error %u", errc);
478     std::string error_messg;
479     if (GetChar() == ';') {
480       GetHexByteString(error_messg);
481       error.SetErrorString(error_messg);
482     }
483   }
484   return error;
485 }
486 
487 size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
488   // Just get the data bytes in the string as
489   // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped
490   // characters. If any 0x7d characters are left in the packet, then they are
491   // supposed to be there...
492   str.clear();
493   const size_t bytes_left = GetBytesLeft();
494   if (bytes_left > 0) {
495     str.assign(m_packet, m_index, bytes_left);
496     m_index += bytes_left;
497   }
498   return str.size();
499 }
500 
501 static bool
502 OKErrorNotSupportedResponseValidator(void *,
503                                      const StringExtractorGDBRemote &response) {
504   switch (response.GetResponseType()) {
505   case StringExtractorGDBRemote::eOK:
506   case StringExtractorGDBRemote::eError:
507   case StringExtractorGDBRemote::eUnsupported:
508     return true;
509 
510   case StringExtractorGDBRemote::eAck:
511   case StringExtractorGDBRemote::eNack:
512   case StringExtractorGDBRemote::eResponse:
513     break;
514   }
515   return false;
516 }
517 
518 static bool JSONResponseValidator(void *,
519                                   const StringExtractorGDBRemote &response) {
520   switch (response.GetResponseType()) {
521   case StringExtractorGDBRemote::eUnsupported:
522   case StringExtractorGDBRemote::eError:
523     return true; // Accept unsupported or EXX as valid responses
524 
525   case StringExtractorGDBRemote::eOK:
526   case StringExtractorGDBRemote::eAck:
527   case StringExtractorGDBRemote::eNack:
528     break;
529 
530   case StringExtractorGDBRemote::eResponse:
531     // JSON that is returned in from JSON query packets is currently always
532     // either a dictionary which starts with a '{', or an array which starts
533     // with a '['. This is a quick validator to just make sure the response
534     // could be valid JSON without having to validate all of the
535     // JSON content.
536     switch (response.GetStringRef()[0]) {
537     case '{':
538       return true;
539     case '[':
540       return true;
541     default:
542       break;
543     }
544     break;
545   }
546   return false;
547 }
548 
549 static bool
550 ASCIIHexBytesResponseValidator(void *,
551                                const StringExtractorGDBRemote &response) {
552   switch (response.GetResponseType()) {
553   case StringExtractorGDBRemote::eUnsupported:
554   case StringExtractorGDBRemote::eError:
555     return true; // Accept unsupported or EXX as valid responses
556 
557   case StringExtractorGDBRemote::eOK:
558   case StringExtractorGDBRemote::eAck:
559   case StringExtractorGDBRemote::eNack:
560     break;
561 
562   case StringExtractorGDBRemote::eResponse: {
563     uint32_t valid_count = 0;
564     for (const char ch : response.GetStringRef()) {
565       if (!isxdigit(ch)) {
566         return false;
567       }
568       if (++valid_count >= 16)
569         break; // Don't validate all the characters in case the packet is very
570                // large
571     }
572     return true;
573   } break;
574   }
575   return false;
576 }
577 
578 void StringExtractorGDBRemote::CopyResponseValidator(
579     const StringExtractorGDBRemote &rhs) {
580   m_validator = rhs.m_validator;
581   m_validator_baton = rhs.m_validator_baton;
582 }
583 
584 void StringExtractorGDBRemote::SetResponseValidator(
585     ResponseValidatorCallback callback, void *baton) {
586   m_validator = callback;
587   m_validator_baton = baton;
588 }
589 
590 void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() {
591   m_validator = OKErrorNotSupportedResponseValidator;
592   m_validator_baton = nullptr;
593 }
594 
595 void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() {
596   m_validator = ASCIIHexBytesResponseValidator;
597   m_validator_baton = nullptr;
598 }
599 
600 void StringExtractorGDBRemote::SetResponseValidatorToJSON() {
601   m_validator = JSONResponseValidator;
602   m_validator_baton = nullptr;
603 }
604 
605 bool StringExtractorGDBRemote::ValidateResponse() const {
606   // If we have a validator callback, try to validate the callback
607   if (m_validator)
608     return m_validator(m_validator_baton, *this);
609   else
610     return true; // No validator, so response is valid
611 }
612 
613 llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>>
614 StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) {
615   llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index);
616   size_t initial_length = view.size();
617   lldb::pid_t pid = default_pid;
618   lldb::tid_t tid;
619 
620   if (view.consume_front("p")) {
621     // process identifier
622     if (view.consume_front("-1")) {
623       // -1 is a special case
624       pid = AllProcesses;
625     } else if (view.consumeInteger(16, pid) || pid == 0) {
626       // not a valid hex integer OR unsupported pid 0
627       m_index = UINT64_MAX;
628       return llvm::None;
629     }
630 
631     // "." must follow if we expect TID too; otherwise, we assume -1
632     if (!view.consume_front(".")) {
633       // update m_index
634       m_index += initial_length - view.size();
635 
636       return {{pid, AllThreads}};
637     }
638   }
639 
640   // thread identifier
641   if (view.consume_front("-1")) {
642     // -1 is a special case
643     tid = AllThreads;
644   } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) {
645     // not a valid hex integer OR tid 0 OR pid -1 + a specific tid
646     m_index = UINT64_MAX;
647     return llvm::None;
648   }
649 
650   // update m_index
651   m_index += initial_length - view.size();
652 
653   return {{pid, tid}};
654 }
655