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