]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r305575, and update
[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     if (PACKET_STARTS_WITH("jTraceBufferRead:"))
290       return eServerPacketType_jTraceBufferRead;
291     if (PACKET_STARTS_WITH("jTraceConfigRead:"))
292       return eServerPacketType_jTraceConfigRead;
293     if (PACKET_STARTS_WITH("jTraceMetaRead:"))
294       return eServerPacketType_jTraceMetaRead;
295     if (PACKET_STARTS_WITH("jTraceStart:"))
296       return eServerPacketType_jTraceStart;
297     if (PACKET_STARTS_WITH("jTraceStop:"))
298       return eServerPacketType_jTraceStop;
299     break;
300
301   case 'v':
302     if (PACKET_STARTS_WITH("vFile:")) {
303       if (PACKET_STARTS_WITH("vFile:open:"))
304         return eServerPacketType_vFile_open;
305       else if (PACKET_STARTS_WITH("vFile:close:"))
306         return eServerPacketType_vFile_close;
307       else if (PACKET_STARTS_WITH("vFile:pread"))
308         return eServerPacketType_vFile_pread;
309       else if (PACKET_STARTS_WITH("vFile:pwrite"))
310         return eServerPacketType_vFile_pwrite;
311       else if (PACKET_STARTS_WITH("vFile:size"))
312         return eServerPacketType_vFile_size;
313       else if (PACKET_STARTS_WITH("vFile:exists"))
314         return eServerPacketType_vFile_exists;
315       else if (PACKET_STARTS_WITH("vFile:stat"))
316         return eServerPacketType_vFile_stat;
317       else if (PACKET_STARTS_WITH("vFile:mode"))
318         return eServerPacketType_vFile_mode;
319       else if (PACKET_STARTS_WITH("vFile:MD5"))
320         return eServerPacketType_vFile_md5;
321       else if (PACKET_STARTS_WITH("vFile:symlink"))
322         return eServerPacketType_vFile_symlink;
323       else if (PACKET_STARTS_WITH("vFile:unlink"))
324         return eServerPacketType_vFile_unlink;
325
326     } else {
327       if (PACKET_STARTS_WITH("vAttach;"))
328         return eServerPacketType_vAttach;
329       if (PACKET_STARTS_WITH("vAttachWait;"))
330         return eServerPacketType_vAttachWait;
331       if (PACKET_STARTS_WITH("vAttachOrWait;"))
332         return eServerPacketType_vAttachOrWait;
333       if (PACKET_STARTS_WITH("vAttachName;"))
334         return eServerPacketType_vAttachName;
335       if (PACKET_STARTS_WITH("vCont;"))
336         return eServerPacketType_vCont;
337       if (PACKET_MATCHES("vCont?"))
338         return eServerPacketType_vCont_actions;
339     }
340     break;
341   case '_':
342     switch (packet_cstr[1]) {
343     case 'M':
344       return eServerPacketType__M;
345
346     case 'm':
347       return eServerPacketType__m;
348     }
349     break;
350
351   case '?':
352     if (packet_size == 1)
353       return eServerPacketType_stop_reason;
354     break;
355
356   case 'c':
357     return eServerPacketType_c;
358
359   case 'C':
360     return eServerPacketType_C;
361
362   case 'D':
363     if (packet_size == 1)
364       return eServerPacketType_D;
365     break;
366
367   case 'g':
368     if (packet_size == 1)
369       return eServerPacketType_g;
370     break;
371
372   case 'G':
373     return eServerPacketType_G;
374
375   case 'H':
376     return eServerPacketType_H;
377
378   case 'I':
379     return eServerPacketType_I;
380
381   case 'k':
382     if (packet_size == 1)
383       return eServerPacketType_k;
384     break;
385
386   case 'm':
387     return eServerPacketType_m;
388
389   case 'M':
390     return eServerPacketType_M;
391
392   case 'p':
393     return eServerPacketType_p;
394
395   case 'P':
396     return eServerPacketType_P;
397
398   case 's':
399     if (packet_size == 1)
400       return eServerPacketType_s;
401     break;
402
403   case 'S':
404     return eServerPacketType_S;
405
406   case 'x':
407     return eServerPacketType_x;
408
409   case 'X':
410     return eServerPacketType_X;
411
412   case 'T':
413     return eServerPacketType_T;
414
415   case 'z':
416     if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
417       return eServerPacketType_z;
418     break;
419
420   case 'Z':
421     if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
422       return eServerPacketType_Z;
423     break;
424   }
425   return eServerPacketType_unimplemented;
426 }
427
428 bool StringExtractorGDBRemote::IsOKResponse() const {
429   return GetResponseType() == eOK;
430 }
431
432 bool StringExtractorGDBRemote::IsUnsupportedResponse() const {
433   return GetResponseType() == eUnsupported;
434 }
435
436 bool StringExtractorGDBRemote::IsNormalResponse() const {
437   return GetResponseType() == eResponse;
438 }
439
440 bool StringExtractorGDBRemote::IsErrorResponse() const {
441   return GetResponseType() == eError && m_packet.size() == 3 &&
442          isxdigit(m_packet[1]) && isxdigit(m_packet[2]);
443 }
444
445 uint8_t StringExtractorGDBRemote::GetError() {
446   if (GetResponseType() == eError) {
447     SetFilePos(1);
448     return GetHexU8(255);
449   }
450   return 0;
451 }
452
453 size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
454   // Just get the data bytes in the string as
455   // GDBRemoteCommunication::CheckForPacket()
456   // already removes any 0x7d escaped characters. If any 0x7d characters are
457   // left in
458   // the packet, then they are supposed to be there...
459   str.clear();
460   const size_t bytes_left = GetBytesLeft();
461   if (bytes_left > 0) {
462     str.assign(m_packet, m_index, bytes_left);
463     m_index += bytes_left;
464   }
465   return str.size();
466 }
467
468 static bool
469 OKErrorNotSupportedResponseValidator(void *,
470                                      const StringExtractorGDBRemote &response) {
471   switch (response.GetResponseType()) {
472   case StringExtractorGDBRemote::eOK:
473   case StringExtractorGDBRemote::eError:
474   case StringExtractorGDBRemote::eUnsupported:
475     return true;
476
477   case StringExtractorGDBRemote::eAck:
478   case StringExtractorGDBRemote::eNack:
479   case StringExtractorGDBRemote::eResponse:
480     break;
481   }
482   return false;
483 }
484
485 static bool JSONResponseValidator(void *,
486                                   const StringExtractorGDBRemote &response) {
487   switch (response.GetResponseType()) {
488   case StringExtractorGDBRemote::eUnsupported:
489   case StringExtractorGDBRemote::eError:
490     return true; // Accept unsupported or EXX as valid responses
491
492   case StringExtractorGDBRemote::eOK:
493   case StringExtractorGDBRemote::eAck:
494   case StringExtractorGDBRemote::eNack:
495     break;
496
497   case StringExtractorGDBRemote::eResponse:
498     // JSON that is returned in from JSON query packets is currently always
499     // either a dictionary which starts with a '{', or an array which
500     // starts with a '['. This is a quick validator to just make sure the
501     // response could be valid JSON without having to validate all of the
502     // JSON content.
503     switch (response.GetStringRef()[0]) {
504     case '{':
505       return true;
506     case '[':
507       return true;
508     default:
509       break;
510     }
511     break;
512   }
513   return false;
514 }
515
516 static bool
517 ASCIIHexBytesResponseValidator(void *,
518                                const StringExtractorGDBRemote &response) {
519   switch (response.GetResponseType()) {
520   case StringExtractorGDBRemote::eUnsupported:
521   case StringExtractorGDBRemote::eError:
522     return true; // Accept unsupported or EXX as valid responses
523
524   case StringExtractorGDBRemote::eOK:
525   case StringExtractorGDBRemote::eAck:
526   case StringExtractorGDBRemote::eNack:
527     break;
528
529   case StringExtractorGDBRemote::eResponse: {
530     uint32_t valid_count = 0;
531     for (const char ch : response.GetStringRef()) {
532       if (!isxdigit(ch)) {
533         return false;
534       }
535       if (++valid_count >= 16)
536         break; // Don't validate all the characters in case the packet is very
537                // large
538     }
539     return true;
540   } break;
541   }
542   return false;
543 }
544
545 void StringExtractorGDBRemote::CopyResponseValidator(
546     const StringExtractorGDBRemote &rhs) {
547   m_validator = rhs.m_validator;
548   m_validator_baton = rhs.m_validator_baton;
549 }
550
551 void StringExtractorGDBRemote::SetResponseValidator(
552     ResponseValidatorCallback callback, void *baton) {
553   m_validator = callback;
554   m_validator_baton = baton;
555 }
556
557 void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() {
558   m_validator = OKErrorNotSupportedResponseValidator;
559   m_validator_baton = nullptr;
560 }
561
562 void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() {
563   m_validator = ASCIIHexBytesResponseValidator;
564   m_validator_baton = nullptr;
565 }
566
567 void StringExtractorGDBRemote::SetResponseValidatorToJSON() {
568   m_validator = JSONResponseValidator;
569   m_validator_baton = nullptr;
570 }
571
572 bool StringExtractorGDBRemote::ValidateResponse() const {
573   // If we have a validator callback, try to validate the callback
574   if (m_validator)
575     return m_validator(m_validator_baton, *this);
576   else
577     return true; // No validator, so response is valid
578 }