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