1 //===-- StringExtractorGDBRemote.cpp --------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/StringExtractorGDBRemote.h" 10 11 #include <cctype> 12 #include <cstring> 13 14 constexpr lldb::pid_t StringExtractorGDBRemote::AllProcesses; 15 constexpr lldb::tid_t StringExtractorGDBRemote::AllThreads; 16 17 StringExtractorGDBRemote::ResponseType 18 StringExtractorGDBRemote::GetResponseType() const { 19 if (m_packet.empty()) 20 return eUnsupported; 21 22 switch (m_packet[0]) { 23 case 'E': 24 if (isxdigit(m_packet[1]) && isxdigit(m_packet[2])) { 25 if (m_packet.size() == 3) 26 return eError; 27 llvm::StringRef packet_ref(m_packet); 28 if (packet_ref[3] == ';') { 29 auto err_string = packet_ref.substr(4); 30 for (auto e : err_string) 31 if (!isxdigit(e)) 32 return eResponse; 33 return eError; 34 } 35 } 36 break; 37 38 case 'O': 39 if (m_packet.size() == 2 && m_packet[1] == 'K') 40 return eOK; 41 break; 42 43 case '+': 44 if (m_packet.size() == 1) 45 return eAck; 46 break; 47 48 case '-': 49 if (m_packet.size() == 1) 50 return eNack; 51 break; 52 } 53 return eResponse; 54 } 55 56 StringExtractorGDBRemote::ServerPacketType 57 StringExtractorGDBRemote::GetServerPacketType() const { 58 #define PACKET_MATCHES(s) \ 59 ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0)) 60 #define PACKET_STARTS_WITH(s) \ 61 ((packet_size >= (sizeof(s) - 1)) && \ 62 ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0) 63 64 // Empty is not a supported packet... 65 if (m_packet.empty()) 66 return eServerPacketType_invalid; 67 68 const size_t packet_size = m_packet.size(); 69 const char *packet_cstr = m_packet.c_str(); 70 switch (m_packet[0]) { 71 72 case '%': 73 return eServerPacketType_notify; 74 75 case '\x03': 76 if (packet_size == 1) 77 return eServerPacketType_interrupt; 78 break; 79 80 case '-': 81 if (packet_size == 1) 82 return eServerPacketType_nack; 83 break; 84 85 case '+': 86 if (packet_size == 1) 87 return eServerPacketType_ack; 88 break; 89 90 case 'A': 91 return eServerPacketType_A; 92 93 case 'Q': 94 95 switch (packet_cstr[1]) { 96 case 'E': 97 if (PACKET_STARTS_WITH("QEnvironment:")) 98 return eServerPacketType_QEnvironment; 99 if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:")) 100 return eServerPacketType_QEnvironmentHexEncoded; 101 if (PACKET_STARTS_WITH("QEnableErrorStrings")) 102 return eServerPacketType_QEnableErrorStrings; 103 break; 104 105 case 'P': 106 if (PACKET_STARTS_WITH("QPassSignals:")) 107 return eServerPacketType_QPassSignals; 108 break; 109 110 case 'S': 111 if (PACKET_MATCHES("QStartNoAckMode")) 112 return eServerPacketType_QStartNoAckMode; 113 if (PACKET_STARTS_WITH("QSaveRegisterState")) 114 return eServerPacketType_QSaveRegisterState; 115 if (PACKET_STARTS_WITH("QSetDisableASLR:")) 116 return eServerPacketType_QSetDisableASLR; 117 if (PACKET_STARTS_WITH("QSetDetachOnError:")) 118 return eServerPacketType_QSetDetachOnError; 119 if (PACKET_STARTS_WITH("QSetSTDIN:")) 120 return eServerPacketType_QSetSTDIN; 121 if (PACKET_STARTS_WITH("QSetSTDOUT:")) 122 return eServerPacketType_QSetSTDOUT; 123 if (PACKET_STARTS_WITH("QSetSTDERR:")) 124 return eServerPacketType_QSetSTDERR; 125 if (PACKET_STARTS_WITH("QSetWorkingDir:")) 126 return eServerPacketType_QSetWorkingDir; 127 if (PACKET_STARTS_WITH("QSetLogging:")) 128 return eServerPacketType_QSetLogging; 129 if (PACKET_STARTS_WITH("QSetIgnoredExceptions")) 130 return eServerPacketType_QSetIgnoredExceptions; 131 if (PACKET_STARTS_WITH("QSetMaxPacketSize:")) 132 return eServerPacketType_QSetMaxPacketSize; 133 if (PACKET_STARTS_WITH("QSetMaxPayloadSize:")) 134 return eServerPacketType_QSetMaxPayloadSize; 135 if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;")) 136 return eServerPacketType_QSetEnableAsyncProfiling; 137 if (PACKET_STARTS_WITH("QSyncThreadState:")) 138 return eServerPacketType_QSyncThreadState; 139 break; 140 141 case 'L': 142 if (PACKET_STARTS_WITH("QLaunchArch:")) 143 return eServerPacketType_QLaunchArch; 144 if (PACKET_MATCHES("QListThreadsInStopReply")) 145 return eServerPacketType_QListThreadsInStopReply; 146 break; 147 148 case 'M': 149 if (PACKET_STARTS_WITH("QMemTags")) 150 return eServerPacketType_QMemTags; 151 break; 152 153 case 'N': 154 if (PACKET_STARTS_WITH("QNonStop:")) 155 return eServerPacketType_QNonStop; 156 break; 157 158 case 'R': 159 if (PACKET_STARTS_WITH("QRestoreRegisterState:")) 160 return eServerPacketType_QRestoreRegisterState; 161 break; 162 163 case 'T': 164 if (PACKET_MATCHES("QThreadSuffixSupported")) 165 return eServerPacketType_QThreadSuffixSupported; 166 break; 167 } 168 break; 169 170 case 'q': 171 switch (packet_cstr[1]) { 172 case 's': 173 if (PACKET_MATCHES("qsProcessInfo")) 174 return eServerPacketType_qsProcessInfo; 175 if (PACKET_MATCHES("qsThreadInfo")) 176 return eServerPacketType_qsThreadInfo; 177 break; 178 179 case 'f': 180 if (PACKET_STARTS_WITH("qfProcessInfo")) 181 return eServerPacketType_qfProcessInfo; 182 if (PACKET_STARTS_WITH("qfThreadInfo")) 183 return eServerPacketType_qfThreadInfo; 184 break; 185 186 case 'C': 187 if (packet_size == 2) 188 return eServerPacketType_qC; 189 break; 190 191 case 'E': 192 if (PACKET_STARTS_WITH("qEcho:")) 193 return eServerPacketType_qEcho; 194 break; 195 196 case 'F': 197 if (PACKET_STARTS_WITH("qFileLoadAddress:")) 198 return eServerPacketType_qFileLoadAddress; 199 break; 200 201 case 'G': 202 if (PACKET_STARTS_WITH("qGroupName:")) 203 return eServerPacketType_qGroupName; 204 if (PACKET_MATCHES("qGetWorkingDir")) 205 return eServerPacketType_qGetWorkingDir; 206 if (PACKET_MATCHES("qGetPid")) 207 return eServerPacketType_qGetPid; 208 if (PACKET_STARTS_WITH("qGetProfileData;")) 209 return eServerPacketType_qGetProfileData; 210 if (PACKET_MATCHES("qGDBServerVersion")) 211 return eServerPacketType_qGDBServerVersion; 212 break; 213 214 case 'H': 215 if (PACKET_MATCHES("qHostInfo")) 216 return eServerPacketType_qHostInfo; 217 break; 218 219 case 'K': 220 if (PACKET_STARTS_WITH("qKillSpawnedProcess")) 221 return eServerPacketType_qKillSpawnedProcess; 222 break; 223 224 case 'L': 225 if (PACKET_STARTS_WITH("qLaunchGDBServer")) 226 return eServerPacketType_qLaunchGDBServer; 227 if (PACKET_MATCHES("qLaunchSuccess")) 228 return eServerPacketType_qLaunchSuccess; 229 break; 230 231 case 'M': 232 if (PACKET_STARTS_WITH("qMemoryRegionInfo:")) 233 return eServerPacketType_qMemoryRegionInfo; 234 if (PACKET_MATCHES("qMemoryRegionInfo")) 235 return eServerPacketType_qMemoryRegionInfoSupported; 236 if (PACKET_STARTS_WITH("qModuleInfo:")) 237 return eServerPacketType_qModuleInfo; 238 if (PACKET_STARTS_WITH("qMemTags:")) 239 return eServerPacketType_qMemTags; 240 break; 241 242 case 'P': 243 if (PACKET_STARTS_WITH("qProcessInfoPID:")) 244 return eServerPacketType_qProcessInfoPID; 245 if (PACKET_STARTS_WITH("qPlatform_shell:")) 246 return eServerPacketType_qPlatform_shell; 247 if (PACKET_STARTS_WITH("qPlatform_mkdir:")) 248 return eServerPacketType_qPlatform_mkdir; 249 if (PACKET_STARTS_WITH("qPlatform_chmod:")) 250 return eServerPacketType_qPlatform_chmod; 251 if (PACKET_MATCHES("qProcessInfo")) 252 return eServerPacketType_qProcessInfo; 253 if (PACKET_STARTS_WITH("qPathComplete:")) 254 return eServerPacketType_qPathComplete; 255 break; 256 257 case 'Q': 258 if (PACKET_MATCHES("qQueryGDBServer")) 259 return eServerPacketType_qQueryGDBServer; 260 break; 261 262 case 'R': 263 if (PACKET_STARTS_WITH("qRcmd,")) 264 return eServerPacketType_qRcmd; 265 if (PACKET_STARTS_WITH("qRegisterInfo")) 266 return eServerPacketType_qRegisterInfo; 267 break; 268 269 case 'S': 270 if (PACKET_STARTS_WITH("qSaveCore")) 271 return eServerPacketType_qLLDBSaveCore; 272 if (PACKET_STARTS_WITH("qSpeedTest:")) 273 return eServerPacketType_qSpeedTest; 274 if (PACKET_MATCHES("qShlibInfoAddr")) 275 return eServerPacketType_qShlibInfoAddr; 276 if (PACKET_MATCHES("qStepPacketSupported")) 277 return eServerPacketType_qStepPacketSupported; 278 if (PACKET_STARTS_WITH("qSupported")) 279 return eServerPacketType_qSupported; 280 if (PACKET_MATCHES("qSyncThreadStateSupported")) 281 return eServerPacketType_qSyncThreadStateSupported; 282 break; 283 284 case 'T': 285 if (PACKET_STARTS_WITH("qThreadExtraInfo,")) 286 return eServerPacketType_qThreadExtraInfo; 287 if (PACKET_STARTS_WITH("qThreadStopInfo")) 288 return eServerPacketType_qThreadStopInfo; 289 break; 290 291 case 'U': 292 if (PACKET_STARTS_WITH("qUserName:")) 293 return eServerPacketType_qUserName; 294 break; 295 296 case 'V': 297 if (PACKET_MATCHES("qVAttachOrWaitSupported")) 298 return eServerPacketType_qVAttachOrWaitSupported; 299 break; 300 301 case 'W': 302 if (PACKET_STARTS_WITH("qWatchpointSupportInfo:")) 303 return eServerPacketType_qWatchpointSupportInfo; 304 if (PACKET_MATCHES("qWatchpointSupportInfo")) 305 return eServerPacketType_qWatchpointSupportInfoSupported; 306 break; 307 308 case 'X': 309 if (PACKET_STARTS_WITH("qXfer:")) 310 return eServerPacketType_qXfer; 311 break; 312 } 313 break; 314 315 case 'j': 316 if (PACKET_STARTS_WITH("jModulesInfo:")) 317 return eServerPacketType_jModulesInfo; 318 if (PACKET_MATCHES("jSignalsInfo")) 319 return eServerPacketType_jSignalsInfo; 320 if (PACKET_MATCHES("jThreadsInfo")) 321 return eServerPacketType_jThreadsInfo; 322 323 if (PACKET_MATCHES("jLLDBTraceSupported")) 324 return eServerPacketType_jLLDBTraceSupported; 325 if (PACKET_STARTS_WITH("jLLDBTraceStop:")) 326 return eServerPacketType_jLLDBTraceStop; 327 if (PACKET_STARTS_WITH("jLLDBTraceStart:")) 328 return eServerPacketType_jLLDBTraceStart; 329 if (PACKET_STARTS_WITH("jLLDBTraceGetState:")) 330 return eServerPacketType_jLLDBTraceGetState; 331 if (PACKET_STARTS_WITH("jLLDBTraceGetBinaryData:")) 332 return eServerPacketType_jLLDBTraceGetBinaryData; 333 break; 334 335 case 'v': 336 if (PACKET_STARTS_WITH("vFile:")) { 337 if (PACKET_STARTS_WITH("vFile:open:")) 338 return eServerPacketType_vFile_open; 339 else if (PACKET_STARTS_WITH("vFile:close:")) 340 return eServerPacketType_vFile_close; 341 else if (PACKET_STARTS_WITH("vFile:pread")) 342 return eServerPacketType_vFile_pread; 343 else if (PACKET_STARTS_WITH("vFile:pwrite")) 344 return eServerPacketType_vFile_pwrite; 345 else if (PACKET_STARTS_WITH("vFile:size")) 346 return eServerPacketType_vFile_size; 347 else if (PACKET_STARTS_WITH("vFile:exists")) 348 return eServerPacketType_vFile_exists; 349 else if (PACKET_STARTS_WITH("vFile:fstat")) 350 return eServerPacketType_vFile_fstat; 351 else if (PACKET_STARTS_WITH("vFile:stat")) 352 return eServerPacketType_vFile_stat; 353 else if (PACKET_STARTS_WITH("vFile:mode")) 354 return eServerPacketType_vFile_mode; 355 else if (PACKET_STARTS_WITH("vFile:MD5")) 356 return eServerPacketType_vFile_md5; 357 else if (PACKET_STARTS_WITH("vFile:symlink")) 358 return eServerPacketType_vFile_symlink; 359 else if (PACKET_STARTS_WITH("vFile:unlink")) 360 return eServerPacketType_vFile_unlink; 361 362 } else { 363 if (PACKET_STARTS_WITH("vAttach;")) 364 return eServerPacketType_vAttach; 365 if (PACKET_STARTS_WITH("vAttachWait;")) 366 return eServerPacketType_vAttachWait; 367 if (PACKET_STARTS_WITH("vAttachOrWait;")) 368 return eServerPacketType_vAttachOrWait; 369 if (PACKET_STARTS_WITH("vAttachName;")) 370 return eServerPacketType_vAttachName; 371 if (PACKET_STARTS_WITH("vCont;")) 372 return eServerPacketType_vCont; 373 if (PACKET_MATCHES("vCont?")) 374 return eServerPacketType_vCont_actions; 375 if (PACKET_STARTS_WITH("vKill;")) 376 return eServerPacketType_vKill; 377 if (PACKET_STARTS_WITH("vRun;")) 378 return eServerPacketType_vRun; 379 if (PACKET_MATCHES("vStopped")) 380 return eServerPacketType_vStopped; 381 if (PACKET_MATCHES("vCtrlC")) 382 return eServerPacketType_vCtrlC; 383 if (PACKET_MATCHES("vStdio")) 384 return eServerPacketType_vStdio; 385 break; 386 387 } 388 break; 389 case '_': 390 switch (packet_cstr[1]) { 391 case 'M': 392 return eServerPacketType__M; 393 394 case 'm': 395 return eServerPacketType__m; 396 } 397 break; 398 399 case '?': 400 if (packet_size == 1) 401 return eServerPacketType_stop_reason; 402 break; 403 404 case 'c': 405 return eServerPacketType_c; 406 407 case 'C': 408 return eServerPacketType_C; 409 410 case 'D': 411 return eServerPacketType_D; 412 413 case 'g': 414 return eServerPacketType_g; 415 416 case 'G': 417 return eServerPacketType_G; 418 419 case 'H': 420 return eServerPacketType_H; 421 422 case 'I': 423 return eServerPacketType_I; 424 425 case 'k': 426 if (packet_size == 1) 427 return eServerPacketType_k; 428 break; 429 430 case 'm': 431 return eServerPacketType_m; 432 433 case 'M': 434 return eServerPacketType_M; 435 436 case 'p': 437 return eServerPacketType_p; 438 439 case 'P': 440 return eServerPacketType_P; 441 442 case 's': 443 if (packet_size == 1) 444 return eServerPacketType_s; 445 break; 446 447 case 'S': 448 return eServerPacketType_S; 449 450 case 'x': 451 return eServerPacketType_x; 452 453 case 'X': 454 return eServerPacketType_X; 455 456 case 'T': 457 return eServerPacketType_T; 458 459 case 'z': 460 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 461 return eServerPacketType_z; 462 break; 463 464 case 'Z': 465 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 466 return eServerPacketType_Z; 467 break; 468 } 469 return eServerPacketType_unimplemented; 470 } 471 472 bool StringExtractorGDBRemote::IsOKResponse() const { 473 return GetResponseType() == eOK; 474 } 475 476 bool StringExtractorGDBRemote::IsUnsupportedResponse() const { 477 return GetResponseType() == eUnsupported; 478 } 479 480 bool StringExtractorGDBRemote::IsNormalResponse() const { 481 return GetResponseType() == eResponse; 482 } 483 484 bool StringExtractorGDBRemote::IsErrorResponse() const { 485 return GetResponseType() == eError && isxdigit(m_packet[1]) && 486 isxdigit(m_packet[2]); 487 } 488 489 uint8_t StringExtractorGDBRemote::GetError() { 490 if (GetResponseType() == eError) { 491 SetFilePos(1); 492 return GetHexU8(255); 493 } 494 return 0; 495 } 496 497 lldb_private::Status StringExtractorGDBRemote::GetStatus() { 498 lldb_private::Status error; 499 if (GetResponseType() == eError) { 500 SetFilePos(1); 501 uint8_t errc = GetHexU8(255); 502 error.SetError(errc, lldb::eErrorTypeGeneric); 503 504 error.SetErrorStringWithFormat("Error %u", errc); 505 std::string error_messg; 506 if (GetChar() == ';') { 507 GetHexByteString(error_messg); 508 error.SetErrorString(error_messg); 509 } 510 } 511 return error; 512 } 513 514 size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) { 515 // Just get the data bytes in the string as 516 // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped 517 // characters. If any 0x7d characters are left in the packet, then they are 518 // supposed to be there... 519 str.clear(); 520 const size_t bytes_left = GetBytesLeft(); 521 if (bytes_left > 0) { 522 str.assign(m_packet, m_index, bytes_left); 523 m_index += bytes_left; 524 } 525 return str.size(); 526 } 527 528 static bool 529 OKErrorNotSupportedResponseValidator(void *, 530 const StringExtractorGDBRemote &response) { 531 switch (response.GetResponseType()) { 532 case StringExtractorGDBRemote::eOK: 533 case StringExtractorGDBRemote::eError: 534 case StringExtractorGDBRemote::eUnsupported: 535 return true; 536 537 case StringExtractorGDBRemote::eAck: 538 case StringExtractorGDBRemote::eNack: 539 case StringExtractorGDBRemote::eResponse: 540 break; 541 } 542 return false; 543 } 544 545 static bool JSONResponseValidator(void *, 546 const StringExtractorGDBRemote &response) { 547 switch (response.GetResponseType()) { 548 case StringExtractorGDBRemote::eUnsupported: 549 case StringExtractorGDBRemote::eError: 550 return true; // Accept unsupported or EXX as valid responses 551 552 case StringExtractorGDBRemote::eOK: 553 case StringExtractorGDBRemote::eAck: 554 case StringExtractorGDBRemote::eNack: 555 break; 556 557 case StringExtractorGDBRemote::eResponse: 558 // JSON that is returned in from JSON query packets is currently always 559 // either a dictionary which starts with a '{', or an array which starts 560 // with a '['. This is a quick validator to just make sure the response 561 // could be valid JSON without having to validate all of the 562 // JSON content. 563 switch (response.GetStringRef()[0]) { 564 case '{': 565 return true; 566 case '[': 567 return true; 568 default: 569 break; 570 } 571 break; 572 } 573 return false; 574 } 575 576 static bool 577 ASCIIHexBytesResponseValidator(void *, 578 const StringExtractorGDBRemote &response) { 579 switch (response.GetResponseType()) { 580 case StringExtractorGDBRemote::eUnsupported: 581 case StringExtractorGDBRemote::eError: 582 return true; // Accept unsupported or EXX as valid responses 583 584 case StringExtractorGDBRemote::eOK: 585 case StringExtractorGDBRemote::eAck: 586 case StringExtractorGDBRemote::eNack: 587 break; 588 589 case StringExtractorGDBRemote::eResponse: { 590 uint32_t valid_count = 0; 591 for (const char ch : response.GetStringRef()) { 592 if (!isxdigit(ch)) { 593 return false; 594 } 595 if (++valid_count >= 16) 596 break; // Don't validate all the characters in case the packet is very 597 // large 598 } 599 return true; 600 } break; 601 } 602 return false; 603 } 604 605 void StringExtractorGDBRemote::CopyResponseValidator( 606 const StringExtractorGDBRemote &rhs) { 607 m_validator = rhs.m_validator; 608 m_validator_baton = rhs.m_validator_baton; 609 } 610 611 void StringExtractorGDBRemote::SetResponseValidator( 612 ResponseValidatorCallback callback, void *baton) { 613 m_validator = callback; 614 m_validator_baton = baton; 615 } 616 617 void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() { 618 m_validator = OKErrorNotSupportedResponseValidator; 619 m_validator_baton = nullptr; 620 } 621 622 void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() { 623 m_validator = ASCIIHexBytesResponseValidator; 624 m_validator_baton = nullptr; 625 } 626 627 void StringExtractorGDBRemote::SetResponseValidatorToJSON() { 628 m_validator = JSONResponseValidator; 629 m_validator_baton = nullptr; 630 } 631 632 bool StringExtractorGDBRemote::ValidateResponse() const { 633 // If we have a validator callback, try to validate the callback 634 if (m_validator) 635 return m_validator(m_validator_baton, *this); 636 else 637 return true; // No validator, so response is valid 638 } 639 640 llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>> 641 StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) { 642 llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index); 643 size_t initial_length = view.size(); 644 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 645 lldb::tid_t tid; 646 647 if (view.consume_front("p")) { 648 // process identifier 649 if (view.consume_front("-1")) { 650 // -1 is a special case 651 pid = AllProcesses; 652 } else if (view.consumeInteger(16, pid) || pid == 0) { 653 // not a valid hex integer OR unsupported pid 0 654 m_index = UINT64_MAX; 655 return llvm::None; 656 } 657 658 // "." must follow if we expect TID too; otherwise, we assume -1 659 if (!view.consume_front(".")) { 660 // update m_index 661 m_index += initial_length - view.size(); 662 663 return {{pid, AllThreads}}; 664 } 665 } 666 667 // thread identifier 668 if (view.consume_front("-1")) { 669 // -1 is a special case 670 tid = AllThreads; 671 } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) { 672 // not a valid hex integer OR tid 0 OR pid -1 + a specific tid 673 m_index = UINT64_MAX; 674 return llvm::None; 675 } 676 677 // update m_index 678 m_index += initial_length - view.size(); 679 680 return {{pid != LLDB_INVALID_PROCESS_ID ? pid : default_pid, tid}}; 681 } 682