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