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