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
27 if (m_packet.size() == 3 &&
28 isxdigit(m_packet[1]) &&
29 isxdigit(m_packet[2]))
34 if (m_packet.size() == 2 && m_packet[1] == 'K')
39 if (m_packet.size() == 1)
44 if (m_packet.size() == 1)
51 StringExtractorGDBRemote::ServerPacketType
52 StringExtractorGDBRemote::GetServerPacketType () const
54 #define PACKET_MATCHES(s) ((packet_size == (sizeof(s)-1)) && (strcmp((packet_cstr),(s)) == 0))
55 #define PACKET_STARTS_WITH(s) ((packet_size >= (sizeof(s)-1)) && ::strncmp(packet_cstr, s, (sizeof(s)-1))==0)
57 // Empty is not a supported packet...
59 return eServerPacketType_invalid;
61 const size_t packet_size = m_packet.size();
62 const char *packet_cstr = m_packet.c_str();
67 return eServerPacketType_notify;
70 if (packet_size == 1) return eServerPacketType_interrupt;
74 if (packet_size == 1) return eServerPacketType_nack;
78 if (packet_size == 1) return eServerPacketType_ack;
82 return eServerPacketType_A;
86 switch (packet_cstr[1])
89 if (PACKET_STARTS_WITH ("QEnvironment:")) return eServerPacketType_QEnvironment;
90 if (PACKET_STARTS_WITH ("QEnvironmentHexEncoded:")) return eServerPacketType_QEnvironmentHexEncoded;
94 if (PACKET_MATCHES ("QStartNoAckMode")) return eServerPacketType_QStartNoAckMode;
95 if (PACKET_STARTS_WITH ("QSaveRegisterState")) return eServerPacketType_QSaveRegisterState;
96 if (PACKET_STARTS_WITH ("QSetDisableASLR:")) return eServerPacketType_QSetDisableASLR;
97 if (PACKET_STARTS_WITH ("QSetDetachOnError:")) return eServerPacketType_QSetDetachOnError;
98 if (PACKET_STARTS_WITH ("QSetSTDIN:")) return eServerPacketType_QSetSTDIN;
99 if (PACKET_STARTS_WITH ("QSetSTDOUT:")) return eServerPacketType_QSetSTDOUT;
100 if (PACKET_STARTS_WITH ("QSetSTDERR:")) return eServerPacketType_QSetSTDERR;
101 if (PACKET_STARTS_WITH ("QSetWorkingDir:")) return eServerPacketType_QSetWorkingDir;
102 if (PACKET_STARTS_WITH ("QSetLogging:")) return eServerPacketType_QSetLogging;
103 if (PACKET_STARTS_WITH ("QSetMaxPacketSize:")) return eServerPacketType_QSetMaxPacketSize;
104 if (PACKET_STARTS_WITH ("QSetMaxPayloadSize:")) return eServerPacketType_QSetMaxPayloadSize;
105 if (PACKET_STARTS_WITH ("QSetEnableAsyncProfiling;")) return eServerPacketType_QSetEnableAsyncProfiling;
106 if (PACKET_STARTS_WITH ("QSyncThreadState:")) return eServerPacketType_QSyncThreadState;
110 if (PACKET_STARTS_WITH ("QLaunchArch:")) return eServerPacketType_QLaunchArch;
111 if (PACKET_MATCHES("QListThreadsInStopReply")) return eServerPacketType_QListThreadsInStopReply;
115 if (PACKET_STARTS_WITH ("QRestoreRegisterState:")) return eServerPacketType_QRestoreRegisterState;
119 if (PACKET_MATCHES ("QThreadSuffixSupported")) return eServerPacketType_QThreadSuffixSupported;
125 switch (packet_cstr[1])
128 if (PACKET_MATCHES ("qsProcessInfo")) return eServerPacketType_qsProcessInfo;
129 if (PACKET_MATCHES ("qsThreadInfo")) return eServerPacketType_qsThreadInfo;
133 if (PACKET_STARTS_WITH ("qfProcessInfo")) return eServerPacketType_qfProcessInfo;
134 if (PACKET_STARTS_WITH ("qfThreadInfo")) return eServerPacketType_qfThreadInfo;
138 if (packet_size == 2) return eServerPacketType_qC;
142 if (PACKET_STARTS_WITH ("qEcho:")) return eServerPacketType_qEcho;
146 if (PACKET_STARTS_WITH ("qFileLoadAddress:")) return eServerPacketType_qFileLoadAddress;
150 if (PACKET_STARTS_WITH ("qGroupName:")) return eServerPacketType_qGroupName;
151 if (PACKET_MATCHES ("qGetWorkingDir")) return eServerPacketType_qGetWorkingDir;
152 if (PACKET_MATCHES ("qGetPid")) return eServerPacketType_qGetPid;
153 if (PACKET_STARTS_WITH ("qGetProfileData;")) return eServerPacketType_qGetProfileData;
154 if (PACKET_MATCHES ("qGDBServerVersion")) return eServerPacketType_qGDBServerVersion;
158 if (PACKET_MATCHES ("qHostInfo")) return eServerPacketType_qHostInfo;
162 if (PACKET_STARTS_WITH ("qKillSpawnedProcess")) return eServerPacketType_qKillSpawnedProcess;
166 if (PACKET_STARTS_WITH ("qLaunchGDBServer")) return eServerPacketType_qLaunchGDBServer;
167 if (PACKET_MATCHES ("qLaunchSuccess")) return eServerPacketType_qLaunchSuccess;
171 if (PACKET_STARTS_WITH ("qMemoryRegionInfo:")) return eServerPacketType_qMemoryRegionInfo;
172 if (PACKET_MATCHES ("qMemoryRegionInfo")) return eServerPacketType_qMemoryRegionInfoSupported;
173 if (PACKET_STARTS_WITH ("qModuleInfo:")) return eServerPacketType_qModuleInfo;
177 if (PACKET_STARTS_WITH ("qProcessInfoPID:")) return eServerPacketType_qProcessInfoPID;
178 if (PACKET_STARTS_WITH ("qPlatform_shell:")) return eServerPacketType_qPlatform_shell;
179 if (PACKET_STARTS_WITH ("qPlatform_mkdir:")) return eServerPacketType_qPlatform_mkdir;
180 if (PACKET_STARTS_WITH ("qPlatform_chmod:")) return eServerPacketType_qPlatform_chmod;
181 if (PACKET_MATCHES ("qProcessInfo")) return eServerPacketType_qProcessInfo;
185 if (PACKET_MATCHES ("qQueryGDBServer")) return eServerPacketType_qQueryGDBServer;
189 if (PACKET_STARTS_WITH ("qRcmd,")) return eServerPacketType_qRcmd;
190 if (PACKET_STARTS_WITH ("qRegisterInfo")) return eServerPacketType_qRegisterInfo;
194 if (PACKET_STARTS_WITH ("qSpeedTest:")) return eServerPacketType_qSpeedTest;
195 if (PACKET_MATCHES ("qShlibInfoAddr")) return eServerPacketType_qShlibInfoAddr;
196 if (PACKET_MATCHES ("qStepPacketSupported")) return eServerPacketType_qStepPacketSupported;
197 if (PACKET_STARTS_WITH ("qSupported")) return eServerPacketType_qSupported;
198 if (PACKET_MATCHES ("qSyncThreadStateSupported")) return eServerPacketType_qSyncThreadStateSupported;
202 if (PACKET_STARTS_WITH ("qThreadExtraInfo,")) return eServerPacketType_qThreadExtraInfo;
203 if (PACKET_STARTS_WITH ("qThreadStopInfo")) return eServerPacketType_qThreadStopInfo;
207 if (PACKET_STARTS_WITH ("qUserName:")) return eServerPacketType_qUserName;
211 if (PACKET_MATCHES ("qVAttachOrWaitSupported")) return eServerPacketType_qVAttachOrWaitSupported;
215 if (PACKET_STARTS_WITH ("qWatchpointSupportInfo:")) return eServerPacketType_qWatchpointSupportInfo;
216 if (PACKET_MATCHES ("qWatchpointSupportInfo")) return eServerPacketType_qWatchpointSupportInfoSupported;
220 if (PACKET_STARTS_WITH ("qXfer:auxv:read::")) return eServerPacketType_qXfer_auxv_read;
226 if (PACKET_MATCHES("jSignalsInfo")) return eServerPacketType_jSignalsInfo;
227 if (PACKET_MATCHES("jThreadsInfo")) return eServerPacketType_jThreadsInfo;
231 if (PACKET_STARTS_WITH("vFile:"))
233 if (PACKET_STARTS_WITH("vFile:open:")) return eServerPacketType_vFile_open;
234 else if (PACKET_STARTS_WITH("vFile:close:")) return eServerPacketType_vFile_close;
235 else if (PACKET_STARTS_WITH("vFile:pread")) return eServerPacketType_vFile_pread;
236 else if (PACKET_STARTS_WITH("vFile:pwrite")) return eServerPacketType_vFile_pwrite;
237 else if (PACKET_STARTS_WITH("vFile:size")) return eServerPacketType_vFile_size;
238 else if (PACKET_STARTS_WITH("vFile:exists")) return eServerPacketType_vFile_exists;
239 else if (PACKET_STARTS_WITH("vFile:stat")) return eServerPacketType_vFile_stat;
240 else if (PACKET_STARTS_WITH("vFile:mode")) return eServerPacketType_vFile_mode;
241 else if (PACKET_STARTS_WITH("vFile:MD5")) return eServerPacketType_vFile_md5;
242 else if (PACKET_STARTS_WITH("vFile:symlink")) return eServerPacketType_vFile_symlink;
243 else if (PACKET_STARTS_WITH("vFile:unlink")) return eServerPacketType_vFile_unlink;
246 if (PACKET_STARTS_WITH ("vAttach;")) return eServerPacketType_vAttach;
247 if (PACKET_STARTS_WITH ("vAttachWait;")) return eServerPacketType_vAttachWait;
248 if (PACKET_STARTS_WITH ("vAttachOrWait;")) return eServerPacketType_vAttachOrWait;
249 if (PACKET_STARTS_WITH ("vAttachName;")) return eServerPacketType_vAttachName;
250 if (PACKET_STARTS_WITH("vCont;")) return eServerPacketType_vCont;
251 if (PACKET_MATCHES ("vCont?")) return eServerPacketType_vCont_actions;
255 switch (packet_cstr[1])
258 return eServerPacketType__M;
261 return eServerPacketType__m;
266 if (packet_size == 1) return eServerPacketType_stop_reason;
270 return eServerPacketType_c;
273 return eServerPacketType_C;
276 if (packet_size == 1) return eServerPacketType_D;
280 if (packet_size == 1) return eServerPacketType_g;
284 return eServerPacketType_G;
287 return eServerPacketType_H;
290 return eServerPacketType_I;
293 if (packet_size == 1) return eServerPacketType_k;
297 return eServerPacketType_m;
300 return eServerPacketType_M;
303 return eServerPacketType_p;
306 return eServerPacketType_P;
309 if (packet_size == 1) return eServerPacketType_s;
313 return eServerPacketType_S;
316 return eServerPacketType_x;
319 return eServerPacketType_X;
322 return eServerPacketType_T;
325 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
326 return eServerPacketType_z;
330 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
331 return eServerPacketType_Z;
334 return eServerPacketType_unimplemented;
338 StringExtractorGDBRemote::IsOKResponse() const
340 return GetResponseType () == eOK;
345 StringExtractorGDBRemote::IsUnsupportedResponse() const
347 return GetResponseType () == eUnsupported;
351 StringExtractorGDBRemote::IsNormalResponse() const
353 return GetResponseType () == eResponse;
357 StringExtractorGDBRemote::IsErrorResponse() const
359 return GetResponseType () == eError &&
360 m_packet.size() == 3 &&
361 isxdigit(m_packet[1]) &&
362 isxdigit(m_packet[2]);
366 StringExtractorGDBRemote::GetError ()
368 if (GetResponseType() == eError)
371 return GetHexU8(255);
377 StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)
379 // Just get the data bytes in the string as GDBRemoteCommunication::CheckForPacket()
380 // already removes any 0x7d escaped characters. If any 0x7d characters are left in
381 // the packet, then they are supposed to be there...
383 const size_t bytes_left = GetBytesLeft();
386 str.assign(m_packet, m_index, bytes_left);
387 m_index += bytes_left;
393 OKErrorNotSupportedResponseValidator(void *, const StringExtractorGDBRemote &response)
395 switch (response.GetResponseType())
397 case StringExtractorGDBRemote::eOK:
398 case StringExtractorGDBRemote::eError:
399 case StringExtractorGDBRemote::eUnsupported:
402 case StringExtractorGDBRemote::eAck:
403 case StringExtractorGDBRemote::eNack:
404 case StringExtractorGDBRemote::eResponse:
411 JSONResponseValidator(void *, const StringExtractorGDBRemote &response)
413 switch (response.GetResponseType())
415 case StringExtractorGDBRemote::eUnsupported:
416 case StringExtractorGDBRemote::eError:
417 return true; // Accept unsupported or EXX as valid responses
419 case StringExtractorGDBRemote::eOK:
420 case StringExtractorGDBRemote::eAck:
421 case StringExtractorGDBRemote::eNack:
424 case StringExtractorGDBRemote::eResponse:
425 // JSON that is returned in from JSON query packets is currently always
426 // either a dictionary which starts with a '{', or an array which
427 // starts with a '['. This is a quick validator to just make sure the
428 // response could be valid JSON without having to validate all of the
430 switch (response.GetStringRef()[0])
432 case '{': return true;
433 case '[': return true;
443 ASCIIHexBytesResponseValidator(void *, const StringExtractorGDBRemote &response)
445 switch (response.GetResponseType())
447 case StringExtractorGDBRemote::eUnsupported:
448 case StringExtractorGDBRemote::eError:
449 return true; // Accept unsupported or EXX as valid responses
451 case StringExtractorGDBRemote::eOK:
452 case StringExtractorGDBRemote::eAck:
453 case StringExtractorGDBRemote::eNack:
456 case StringExtractorGDBRemote::eResponse:
458 uint32_t valid_count = 0;
459 for (const char ch : response.GetStringRef())
465 if (++valid_count >= 16)
466 break; // Don't validate all the characters in case the packet is very large
476 StringExtractorGDBRemote::CopyResponseValidator(const StringExtractorGDBRemote& rhs)
478 m_validator = rhs.m_validator;
479 m_validator_baton = rhs.m_validator_baton;
483 StringExtractorGDBRemote::SetResponseValidator(ResponseValidatorCallback callback, void *baton)
485 m_validator = callback;
486 m_validator_baton = baton;
490 StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported()
492 m_validator = OKErrorNotSupportedResponseValidator;
493 m_validator_baton = nullptr;
497 StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes()
499 m_validator = ASCIIHexBytesResponseValidator;
500 m_validator_baton = nullptr;
504 StringExtractorGDBRemote::SetResponseValidatorToJSON()
506 m_validator = JSONResponseValidator;
507 m_validator_baton = nullptr;
511 StringExtractorGDBRemote::ValidateResponse() const
513 // If we have a validator callback, try to validate the callback
515 return m_validator(m_validator_baton, *this);
517 return true; // No validator, so response is valid