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 'R': 154 if (PACKET_STARTS_WITH("QRestoreRegisterState:")) 155 return eServerPacketType_QRestoreRegisterState; 156 break; 157 158 case 'T': 159 if (PACKET_MATCHES("QThreadSuffixSupported")) 160 return eServerPacketType_QThreadSuffixSupported; 161 break; 162 } 163 break; 164 165 case 'q': 166 switch (packet_cstr[1]) { 167 case 's': 168 if (PACKET_MATCHES("qsProcessInfo")) 169 return eServerPacketType_qsProcessInfo; 170 if (PACKET_MATCHES("qsThreadInfo")) 171 return eServerPacketType_qsThreadInfo; 172 break; 173 174 case 'f': 175 if (PACKET_STARTS_WITH("qfProcessInfo")) 176 return eServerPacketType_qfProcessInfo; 177 if (PACKET_STARTS_WITH("qfThreadInfo")) 178 return eServerPacketType_qfThreadInfo; 179 break; 180 181 case 'C': 182 if (packet_size == 2) 183 return eServerPacketType_qC; 184 break; 185 186 case 'E': 187 if (PACKET_STARTS_WITH("qEcho:")) 188 return eServerPacketType_qEcho; 189 break; 190 191 case 'F': 192 if (PACKET_STARTS_WITH("qFileLoadAddress:")) 193 return eServerPacketType_qFileLoadAddress; 194 break; 195 196 case 'G': 197 if (PACKET_STARTS_WITH("qGroupName:")) 198 return eServerPacketType_qGroupName; 199 if (PACKET_MATCHES("qGetWorkingDir")) 200 return eServerPacketType_qGetWorkingDir; 201 if (PACKET_MATCHES("qGetPid")) 202 return eServerPacketType_qGetPid; 203 if (PACKET_STARTS_WITH("qGetProfileData;")) 204 return eServerPacketType_qGetProfileData; 205 if (PACKET_MATCHES("qGDBServerVersion")) 206 return eServerPacketType_qGDBServerVersion; 207 break; 208 209 case 'H': 210 if (PACKET_MATCHES("qHostInfo")) 211 return eServerPacketType_qHostInfo; 212 break; 213 214 case 'K': 215 if (PACKET_STARTS_WITH("qKillSpawnedProcess")) 216 return eServerPacketType_qKillSpawnedProcess; 217 break; 218 219 case 'L': 220 if (PACKET_STARTS_WITH("qLaunchGDBServer")) 221 return eServerPacketType_qLaunchGDBServer; 222 if (PACKET_MATCHES("qLaunchSuccess")) 223 return eServerPacketType_qLaunchSuccess; 224 break; 225 226 case 'M': 227 if (PACKET_STARTS_WITH("qMemoryRegionInfo:")) 228 return eServerPacketType_qMemoryRegionInfo; 229 if (PACKET_MATCHES("qMemoryRegionInfo")) 230 return eServerPacketType_qMemoryRegionInfoSupported; 231 if (PACKET_STARTS_WITH("qModuleInfo:")) 232 return eServerPacketType_qModuleInfo; 233 if (PACKET_STARTS_WITH("qMemTags:")) 234 return eServerPacketType_qMemTags; 235 break; 236 237 case 'P': 238 if (PACKET_STARTS_WITH("qProcessInfoPID:")) 239 return eServerPacketType_qProcessInfoPID; 240 if (PACKET_STARTS_WITH("qPlatform_shell:")) 241 return eServerPacketType_qPlatform_shell; 242 if (PACKET_STARTS_WITH("qPlatform_mkdir:")) 243 return eServerPacketType_qPlatform_mkdir; 244 if (PACKET_STARTS_WITH("qPlatform_chmod:")) 245 return eServerPacketType_qPlatform_chmod; 246 if (PACKET_MATCHES("qProcessInfo")) 247 return eServerPacketType_qProcessInfo; 248 if (PACKET_STARTS_WITH("qPathComplete:")) 249 return eServerPacketType_qPathComplete; 250 break; 251 252 case 'Q': 253 if (PACKET_MATCHES("qQueryGDBServer")) 254 return eServerPacketType_qQueryGDBServer; 255 break; 256 257 case 'R': 258 if (PACKET_STARTS_WITH("qRcmd,")) 259 return eServerPacketType_qRcmd; 260 if (PACKET_STARTS_WITH("qRegisterInfo")) 261 return eServerPacketType_qRegisterInfo; 262 break; 263 264 case 'S': 265 if (PACKET_STARTS_WITH("qSaveCore")) 266 return eServerPacketType_qLLDBSaveCore; 267 if (PACKET_STARTS_WITH("qSpeedTest:")) 268 return eServerPacketType_qSpeedTest; 269 if (PACKET_MATCHES("qShlibInfoAddr")) 270 return eServerPacketType_qShlibInfoAddr; 271 if (PACKET_MATCHES("qStepPacketSupported")) 272 return eServerPacketType_qStepPacketSupported; 273 if (PACKET_STARTS_WITH("qSupported")) 274 return eServerPacketType_qSupported; 275 if (PACKET_MATCHES("qSyncThreadStateSupported")) 276 return eServerPacketType_qSyncThreadStateSupported; 277 break; 278 279 case 'T': 280 if (PACKET_STARTS_WITH("qThreadExtraInfo,")) 281 return eServerPacketType_qThreadExtraInfo; 282 if (PACKET_STARTS_WITH("qThreadStopInfo")) 283 return eServerPacketType_qThreadStopInfo; 284 break; 285 286 case 'U': 287 if (PACKET_STARTS_WITH("qUserName:")) 288 return eServerPacketType_qUserName; 289 break; 290 291 case 'V': 292 if (PACKET_MATCHES("qVAttachOrWaitSupported")) 293 return eServerPacketType_qVAttachOrWaitSupported; 294 break; 295 296 case 'W': 297 if (PACKET_STARTS_WITH("qWatchpointSupportInfo:")) 298 return eServerPacketType_qWatchpointSupportInfo; 299 if (PACKET_MATCHES("qWatchpointSupportInfo")) 300 return eServerPacketType_qWatchpointSupportInfoSupported; 301 break; 302 303 case 'X': 304 if (PACKET_STARTS_WITH("qXfer:")) 305 return eServerPacketType_qXfer; 306 break; 307 } 308 break; 309 310 case 'j': 311 if (PACKET_STARTS_WITH("jModulesInfo:")) 312 return eServerPacketType_jModulesInfo; 313 if (PACKET_MATCHES("jSignalsInfo")) 314 return eServerPacketType_jSignalsInfo; 315 if (PACKET_MATCHES("jThreadsInfo")) 316 return eServerPacketType_jThreadsInfo; 317 318 if (PACKET_MATCHES("jLLDBTraceSupported")) 319 return eServerPacketType_jLLDBTraceSupported; 320 if (PACKET_STARTS_WITH("jLLDBTraceStop:")) 321 return eServerPacketType_jLLDBTraceStop; 322 if (PACKET_STARTS_WITH("jLLDBTraceStart:")) 323 return eServerPacketType_jLLDBTraceStart; 324 if (PACKET_STARTS_WITH("jLLDBTraceGetState:")) 325 return eServerPacketType_jLLDBTraceGetState; 326 if (PACKET_STARTS_WITH("jLLDBTraceGetBinaryData:")) 327 return eServerPacketType_jLLDBTraceGetBinaryData; 328 break; 329 330 case 'v': 331 if (PACKET_STARTS_WITH("vFile:")) { 332 if (PACKET_STARTS_WITH("vFile:open:")) 333 return eServerPacketType_vFile_open; 334 else if (PACKET_STARTS_WITH("vFile:close:")) 335 return eServerPacketType_vFile_close; 336 else if (PACKET_STARTS_WITH("vFile:pread")) 337 return eServerPacketType_vFile_pread; 338 else if (PACKET_STARTS_WITH("vFile:pwrite")) 339 return eServerPacketType_vFile_pwrite; 340 else if (PACKET_STARTS_WITH("vFile:size")) 341 return eServerPacketType_vFile_size; 342 else if (PACKET_STARTS_WITH("vFile:exists")) 343 return eServerPacketType_vFile_exists; 344 else if (PACKET_STARTS_WITH("vFile:fstat")) 345 return eServerPacketType_vFile_fstat; 346 else if (PACKET_STARTS_WITH("vFile:stat")) 347 return eServerPacketType_vFile_stat; 348 else if (PACKET_STARTS_WITH("vFile:mode")) 349 return eServerPacketType_vFile_mode; 350 else if (PACKET_STARTS_WITH("vFile:MD5")) 351 return eServerPacketType_vFile_md5; 352 else if (PACKET_STARTS_WITH("vFile:symlink")) 353 return eServerPacketType_vFile_symlink; 354 else if (PACKET_STARTS_WITH("vFile:unlink")) 355 return eServerPacketType_vFile_unlink; 356 357 } else { 358 if (PACKET_STARTS_WITH("vAttach;")) 359 return eServerPacketType_vAttach; 360 if (PACKET_STARTS_WITH("vAttachWait;")) 361 return eServerPacketType_vAttachWait; 362 if (PACKET_STARTS_WITH("vAttachOrWait;")) 363 return eServerPacketType_vAttachOrWait; 364 if (PACKET_STARTS_WITH("vAttachName;")) 365 return eServerPacketType_vAttachName; 366 if (PACKET_STARTS_WITH("vCont;")) 367 return eServerPacketType_vCont; 368 if (PACKET_MATCHES("vCont?")) 369 return eServerPacketType_vCont_actions; 370 if (PACKET_STARTS_WITH("vRun;")) 371 return eServerPacketType_vRun; 372 } 373 break; 374 case '_': 375 switch (packet_cstr[1]) { 376 case 'M': 377 return eServerPacketType__M; 378 379 case 'm': 380 return eServerPacketType__m; 381 } 382 break; 383 384 case '?': 385 if (packet_size == 1) 386 return eServerPacketType_stop_reason; 387 break; 388 389 case 'c': 390 return eServerPacketType_c; 391 392 case 'C': 393 return eServerPacketType_C; 394 395 case 'D': 396 return eServerPacketType_D; 397 398 case 'g': 399 return eServerPacketType_g; 400 401 case 'G': 402 return eServerPacketType_G; 403 404 case 'H': 405 return eServerPacketType_H; 406 407 case 'I': 408 return eServerPacketType_I; 409 410 case 'k': 411 if (packet_size == 1) 412 return eServerPacketType_k; 413 break; 414 415 case 'm': 416 return eServerPacketType_m; 417 418 case 'M': 419 return eServerPacketType_M; 420 421 case 'p': 422 return eServerPacketType_p; 423 424 case 'P': 425 return eServerPacketType_P; 426 427 case 's': 428 if (packet_size == 1) 429 return eServerPacketType_s; 430 break; 431 432 case 'S': 433 return eServerPacketType_S; 434 435 case 'x': 436 return eServerPacketType_x; 437 438 case 'X': 439 return eServerPacketType_X; 440 441 case 'T': 442 return eServerPacketType_T; 443 444 case 'z': 445 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 446 return eServerPacketType_z; 447 break; 448 449 case 'Z': 450 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 451 return eServerPacketType_Z; 452 break; 453 } 454 return eServerPacketType_unimplemented; 455 } 456 457 bool StringExtractorGDBRemote::IsOKResponse() const { 458 return GetResponseType() == eOK; 459 } 460 461 bool StringExtractorGDBRemote::IsUnsupportedResponse() const { 462 return GetResponseType() == eUnsupported; 463 } 464 465 bool StringExtractorGDBRemote::IsNormalResponse() const { 466 return GetResponseType() == eResponse; 467 } 468 469 bool StringExtractorGDBRemote::IsErrorResponse() const { 470 return GetResponseType() == eError && isxdigit(m_packet[1]) && 471 isxdigit(m_packet[2]); 472 } 473 474 uint8_t StringExtractorGDBRemote::GetError() { 475 if (GetResponseType() == eError) { 476 SetFilePos(1); 477 return GetHexU8(255); 478 } 479 return 0; 480 } 481 482 lldb_private::Status StringExtractorGDBRemote::GetStatus() { 483 lldb_private::Status error; 484 if (GetResponseType() == eError) { 485 SetFilePos(1); 486 uint8_t errc = GetHexU8(255); 487 error.SetError(errc, lldb::eErrorTypeGeneric); 488 489 error.SetErrorStringWithFormat("Error %u", errc); 490 std::string error_messg; 491 if (GetChar() == ';') { 492 GetHexByteString(error_messg); 493 error.SetErrorString(error_messg); 494 } 495 } 496 return error; 497 } 498 499 size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) { 500 // Just get the data bytes in the string as 501 // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped 502 // characters. If any 0x7d characters are left in the packet, then they are 503 // supposed to be there... 504 str.clear(); 505 const size_t bytes_left = GetBytesLeft(); 506 if (bytes_left > 0) { 507 str.assign(m_packet, m_index, bytes_left); 508 m_index += bytes_left; 509 } 510 return str.size(); 511 } 512 513 static bool 514 OKErrorNotSupportedResponseValidator(void *, 515 const StringExtractorGDBRemote &response) { 516 switch (response.GetResponseType()) { 517 case StringExtractorGDBRemote::eOK: 518 case StringExtractorGDBRemote::eError: 519 case StringExtractorGDBRemote::eUnsupported: 520 return true; 521 522 case StringExtractorGDBRemote::eAck: 523 case StringExtractorGDBRemote::eNack: 524 case StringExtractorGDBRemote::eResponse: 525 break; 526 } 527 return false; 528 } 529 530 static bool JSONResponseValidator(void *, 531 const StringExtractorGDBRemote &response) { 532 switch (response.GetResponseType()) { 533 case StringExtractorGDBRemote::eUnsupported: 534 case StringExtractorGDBRemote::eError: 535 return true; // Accept unsupported or EXX as valid responses 536 537 case StringExtractorGDBRemote::eOK: 538 case StringExtractorGDBRemote::eAck: 539 case StringExtractorGDBRemote::eNack: 540 break; 541 542 case StringExtractorGDBRemote::eResponse: 543 // JSON that is returned in from JSON query packets is currently always 544 // either a dictionary which starts with a '{', or an array which starts 545 // with a '['. This is a quick validator to just make sure the response 546 // could be valid JSON without having to validate all of the 547 // JSON content. 548 switch (response.GetStringRef()[0]) { 549 case '{': 550 return true; 551 case '[': 552 return true; 553 default: 554 break; 555 } 556 break; 557 } 558 return false; 559 } 560 561 static bool 562 ASCIIHexBytesResponseValidator(void *, 563 const StringExtractorGDBRemote &response) { 564 switch (response.GetResponseType()) { 565 case StringExtractorGDBRemote::eUnsupported: 566 case StringExtractorGDBRemote::eError: 567 return true; // Accept unsupported or EXX as valid responses 568 569 case StringExtractorGDBRemote::eOK: 570 case StringExtractorGDBRemote::eAck: 571 case StringExtractorGDBRemote::eNack: 572 break; 573 574 case StringExtractorGDBRemote::eResponse: { 575 uint32_t valid_count = 0; 576 for (const char ch : response.GetStringRef()) { 577 if (!isxdigit(ch)) { 578 return false; 579 } 580 if (++valid_count >= 16) 581 break; // Don't validate all the characters in case the packet is very 582 // large 583 } 584 return true; 585 } break; 586 } 587 return false; 588 } 589 590 void StringExtractorGDBRemote::CopyResponseValidator( 591 const StringExtractorGDBRemote &rhs) { 592 m_validator = rhs.m_validator; 593 m_validator_baton = rhs.m_validator_baton; 594 } 595 596 void StringExtractorGDBRemote::SetResponseValidator( 597 ResponseValidatorCallback callback, void *baton) { 598 m_validator = callback; 599 m_validator_baton = baton; 600 } 601 602 void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() { 603 m_validator = OKErrorNotSupportedResponseValidator; 604 m_validator_baton = nullptr; 605 } 606 607 void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() { 608 m_validator = ASCIIHexBytesResponseValidator; 609 m_validator_baton = nullptr; 610 } 611 612 void StringExtractorGDBRemote::SetResponseValidatorToJSON() { 613 m_validator = JSONResponseValidator; 614 m_validator_baton = nullptr; 615 } 616 617 bool StringExtractorGDBRemote::ValidateResponse() const { 618 // If we have a validator callback, try to validate the callback 619 if (m_validator) 620 return m_validator(m_validator_baton, *this); 621 else 622 return true; // No validator, so response is valid 623 } 624 625 llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>> 626 StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) { 627 llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index); 628 size_t initial_length = view.size(); 629 lldb::pid_t pid = default_pid; 630 lldb::tid_t tid; 631 632 if (view.consume_front("p")) { 633 // process identifier 634 if (view.consume_front("-1")) { 635 // -1 is a special case 636 pid = AllProcesses; 637 } else if (view.consumeInteger(16, pid) || pid == 0) { 638 // not a valid hex integer OR unsupported pid 0 639 m_index = UINT64_MAX; 640 return llvm::None; 641 } 642 643 // "." must follow if we expect TID too; otherwise, we assume -1 644 if (!view.consume_front(".")) { 645 // update m_index 646 m_index += initial_length - view.size(); 647 648 return {{pid, AllThreads}}; 649 } 650 } 651 652 // thread identifier 653 if (view.consume_front("-1")) { 654 // -1 is a special case 655 tid = AllThreads; 656 } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) { 657 // not a valid hex integer OR tid 0 OR pid -1 + a specific tid 658 m_index = UINT64_MAX; 659 return llvm::None; 660 } 661 662 // update m_index 663 m_index += initial_length - view.size(); 664 665 return {{pid, tid}}; 666 } 667