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