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