1 //===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 // Other libraries and framework includes
16 #include "Utility/StringExtractorGDBRemote.h"
18 StringExtractorGDBRemote::ResponseType
19 StringExtractorGDBRemote::GetResponseType() const {
23 switch (m_packet[0]) {
25 if (m_packet.size() == 3 && isxdigit(m_packet[1]) && isxdigit(m_packet[2]))
30 if (m_packet.size() == 2 && m_packet[1] == 'K')
35 if (m_packet.size() == 1)
40 if (m_packet.size() == 1)
47 StringExtractorGDBRemote::ServerPacketType
48 StringExtractorGDBRemote::GetServerPacketType() const {
49 #define PACKET_MATCHES(s) \
50 ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0))
51 #define PACKET_STARTS_WITH(s) \
52 ((packet_size >= (sizeof(s) - 1)) && \
53 ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0)
55 // Empty is not a supported packet...
57 return eServerPacketType_invalid;
59 const size_t packet_size = m_packet.size();
60 const char *packet_cstr = m_packet.c_str();
61 switch (m_packet[0]) {
64 return eServerPacketType_notify;
68 return eServerPacketType_interrupt;
73 return eServerPacketType_nack;
78 return eServerPacketType_ack;
82 return eServerPacketType_A;
86 switch (packet_cstr[1]) {
88 if (PACKET_STARTS_WITH("QEnvironment:"))
89 return eServerPacketType_QEnvironment;
90 if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:"))
91 return eServerPacketType_QEnvironmentHexEncoded;
95 if (PACKET_MATCHES("QStartNoAckMode"))
96 return eServerPacketType_QStartNoAckMode;
97 if (PACKET_STARTS_WITH("QSaveRegisterState"))
98 return eServerPacketType_QSaveRegisterState;
99 if (PACKET_STARTS_WITH("QSetDisableASLR:"))
100 return eServerPacketType_QSetDisableASLR;
101 if (PACKET_STARTS_WITH("QSetDetachOnError:"))
102 return eServerPacketType_QSetDetachOnError;
103 if (PACKET_STARTS_WITH("QSetSTDIN:"))
104 return eServerPacketType_QSetSTDIN;
105 if (PACKET_STARTS_WITH("QSetSTDOUT:"))
106 return eServerPacketType_QSetSTDOUT;
107 if (PACKET_STARTS_WITH("QSetSTDERR:"))
108 return eServerPacketType_QSetSTDERR;
109 if (PACKET_STARTS_WITH("QSetWorkingDir:"))
110 return eServerPacketType_QSetWorkingDir;
111 if (PACKET_STARTS_WITH("QSetLogging:"))
112 return eServerPacketType_QSetLogging;
113 if (PACKET_STARTS_WITH("QSetMaxPacketSize:"))
114 return eServerPacketType_QSetMaxPacketSize;
115 if (PACKET_STARTS_WITH("QSetMaxPayloadSize:"))
116 return eServerPacketType_QSetMaxPayloadSize;
117 if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;"))
118 return eServerPacketType_QSetEnableAsyncProfiling;
119 if (PACKET_STARTS_WITH("QSyncThreadState:"))
120 return eServerPacketType_QSyncThreadState;
124 if (PACKET_STARTS_WITH("QLaunchArch:"))
125 return eServerPacketType_QLaunchArch;
126 if (PACKET_MATCHES("QListThreadsInStopReply"))
127 return eServerPacketType_QListThreadsInStopReply;
131 if (PACKET_STARTS_WITH("QRestoreRegisterState:"))
132 return eServerPacketType_QRestoreRegisterState;
136 if (PACKET_MATCHES("QThreadSuffixSupported"))
137 return eServerPacketType_QThreadSuffixSupported;
143 switch (packet_cstr[1]) {
145 if (PACKET_MATCHES("qsProcessInfo"))
146 return eServerPacketType_qsProcessInfo;
147 if (PACKET_MATCHES("qsThreadInfo"))
148 return eServerPacketType_qsThreadInfo;
152 if (PACKET_STARTS_WITH("qfProcessInfo"))
153 return eServerPacketType_qfProcessInfo;
154 if (PACKET_STARTS_WITH("qfThreadInfo"))
155 return eServerPacketType_qfThreadInfo;
159 if (packet_size == 2)
160 return eServerPacketType_qC;
164 if (PACKET_STARTS_WITH("qEcho:"))
165 return eServerPacketType_qEcho;
169 if (PACKET_STARTS_WITH("qFileLoadAddress:"))
170 return eServerPacketType_qFileLoadAddress;
174 if (PACKET_STARTS_WITH("qGroupName:"))
175 return eServerPacketType_qGroupName;
176 if (PACKET_MATCHES("qGetWorkingDir"))
177 return eServerPacketType_qGetWorkingDir;
178 if (PACKET_MATCHES("qGetPid"))
179 return eServerPacketType_qGetPid;
180 if (PACKET_STARTS_WITH("qGetProfileData;"))
181 return eServerPacketType_qGetProfileData;
182 if (PACKET_MATCHES("qGDBServerVersion"))
183 return eServerPacketType_qGDBServerVersion;
187 if (PACKET_MATCHES("qHostInfo"))
188 return eServerPacketType_qHostInfo;
192 if (PACKET_STARTS_WITH("qKillSpawnedProcess"))
193 return eServerPacketType_qKillSpawnedProcess;
197 if (PACKET_STARTS_WITH("qLaunchGDBServer"))
198 return eServerPacketType_qLaunchGDBServer;
199 if (PACKET_MATCHES("qLaunchSuccess"))
200 return eServerPacketType_qLaunchSuccess;
204 if (PACKET_STARTS_WITH("qMemoryRegionInfo:"))
205 return eServerPacketType_qMemoryRegionInfo;
206 if (PACKET_MATCHES("qMemoryRegionInfo"))
207 return eServerPacketType_qMemoryRegionInfoSupported;
208 if (PACKET_STARTS_WITH("qModuleInfo:"))
209 return eServerPacketType_qModuleInfo;
213 if (PACKET_STARTS_WITH("qProcessInfoPID:"))
214 return eServerPacketType_qProcessInfoPID;
215 if (PACKET_STARTS_WITH("qPlatform_shell:"))
216 return eServerPacketType_qPlatform_shell;
217 if (PACKET_STARTS_WITH("qPlatform_mkdir:"))
218 return eServerPacketType_qPlatform_mkdir;
219 if (PACKET_STARTS_WITH("qPlatform_chmod:"))
220 return eServerPacketType_qPlatform_chmod;
221 if (PACKET_MATCHES("qProcessInfo"))
222 return eServerPacketType_qProcessInfo;
226 if (PACKET_MATCHES("qQueryGDBServer"))
227 return eServerPacketType_qQueryGDBServer;
231 if (PACKET_STARTS_WITH("qRcmd,"))
232 return eServerPacketType_qRcmd;
233 if (PACKET_STARTS_WITH("qRegisterInfo"))
234 return eServerPacketType_qRegisterInfo;
238 if (PACKET_STARTS_WITH("qSpeedTest:"))
239 return eServerPacketType_qSpeedTest;
240 if (PACKET_MATCHES("qShlibInfoAddr"))
241 return eServerPacketType_qShlibInfoAddr;
242 if (PACKET_MATCHES("qStepPacketSupported"))
243 return eServerPacketType_qStepPacketSupported;
244 if (PACKET_STARTS_WITH("qSupported"))
245 return eServerPacketType_qSupported;
246 if (PACKET_MATCHES("qSyncThreadStateSupported"))
247 return eServerPacketType_qSyncThreadStateSupported;
251 if (PACKET_STARTS_WITH("qThreadExtraInfo,"))
252 return eServerPacketType_qThreadExtraInfo;
253 if (PACKET_STARTS_WITH("qThreadStopInfo"))
254 return eServerPacketType_qThreadStopInfo;
258 if (PACKET_STARTS_WITH("qUserName:"))
259 return eServerPacketType_qUserName;
263 if (PACKET_MATCHES("qVAttachOrWaitSupported"))
264 return eServerPacketType_qVAttachOrWaitSupported;
268 if (PACKET_STARTS_WITH("qWatchpointSupportInfo:"))
269 return eServerPacketType_qWatchpointSupportInfo;
270 if (PACKET_MATCHES("qWatchpointSupportInfo"))
271 return eServerPacketType_qWatchpointSupportInfoSupported;
275 if (PACKET_STARTS_WITH("qXfer:auxv:read::"))
276 return eServerPacketType_qXfer_auxv_read;
282 if (PACKET_STARTS_WITH("jModulesInfo:"))
283 return eServerPacketType_jModulesInfo;
284 if (PACKET_MATCHES("jSignalsInfo"))
285 return eServerPacketType_jSignalsInfo;
286 if (PACKET_MATCHES("jThreadsInfo"))
287 return eServerPacketType_jThreadsInfo;
291 if (PACKET_STARTS_WITH("vFile:")) {
292 if (PACKET_STARTS_WITH("vFile:open:"))
293 return eServerPacketType_vFile_open;
294 else if (PACKET_STARTS_WITH("vFile:close:"))
295 return eServerPacketType_vFile_close;
296 else if (PACKET_STARTS_WITH("vFile:pread"))
297 return eServerPacketType_vFile_pread;
298 else if (PACKET_STARTS_WITH("vFile:pwrite"))
299 return eServerPacketType_vFile_pwrite;
300 else if (PACKET_STARTS_WITH("vFile:size"))
301 return eServerPacketType_vFile_size;
302 else if (PACKET_STARTS_WITH("vFile:exists"))
303 return eServerPacketType_vFile_exists;
304 else if (PACKET_STARTS_WITH("vFile:stat"))
305 return eServerPacketType_vFile_stat;
306 else if (PACKET_STARTS_WITH("vFile:mode"))
307 return eServerPacketType_vFile_mode;
308 else if (PACKET_STARTS_WITH("vFile:MD5"))
309 return eServerPacketType_vFile_md5;
310 else if (PACKET_STARTS_WITH("vFile:symlink"))
311 return eServerPacketType_vFile_symlink;
312 else if (PACKET_STARTS_WITH("vFile:unlink"))
313 return eServerPacketType_vFile_unlink;
316 if (PACKET_STARTS_WITH("vAttach;"))
317 return eServerPacketType_vAttach;
318 if (PACKET_STARTS_WITH("vAttachWait;"))
319 return eServerPacketType_vAttachWait;
320 if (PACKET_STARTS_WITH("vAttachOrWait;"))
321 return eServerPacketType_vAttachOrWait;
322 if (PACKET_STARTS_WITH("vAttachName;"))
323 return eServerPacketType_vAttachName;
324 if (PACKET_STARTS_WITH("vCont;"))
325 return eServerPacketType_vCont;
326 if (PACKET_MATCHES("vCont?"))
327 return eServerPacketType_vCont_actions;
331 switch (packet_cstr[1]) {
333 return eServerPacketType__M;
336 return eServerPacketType__m;
341 if (packet_size == 1)
342 return eServerPacketType_stop_reason;
346 return eServerPacketType_c;
349 return eServerPacketType_C;
352 if (packet_size == 1)
353 return eServerPacketType_D;
357 if (packet_size == 1)
358 return eServerPacketType_g;
362 return eServerPacketType_G;
365 return eServerPacketType_H;
368 return eServerPacketType_I;
371 if (packet_size == 1)
372 return eServerPacketType_k;
376 return eServerPacketType_m;
379 return eServerPacketType_M;
382 return eServerPacketType_p;
385 return eServerPacketType_P;
388 if (packet_size == 1)
389 return eServerPacketType_s;
393 return eServerPacketType_S;
396 return eServerPacketType_x;
399 return eServerPacketType_X;
402 return eServerPacketType_T;
405 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
406 return eServerPacketType_z;
410 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
411 return eServerPacketType_Z;
414 return eServerPacketType_unimplemented;
417 bool StringExtractorGDBRemote::IsOKResponse() const {
418 return GetResponseType() == eOK;
421 bool StringExtractorGDBRemote::IsUnsupportedResponse() const {
422 return GetResponseType() == eUnsupported;
425 bool StringExtractorGDBRemote::IsNormalResponse() const {
426 return GetResponseType() == eResponse;
429 bool StringExtractorGDBRemote::IsErrorResponse() const {
430 return GetResponseType() == eError && m_packet.size() == 3 &&
431 isxdigit(m_packet[1]) && isxdigit(m_packet[2]);
434 uint8_t StringExtractorGDBRemote::GetError() {
435 if (GetResponseType() == eError) {
437 return GetHexU8(255);
442 size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
443 // Just get the data bytes in the string as
444 // GDBRemoteCommunication::CheckForPacket()
445 // already removes any 0x7d escaped characters. If any 0x7d characters are
447 // the packet, then they are supposed to be there...
449 const size_t bytes_left = GetBytesLeft();
450 if (bytes_left > 0) {
451 str.assign(m_packet, m_index, bytes_left);
452 m_index += bytes_left;
458 OKErrorNotSupportedResponseValidator(void *,
459 const StringExtractorGDBRemote &response) {
460 switch (response.GetResponseType()) {
461 case StringExtractorGDBRemote::eOK:
462 case StringExtractorGDBRemote::eError:
463 case StringExtractorGDBRemote::eUnsupported:
466 case StringExtractorGDBRemote::eAck:
467 case StringExtractorGDBRemote::eNack:
468 case StringExtractorGDBRemote::eResponse:
474 static bool JSONResponseValidator(void *,
475 const StringExtractorGDBRemote &response) {
476 switch (response.GetResponseType()) {
477 case StringExtractorGDBRemote::eUnsupported:
478 case StringExtractorGDBRemote::eError:
479 return true; // Accept unsupported or EXX as valid responses
481 case StringExtractorGDBRemote::eOK:
482 case StringExtractorGDBRemote::eAck:
483 case StringExtractorGDBRemote::eNack:
486 case StringExtractorGDBRemote::eResponse:
487 // JSON that is returned in from JSON query packets is currently always
488 // either a dictionary which starts with a '{', or an array which
489 // starts with a '['. This is a quick validator to just make sure the
490 // response could be valid JSON without having to validate all of the
492 switch (response.GetStringRef()[0]) {
506 ASCIIHexBytesResponseValidator(void *,
507 const StringExtractorGDBRemote &response) {
508 switch (response.GetResponseType()) {
509 case StringExtractorGDBRemote::eUnsupported:
510 case StringExtractorGDBRemote::eError:
511 return true; // Accept unsupported or EXX as valid responses
513 case StringExtractorGDBRemote::eOK:
514 case StringExtractorGDBRemote::eAck:
515 case StringExtractorGDBRemote::eNack:
518 case StringExtractorGDBRemote::eResponse: {
519 uint32_t valid_count = 0;
520 for (const char ch : response.GetStringRef()) {
524 if (++valid_count >= 16)
525 break; // Don't validate all the characters in case the packet is very
534 void StringExtractorGDBRemote::CopyResponseValidator(
535 const StringExtractorGDBRemote &rhs) {
536 m_validator = rhs.m_validator;
537 m_validator_baton = rhs.m_validator_baton;
540 void StringExtractorGDBRemote::SetResponseValidator(
541 ResponseValidatorCallback callback, void *baton) {
542 m_validator = callback;
543 m_validator_baton = baton;
546 void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() {
547 m_validator = OKErrorNotSupportedResponseValidator;
548 m_validator_baton = nullptr;
551 void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() {
552 m_validator = ASCIIHexBytesResponseValidator;
553 m_validator_baton = nullptr;
556 void StringExtractorGDBRemote::SetResponseValidatorToJSON() {
557 m_validator = JSONResponseValidator;
558 m_validator_baton = nullptr;
561 bool StringExtractorGDBRemote::ValidateResponse() const {
562 // If we have a validator callback, try to validate the callback
564 return m_validator(m_validator_baton, *this);
566 return true; // No validator, so response is valid