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