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 15constexpr lldb::pid_t StringExtractorGDBRemote::AllProcesses; 16constexpr lldb::tid_t StringExtractorGDBRemote::AllThreads; 17 18StringExtractorGDBRemote::ResponseType 19StringExtractorGDBRemote::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 57StringExtractorGDBRemote::ServerPacketType 58StringExtractorGDBRemote::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 473bool StringExtractorGDBRemote::IsOKResponse() const { 474 return GetResponseType() == eOK; 475} 476 477bool StringExtractorGDBRemote::IsUnsupportedResponse() const { 478 return GetResponseType() == eUnsupported; 479} 480 481bool StringExtractorGDBRemote::IsNormalResponse() const { 482 return GetResponseType() == eResponse; 483} 484 485bool StringExtractorGDBRemote::IsErrorResponse() const { 486 return GetResponseType() == eError && isxdigit(m_packet[1]) && 487 isxdigit(m_packet[2]); 488} 489 490uint8_t StringExtractorGDBRemote::GetError() { 491 if (GetResponseType() == eError) { 492 SetFilePos(1); 493 return GetHexU8(255); 494 } 495 return 0; 496} 497 498lldb_private::Status StringExtractorGDBRemote::GetStatus() { 499 lldb_private::Status error; 500 if (GetResponseType() == eError) { 501 SetFilePos(1); 502 uint8_t errc = GetHexU8(255); 503 error.SetError(errc, lldb::eErrorTypeGeneric); 504 505 error.SetErrorStringWithFormat("Error %u", errc); 506 std::string error_messg; 507 if (GetChar() == ';') { 508 GetHexByteString(error_messg); 509 error.SetErrorString(error_messg); 510 } 511 } 512 return error; 513} 514 515size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) { 516 // Just get the data bytes in the string as 517 // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped 518 // characters. If any 0x7d characters are left in the packet, then they are 519 // supposed to be there... 520 str.clear(); 521 const size_t bytes_left = GetBytesLeft(); 522 if (bytes_left > 0) { 523 str.assign(m_packet, m_index, bytes_left); 524 m_index += bytes_left; 525 } 526 return str.size(); 527} 528 529static bool 530OKErrorNotSupportedResponseValidator(void *, 531 const StringExtractorGDBRemote &response) { 532 switch (response.GetResponseType()) { 533 case StringExtractorGDBRemote::eOK: 534 case StringExtractorGDBRemote::eError: 535 case StringExtractorGDBRemote::eUnsupported: 536 return true; 537 538 case StringExtractorGDBRemote::eAck: 539 case StringExtractorGDBRemote::eNack: 540 case StringExtractorGDBRemote::eResponse: 541 break; 542 } 543 return false; 544} 545 546static bool JSONResponseValidator(void *, 547 const StringExtractorGDBRemote &response) { 548 switch (response.GetResponseType()) { 549 case StringExtractorGDBRemote::eUnsupported: 550 case StringExtractorGDBRemote::eError: 551 return true; // Accept unsupported or EXX as valid responses 552 553 case StringExtractorGDBRemote::eOK: 554 case StringExtractorGDBRemote::eAck: 555 case StringExtractorGDBRemote::eNack: 556 break; 557 558 case StringExtractorGDBRemote::eResponse: 559 // JSON that is returned in from JSON query packets is currently always 560 // either a dictionary which starts with a '{', or an array which starts 561 // with a '['. This is a quick validator to just make sure the response 562 // could be valid JSON without having to validate all of the 563 // JSON content. 564 switch (response.GetStringRef()[0]) { 565 case '{': 566 return true; 567 case '[': 568 return true; 569 default: 570 break; 571 } 572 break; 573 } 574 return false; 575} 576 577static bool 578ASCIIHexBytesResponseValidator(void *, 579 const StringExtractorGDBRemote &response) { 580 switch (response.GetResponseType()) { 581 case StringExtractorGDBRemote::eUnsupported: 582 case StringExtractorGDBRemote::eError: 583 return true; // Accept unsupported or EXX as valid responses 584 585 case StringExtractorGDBRemote::eOK: 586 case StringExtractorGDBRemote::eAck: 587 case StringExtractorGDBRemote::eNack: 588 break; 589 590 case StringExtractorGDBRemote::eResponse: { 591 uint32_t valid_count = 0; 592 for (const char ch : response.GetStringRef()) { 593 if (!isxdigit(ch)) { 594 return false; 595 } 596 if (++valid_count >= 16) 597 break; // Don't validate all the characters in case the packet is very 598 // large 599 } 600 return true; 601 } break; 602 } 603 return false; 604} 605 606void StringExtractorGDBRemote::CopyResponseValidator( 607 const StringExtractorGDBRemote &rhs) { 608 m_validator = rhs.m_validator; 609 m_validator_baton = rhs.m_validator_baton; 610} 611 612void StringExtractorGDBRemote::SetResponseValidator( 613 ResponseValidatorCallback callback, void *baton) { 614 m_validator = callback; 615 m_validator_baton = baton; 616} 617 618void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() { 619 m_validator = OKErrorNotSupportedResponseValidator; 620 m_validator_baton = nullptr; 621} 622 623void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() { 624 m_validator = ASCIIHexBytesResponseValidator; 625 m_validator_baton = nullptr; 626} 627 628void StringExtractorGDBRemote::SetResponseValidatorToJSON() { 629 m_validator = JSONResponseValidator; 630 m_validator_baton = nullptr; 631} 632 633bool StringExtractorGDBRemote::ValidateResponse() const { 634 // If we have a validator callback, try to validate the callback 635 if (m_validator) 636 return m_validator(m_validator_baton, *this); 637 else 638 return true; // No validator, so response is valid 639} 640 641std::optional<std::pair<lldb::pid_t, lldb::tid_t>> 642StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) { 643 llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index); 644 size_t initial_length = view.size(); 645 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; 646 lldb::tid_t tid; 647 648 if (view.consume_front("p")) { 649 // process identifier 650 if (view.consume_front("-1")) { 651 // -1 is a special case 652 pid = AllProcesses; 653 } else if (view.consumeInteger(16, pid) || pid == 0) { 654 // not a valid hex integer OR unsupported pid 0 655 m_index = UINT64_MAX; 656 return std::nullopt; 657 } 658 659 // "." must follow if we expect TID too; otherwise, we assume -1 660 if (!view.consume_front(".")) { 661 // update m_index 662 m_index += initial_length - view.size(); 663 664 return {{pid, AllThreads}}; 665 } 666 } 667 668 // thread identifier 669 if (view.consume_front("-1")) { 670 // -1 is a special case 671 tid = AllThreads; 672 } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) { 673 // not a valid hex integer OR tid 0 OR pid -1 + a specific tid 674 m_index = UINT64_MAX; 675 return std::nullopt; 676 } 677 678 // update m_index 679 m_index += initial_length - view.size(); 680 681 return {{pid != LLDB_INVALID_PROCESS_ID ? pid : default_pid, tid}}; 682} 683