180814287SRaphael Isemann //===-- StringExtractorGDBRemote.cpp --------------------------------------===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 99af71b38SPavel Labath #include "lldb/Utility/StringExtractorGDBRemote.h" 1030fdc8d8SChris Lattner 1176e47d48SRaphael Isemann #include <cctype> 1276e47d48SRaphael Isemann #include <cstring> 134479ac15SZachary Turner 146c1a8039SMichał Górny constexpr lldb::pid_t StringExtractorGDBRemote::AllProcesses; 156c1a8039SMichał Górny constexpr lldb::tid_t StringExtractorGDBRemote::AllThreads; 166c1a8039SMichał Górny 17576d8834SGreg Clayton StringExtractorGDBRemote::ResponseType 18b9c1b51eSKate Stone StringExtractorGDBRemote::GetResponseType() const { 1930fdc8d8SChris Lattner if (m_packet.empty()) 2030fdc8d8SChris Lattner return eUnsupported; 2130fdc8d8SChris Lattner 22b9c1b51eSKate Stone switch (m_packet[0]) { 2330fdc8d8SChris Lattner case 'E': 24dab1d5f3SRavitheja Addepally if (isxdigit(m_packet[1]) && isxdigit(m_packet[2])) { 25dab1d5f3SRavitheja Addepally if (m_packet.size() == 3) 2630fdc8d8SChris Lattner return eError; 27dab1d5f3SRavitheja Addepally llvm::StringRef packet_ref(m_packet); 28dab1d5f3SRavitheja Addepally if (packet_ref[3] == ';') { 29dab1d5f3SRavitheja Addepally auto err_string = packet_ref.substr(4); 30dab1d5f3SRavitheja Addepally for (auto e : err_string) 31dab1d5f3SRavitheja Addepally if (!isxdigit(e)) 32dab1d5f3SRavitheja Addepally return eResponse; 33dab1d5f3SRavitheja Addepally return eError; 34dab1d5f3SRavitheja Addepally } 35dab1d5f3SRavitheja Addepally } 3630fdc8d8SChris Lattner break; 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner case 'O': 3930fdc8d8SChris Lattner if (m_packet.size() == 2 && m_packet[1] == 'K') 4030fdc8d8SChris Lattner return eOK; 4130fdc8d8SChris Lattner break; 4230fdc8d8SChris Lattner 4330fdc8d8SChris Lattner case '+': 4430fdc8d8SChris Lattner if (m_packet.size() == 1) 4530fdc8d8SChris Lattner return eAck; 4630fdc8d8SChris Lattner break; 4730fdc8d8SChris Lattner 4830fdc8d8SChris Lattner case '-': 4930fdc8d8SChris Lattner if (m_packet.size() == 1) 5030fdc8d8SChris Lattner return eNack; 5130fdc8d8SChris Lattner break; 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner return eResponse; 5430fdc8d8SChris Lattner } 5530fdc8d8SChris Lattner 56576d8834SGreg Clayton StringExtractorGDBRemote::ServerPacketType 57b9c1b51eSKate Stone StringExtractorGDBRemote::GetServerPacketType() const { 58b9c1b51eSKate Stone #define PACKET_MATCHES(s) \ 59b9c1b51eSKate Stone ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0)) 60b9c1b51eSKate Stone #define PACKET_STARTS_WITH(s) \ 61b9c1b51eSKate Stone ((packet_size >= (sizeof(s) - 1)) && \ 62b9c1b51eSKate Stone ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0) 638b82f087SGreg Clayton 64576d8834SGreg Clayton // Empty is not a supported packet... 65576d8834SGreg Clayton if (m_packet.empty()) 66576d8834SGreg Clayton return eServerPacketType_invalid; 67576d8834SGreg Clayton 688b82f087SGreg Clayton const size_t packet_size = m_packet.size(); 69576d8834SGreg Clayton const char *packet_cstr = m_packet.c_str(); 70b9c1b51eSKate Stone switch (m_packet[0]) { 7178baa197SEwan Crawford 7278baa197SEwan Crawford case '%': 7378baa197SEwan Crawford return eServerPacketType_notify; 7478baa197SEwan Crawford 75d314e810SGreg Clayton case '\x03': 76b9c1b51eSKate Stone if (packet_size == 1) 77b9c1b51eSKate Stone return eServerPacketType_interrupt; 78d314e810SGreg Clayton break; 79d314e810SGreg Clayton 80576d8834SGreg Clayton case '-': 81b9c1b51eSKate Stone if (packet_size == 1) 82b9c1b51eSKate Stone return eServerPacketType_nack; 83576d8834SGreg Clayton break; 84576d8834SGreg Clayton 85576d8834SGreg Clayton case '+': 86b9c1b51eSKate Stone if (packet_size == 1) 87b9c1b51eSKate Stone return eServerPacketType_ack; 88576d8834SGreg Clayton break; 89576d8834SGreg Clayton 908b82f087SGreg Clayton case 'A': 918b82f087SGreg Clayton return eServerPacketType_A; 928b82f087SGreg Clayton 931cb6496eSGreg Clayton case 'Q': 940fefa676SJean-Daniel Dupas 95b9c1b51eSKate Stone switch (packet_cstr[1]) { 968b82f087SGreg Clayton case 'E': 97b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QEnvironment:")) 98b9c1b51eSKate Stone return eServerPacketType_QEnvironment; 99b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:")) 100b9c1b51eSKate Stone return eServerPacketType_QEnvironmentHexEncoded; 101dab1d5f3SRavitheja Addepally if (PACKET_STARTS_WITH("QEnableErrorStrings")) 102dab1d5f3SRavitheja Addepally return eServerPacketType_QEnableErrorStrings; 1038b82f087SGreg Clayton break; 1048b82f087SGreg Clayton 1054a705e7eSPavel Labath case 'P': 1064a705e7eSPavel Labath if (PACKET_STARTS_WITH("QPassSignals:")) 1074a705e7eSPavel Labath return eServerPacketType_QPassSignals; 1085b075d63SGreg Clayton break; 1094a705e7eSPavel Labath 1108b82f087SGreg Clayton case 'S': 111b9c1b51eSKate Stone if (PACKET_MATCHES("QStartNoAckMode")) 112b9c1b51eSKate Stone return eServerPacketType_QStartNoAckMode; 113b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSaveRegisterState")) 114b9c1b51eSKate Stone return eServerPacketType_QSaveRegisterState; 115b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetDisableASLR:")) 116b9c1b51eSKate Stone return eServerPacketType_QSetDisableASLR; 117b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetDetachOnError:")) 118b9c1b51eSKate Stone return eServerPacketType_QSetDetachOnError; 119b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDIN:")) 120b9c1b51eSKate Stone return eServerPacketType_QSetSTDIN; 121b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDOUT:")) 122b9c1b51eSKate Stone return eServerPacketType_QSetSTDOUT; 123b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDERR:")) 124b9c1b51eSKate Stone return eServerPacketType_QSetSTDERR; 125b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetWorkingDir:")) 126b9c1b51eSKate Stone return eServerPacketType_QSetWorkingDir; 127b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetLogging:")) 128b9c1b51eSKate Stone return eServerPacketType_QSetLogging; 129bff4673bSJim Ingham if (PACKET_STARTS_WITH("QSetIgnoredExceptions")) 130bff4673bSJim Ingham return eServerPacketType_QSetIgnoredExceptions; 131b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetMaxPacketSize:")) 132b9c1b51eSKate Stone return eServerPacketType_QSetMaxPacketSize; 133b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetMaxPayloadSize:")) 134b9c1b51eSKate Stone return eServerPacketType_QSetMaxPayloadSize; 135b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;")) 136b9c1b51eSKate Stone return eServerPacketType_QSetEnableAsyncProfiling; 137b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSyncThreadState:")) 138b9c1b51eSKate Stone return eServerPacketType_QSyncThreadState; 1398b82f087SGreg Clayton break; 1400fefa676SJean-Daniel Dupas 141e0f8f574SDaniel Malea case 'L': 142b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QLaunchArch:")) 143b9c1b51eSKate Stone return eServerPacketType_QLaunchArch; 144b9c1b51eSKate Stone if (PACKET_MATCHES("QListThreadsInStopReply")) 145b9c1b51eSKate Stone return eServerPacketType_QListThreadsInStopReply; 1460fefa676SJean-Daniel Dupas break; 1470fefa676SJean-Daniel Dupas 1487d27230dSDavid Spickett case 'M': 1497d27230dSDavid Spickett if (PACKET_STARTS_WITH("QMemTags")) 1507d27230dSDavid Spickett return eServerPacketType_QMemTags; 1517d27230dSDavid Spickett break; 1527d27230dSDavid Spickett 153bc04d240SMichał Górny case 'N': 154bc04d240SMichał Górny if (PACKET_STARTS_WITH("QNonStop:")) 155bc04d240SMichał Górny return eServerPacketType_QNonStop; 156bc04d240SMichał Górny break; 157bc04d240SMichał Górny 1580fefa676SJean-Daniel Dupas case 'R': 159b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QRestoreRegisterState:")) 160b9c1b51eSKate Stone return eServerPacketType_QRestoreRegisterState; 1610fefa676SJean-Daniel Dupas break; 1620fefa676SJean-Daniel Dupas 1630fefa676SJean-Daniel Dupas case 'T': 164b9c1b51eSKate Stone if (PACKET_MATCHES("QThreadSuffixSupported")) 165b9c1b51eSKate Stone return eServerPacketType_QThreadSuffixSupported; 166e0f8f574SDaniel Malea break; 1678b82f087SGreg Clayton } 1681cb6496eSGreg Clayton break; 1691cb6496eSGreg Clayton 170576d8834SGreg Clayton case 'q': 171b9c1b51eSKate Stone switch (packet_cstr[1]) { 1728b82f087SGreg Clayton case 's': 173b9c1b51eSKate Stone if (PACKET_MATCHES("qsProcessInfo")) 174b9c1b51eSKate Stone return eServerPacketType_qsProcessInfo; 175b9c1b51eSKate Stone if (PACKET_MATCHES("qsThreadInfo")) 176b9c1b51eSKate Stone return eServerPacketType_qsThreadInfo; 1778b82f087SGreg Clayton break; 1788b82f087SGreg Clayton 1798b82f087SGreg Clayton case 'f': 180b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qfProcessInfo")) 181b9c1b51eSKate Stone return eServerPacketType_qfProcessInfo; 182b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qfThreadInfo")) 183b9c1b51eSKate Stone return eServerPacketType_qfThreadInfo; 1848b82f087SGreg Clayton break; 1858b82f087SGreg Clayton 1868b82f087SGreg Clayton case 'C': 187b9c1b51eSKate Stone if (packet_size == 2) 188b9c1b51eSKate Stone return eServerPacketType_qC; 1898b82f087SGreg Clayton break; 1908b82f087SGreg Clayton 191420562aaSGreg Clayton case 'E': 192b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qEcho:")) 193b9c1b51eSKate Stone return eServerPacketType_qEcho; 194420562aaSGreg Clayton break; 195420562aaSGreg Clayton 196783bfc8cSTamas Berghammer case 'F': 197b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qFileLoadAddress:")) 198b9c1b51eSKate Stone return eServerPacketType_qFileLoadAddress; 199783bfc8cSTamas Berghammer break; 200783bfc8cSTamas Berghammer 2018b82f087SGreg Clayton case 'G': 202b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qGroupName:")) 203b9c1b51eSKate Stone return eServerPacketType_qGroupName; 204b9c1b51eSKate Stone if (PACKET_MATCHES("qGetWorkingDir")) 205b9c1b51eSKate Stone return eServerPacketType_qGetWorkingDir; 206b9c1b51eSKate Stone if (PACKET_MATCHES("qGetPid")) 207b9c1b51eSKate Stone return eServerPacketType_qGetPid; 208b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qGetProfileData;")) 209b9c1b51eSKate Stone return eServerPacketType_qGetProfileData; 210b9c1b51eSKate Stone if (PACKET_MATCHES("qGDBServerVersion")) 211b9c1b51eSKate Stone return eServerPacketType_qGDBServerVersion; 2128b82f087SGreg Clayton break; 2138b82f087SGreg Clayton 2148b82f087SGreg Clayton case 'H': 215b9c1b51eSKate Stone if (PACKET_MATCHES("qHostInfo")) 216b9c1b51eSKate Stone return eServerPacketType_qHostInfo; 2178b82f087SGreg Clayton break; 2188b82f087SGreg Clayton 219e0f8f574SDaniel Malea case 'K': 220b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qKillSpawnedProcess")) 221b9c1b51eSKate Stone return eServerPacketType_qKillSpawnedProcess; 222e0f8f574SDaniel Malea break; 223e0f8f574SDaniel Malea 2248b82f087SGreg Clayton case 'L': 225b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qLaunchGDBServer")) 226b9c1b51eSKate Stone return eServerPacketType_qLaunchGDBServer; 227b9c1b51eSKate Stone if (PACKET_MATCHES("qLaunchSuccess")) 228b9c1b51eSKate Stone return eServerPacketType_qLaunchSuccess; 2298b82f087SGreg Clayton break; 2308b82f087SGreg Clayton 2310fefa676SJean-Daniel Dupas case 'M': 232b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qMemoryRegionInfo:")) 233b9c1b51eSKate Stone return eServerPacketType_qMemoryRegionInfo; 234b9c1b51eSKate Stone if (PACKET_MATCHES("qMemoryRegionInfo")) 235b9c1b51eSKate Stone return eServerPacketType_qMemoryRegionInfoSupported; 236b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qModuleInfo:")) 237b9c1b51eSKate Stone return eServerPacketType_qModuleInfo; 238da2e614fSDavid Spickett if (PACKET_STARTS_WITH("qMemTags:")) 239da2e614fSDavid Spickett return eServerPacketType_qMemTags; 2400fefa676SJean-Daniel Dupas break; 2410fefa676SJean-Daniel Dupas 2428b82f087SGreg Clayton case 'P': 243b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qProcessInfoPID:")) 244b9c1b51eSKate Stone return eServerPacketType_qProcessInfoPID; 245b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_shell:")) 246b9c1b51eSKate Stone return eServerPacketType_qPlatform_shell; 247b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_mkdir:")) 248b9c1b51eSKate Stone return eServerPacketType_qPlatform_mkdir; 249b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_chmod:")) 250b9c1b51eSKate Stone return eServerPacketType_qPlatform_chmod; 251b9c1b51eSKate Stone if (PACKET_MATCHES("qProcessInfo")) 252b9c1b51eSKate Stone return eServerPacketType_qProcessInfo; 2533cd8d7b1SGongyu Deng if (PACKET_STARTS_WITH("qPathComplete:")) 2543cd8d7b1SGongyu Deng return eServerPacketType_qPathComplete; 2558b82f087SGreg Clayton break; 2568b82f087SGreg Clayton 257ccd6cffbSTamas Berghammer case 'Q': 258b9c1b51eSKate Stone if (PACKET_MATCHES("qQueryGDBServer")) 259b9c1b51eSKate Stone return eServerPacketType_qQueryGDBServer; 260ccd6cffbSTamas Berghammer break; 261ccd6cffbSTamas Berghammer 2620fefa676SJean-Daniel Dupas case 'R': 263b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qRcmd,")) 264b9c1b51eSKate Stone return eServerPacketType_qRcmd; 265b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qRegisterInfo")) 266b9c1b51eSKate Stone return eServerPacketType_qRegisterInfo; 2670fefa676SJean-Daniel Dupas break; 268e0f8f574SDaniel Malea 2698b82f087SGreg Clayton case 'S': 27037cbd817SMichał Górny if (PACKET_STARTS_WITH("qSaveCore")) 27137cbd817SMichał Górny return eServerPacketType_qLLDBSaveCore; 272b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qSpeedTest:")) 273b9c1b51eSKate Stone return eServerPacketType_qSpeedTest; 274b9c1b51eSKate Stone if (PACKET_MATCHES("qShlibInfoAddr")) 275b9c1b51eSKate Stone return eServerPacketType_qShlibInfoAddr; 276b9c1b51eSKate Stone if (PACKET_MATCHES("qStepPacketSupported")) 277b9c1b51eSKate Stone return eServerPacketType_qStepPacketSupported; 278b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qSupported")) 279b9c1b51eSKate Stone return eServerPacketType_qSupported; 280b9c1b51eSKate Stone if (PACKET_MATCHES("qSyncThreadStateSupported")) 281b9c1b51eSKate Stone return eServerPacketType_qSyncThreadStateSupported; 2820fefa676SJean-Daniel Dupas break; 2830fefa676SJean-Daniel Dupas 2840fefa676SJean-Daniel Dupas case 'T': 285b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qThreadExtraInfo,")) 286b9c1b51eSKate Stone return eServerPacketType_qThreadExtraInfo; 287b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qThreadStopInfo")) 288b9c1b51eSKate Stone return eServerPacketType_qThreadStopInfo; 2898b82f087SGreg Clayton break; 2908b82f087SGreg Clayton 2918b82f087SGreg Clayton case 'U': 292b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qUserName:")) 293b9c1b51eSKate Stone return eServerPacketType_qUserName; 2948b82f087SGreg Clayton break; 2950fefa676SJean-Daniel Dupas 2960fefa676SJean-Daniel Dupas case 'V': 297b9c1b51eSKate Stone if (PACKET_MATCHES("qVAttachOrWaitSupported")) 298b9c1b51eSKate Stone return eServerPacketType_qVAttachOrWaitSupported; 2990fefa676SJean-Daniel Dupas break; 3000fefa676SJean-Daniel Dupas 3010fefa676SJean-Daniel Dupas case 'W': 302b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qWatchpointSupportInfo:")) 303b9c1b51eSKate Stone return eServerPacketType_qWatchpointSupportInfo; 304b9c1b51eSKate Stone if (PACKET_MATCHES("qWatchpointSupportInfo")) 305b9c1b51eSKate Stone return eServerPacketType_qWatchpointSupportInfoSupported; 3060fefa676SJean-Daniel Dupas break; 307af245d11STodd Fiala 308af245d11STodd Fiala case 'X': 30957e2da4fSAntonio Afonso if (PACKET_STARTS_WITH("qXfer:")) 31057e2da4fSAntonio Afonso return eServerPacketType_qXfer; 311af245d11STodd Fiala break; 3128b82f087SGreg Clayton } 313576d8834SGreg Clayton break; 31498d0a4b3SChaoren Lin 31598d0a4b3SChaoren Lin case 'j': 3162f1fbaebSPavel Labath if (PACKET_STARTS_WITH("jModulesInfo:")) 3172f1fbaebSPavel Labath return eServerPacketType_jModulesInfo; 318b9c1b51eSKate Stone if (PACKET_MATCHES("jSignalsInfo")) 319b9c1b51eSKate Stone return eServerPacketType_jSignalsInfo; 320b9c1b51eSKate Stone if (PACKET_MATCHES("jThreadsInfo")) 321b9c1b51eSKate Stone return eServerPacketType_jThreadsInfo; 3220b697561SWalter Erquinigo 3230b697561SWalter Erquinigo if (PACKET_MATCHES("jLLDBTraceSupported")) 3240b697561SWalter Erquinigo return eServerPacketType_jLLDBTraceSupported; 3250b697561SWalter Erquinigo if (PACKET_STARTS_WITH("jLLDBTraceStop:")) 3260b697561SWalter Erquinigo return eServerPacketType_jLLDBTraceStop; 3270b697561SWalter Erquinigo if (PACKET_STARTS_WITH("jLLDBTraceStart:")) 3280b697561SWalter Erquinigo return eServerPacketType_jLLDBTraceStart; 3290b697561SWalter Erquinigo if (PACKET_STARTS_WITH("jLLDBTraceGetState:")) 3300b697561SWalter Erquinigo return eServerPacketType_jLLDBTraceGetState; 3310b697561SWalter Erquinigo if (PACKET_STARTS_WITH("jLLDBTraceGetBinaryData:")) 3320b697561SWalter Erquinigo return eServerPacketType_jLLDBTraceGetBinaryData; 333cec91ef9SGreg Clayton break; 33498d0a4b3SChaoren Lin 335e0f8f574SDaniel Malea case 'v': 336b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vFile:")) { 337b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vFile:open:")) 338b9c1b51eSKate Stone return eServerPacketType_vFile_open; 339b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:close:")) 340b9c1b51eSKate Stone return eServerPacketType_vFile_close; 341b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:pread")) 342b9c1b51eSKate Stone return eServerPacketType_vFile_pread; 343b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:pwrite")) 344b9c1b51eSKate Stone return eServerPacketType_vFile_pwrite; 345b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:size")) 346b9c1b51eSKate Stone return eServerPacketType_vFile_size; 347b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:exists")) 348b9c1b51eSKate Stone return eServerPacketType_vFile_exists; 349a1097d31SMichał Górny else if (PACKET_STARTS_WITH("vFile:fstat")) 350a1097d31SMichał Górny return eServerPacketType_vFile_fstat; 351b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:stat")) 352b9c1b51eSKate Stone return eServerPacketType_vFile_stat; 353b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:mode")) 354b9c1b51eSKate Stone return eServerPacketType_vFile_mode; 355b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:MD5")) 356b9c1b51eSKate Stone return eServerPacketType_vFile_md5; 357b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:symlink")) 358b9c1b51eSKate Stone return eServerPacketType_vFile_symlink; 359b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:unlink")) 360b9c1b51eSKate Stone return eServerPacketType_vFile_unlink; 361e0f8f574SDaniel Malea 3620fefa676SJean-Daniel Dupas } else { 363b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttach;")) 364b9c1b51eSKate Stone return eServerPacketType_vAttach; 365b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachWait;")) 366b9c1b51eSKate Stone return eServerPacketType_vAttachWait; 367b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachOrWait;")) 368b9c1b51eSKate Stone return eServerPacketType_vAttachOrWait; 369b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachName;")) 370b9c1b51eSKate Stone return eServerPacketType_vAttachName; 371b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vCont;")) 372b9c1b51eSKate Stone return eServerPacketType_vCont; 373b9c1b51eSKate Stone if (PACKET_MATCHES("vCont?")) 374b9c1b51eSKate Stone return eServerPacketType_vCont_actions; 375*c18784baSMichał Górny if (PACKET_STARTS_WITH("vKill;")) 376*c18784baSMichał Górny return eServerPacketType_vKill; 3776ba3f723SMichał Górny if (PACKET_STARTS_WITH("vRun;")) 3786ba3f723SMichał Górny return eServerPacketType_vRun; 379bc04d240SMichał Górny if (PACKET_MATCHES("vStopped")) 380bc04d240SMichał Górny return eServerPacketType_vStopped; 381bc04d240SMichał Górny if (PACKET_MATCHES("vCtrlC")) 382bc04d240SMichał Górny return eServerPacketType_vCtrlC; 383bc04d240SMichał Górny break; 384bc04d240SMichał Górny 385e0f8f574SDaniel Malea } 386e0f8f574SDaniel Malea break; 3870fefa676SJean-Daniel Dupas case '_': 388b9c1b51eSKate Stone switch (packet_cstr[1]) { 3890fefa676SJean-Daniel Dupas case 'M': 3900fefa676SJean-Daniel Dupas return eServerPacketType__M; 3910fefa676SJean-Daniel Dupas 3920fefa676SJean-Daniel Dupas case 'm': 3930fefa676SJean-Daniel Dupas return eServerPacketType__m; 3940fefa676SJean-Daniel Dupas } 3950fefa676SJean-Daniel Dupas break; 3960fefa676SJean-Daniel Dupas 3970fefa676SJean-Daniel Dupas case '?': 398b9c1b51eSKate Stone if (packet_size == 1) 399b9c1b51eSKate Stone return eServerPacketType_stop_reason; 4000fefa676SJean-Daniel Dupas break; 4010fefa676SJean-Daniel Dupas 4020fefa676SJean-Daniel Dupas case 'c': 4030fefa676SJean-Daniel Dupas return eServerPacketType_c; 4040fefa676SJean-Daniel Dupas 4050fefa676SJean-Daniel Dupas case 'C': 4060fefa676SJean-Daniel Dupas return eServerPacketType_C; 4070fefa676SJean-Daniel Dupas 4080fefa676SJean-Daniel Dupas case 'D': 409b9c1b51eSKate Stone return eServerPacketType_D; 4100fefa676SJean-Daniel Dupas 4110fefa676SJean-Daniel Dupas case 'g': 412b9c1b51eSKate Stone return eServerPacketType_g; 4130fefa676SJean-Daniel Dupas 4140fefa676SJean-Daniel Dupas case 'G': 4150fefa676SJean-Daniel Dupas return eServerPacketType_G; 4160fefa676SJean-Daniel Dupas 4170fefa676SJean-Daniel Dupas case 'H': 4180fefa676SJean-Daniel Dupas return eServerPacketType_H; 4190fefa676SJean-Daniel Dupas 420e0be425aSVince Harron case 'I': 421e0be425aSVince Harron return eServerPacketType_I; 422e0be425aSVince Harron 4230fefa676SJean-Daniel Dupas case 'k': 424b9c1b51eSKate Stone if (packet_size == 1) 425b9c1b51eSKate Stone return eServerPacketType_k; 4260fefa676SJean-Daniel Dupas break; 4270fefa676SJean-Daniel Dupas 4280fefa676SJean-Daniel Dupas case 'm': 4290fefa676SJean-Daniel Dupas return eServerPacketType_m; 4300fefa676SJean-Daniel Dupas 4310fefa676SJean-Daniel Dupas case 'M': 4320fefa676SJean-Daniel Dupas return eServerPacketType_M; 4330fefa676SJean-Daniel Dupas 4340fefa676SJean-Daniel Dupas case 'p': 4350fefa676SJean-Daniel Dupas return eServerPacketType_p; 4360fefa676SJean-Daniel Dupas 4370fefa676SJean-Daniel Dupas case 'P': 4380fefa676SJean-Daniel Dupas return eServerPacketType_P; 4390fefa676SJean-Daniel Dupas 4400fefa676SJean-Daniel Dupas case 's': 441b9c1b51eSKate Stone if (packet_size == 1) 442b9c1b51eSKate Stone return eServerPacketType_s; 4430fefa676SJean-Daniel Dupas break; 4440fefa676SJean-Daniel Dupas 4450fefa676SJean-Daniel Dupas case 'S': 4460fefa676SJean-Daniel Dupas return eServerPacketType_S; 4470fefa676SJean-Daniel Dupas 4483bf11256SPavel Labath case 'x': 4493bf11256SPavel Labath return eServerPacketType_x; 4503bf11256SPavel Labath 4513bf11256SPavel Labath case 'X': 4523bf11256SPavel Labath return eServerPacketType_X; 4533bf11256SPavel Labath 4540fefa676SJean-Daniel Dupas case 'T': 4550fefa676SJean-Daniel Dupas return eServerPacketType_T; 4560fefa676SJean-Daniel Dupas 4570fefa676SJean-Daniel Dupas case 'z': 4580fefa676SJean-Daniel Dupas if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 4590fefa676SJean-Daniel Dupas return eServerPacketType_z; 4600fefa676SJean-Daniel Dupas break; 4610fefa676SJean-Daniel Dupas 4620fefa676SJean-Daniel Dupas case 'Z': 4630fefa676SJean-Daniel Dupas if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 4640fefa676SJean-Daniel Dupas return eServerPacketType_Z; 4650fefa676SJean-Daniel Dupas break; 466576d8834SGreg Clayton } 467576d8834SGreg Clayton return eServerPacketType_unimplemented; 468576d8834SGreg Clayton } 469576d8834SGreg Clayton 470b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsOKResponse() const { 471576d8834SGreg Clayton return GetResponseType() == eOK; 47230fdc8d8SChris Lattner } 47330fdc8d8SChris Lattner 474b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsUnsupportedResponse() const { 475576d8834SGreg Clayton return GetResponseType() == eUnsupported; 47630fdc8d8SChris Lattner } 47730fdc8d8SChris Lattner 478b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsNormalResponse() const { 479576d8834SGreg Clayton return GetResponseType() == eResponse; 48030fdc8d8SChris Lattner } 48130fdc8d8SChris Lattner 482b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsErrorResponse() const { 483dab1d5f3SRavitheja Addepally return GetResponseType() == eError && isxdigit(m_packet[1]) && 484dab1d5f3SRavitheja Addepally isxdigit(m_packet[2]); 48530fdc8d8SChris Lattner } 48630fdc8d8SChris Lattner 487b9c1b51eSKate Stone uint8_t StringExtractorGDBRemote::GetError() { 488b9c1b51eSKate Stone if (GetResponseType() == eError) { 48930fdc8d8SChris Lattner SetFilePos(1); 49030fdc8d8SChris Lattner return GetHexU8(255); 49130fdc8d8SChris Lattner } 49230fdc8d8SChris Lattner return 0; 49330fdc8d8SChris Lattner } 494e0f8f574SDaniel Malea 495dab1d5f3SRavitheja Addepally lldb_private::Status StringExtractorGDBRemote::GetStatus() { 496dab1d5f3SRavitheja Addepally lldb_private::Status error; 497dab1d5f3SRavitheja Addepally if (GetResponseType() == eError) { 498dab1d5f3SRavitheja Addepally SetFilePos(1); 499dab1d5f3SRavitheja Addepally uint8_t errc = GetHexU8(255); 500dab1d5f3SRavitheja Addepally error.SetError(errc, lldb::eErrorTypeGeneric); 501dab1d5f3SRavitheja Addepally 502fa73e340SRavitheja Addepally error.SetErrorStringWithFormat("Error %u", errc); 503fa73e340SRavitheja Addepally std::string error_messg; 504fa73e340SRavitheja Addepally if (GetChar() == ';') { 505dab1d5f3SRavitheja Addepally GetHexByteString(error_messg); 506dab1d5f3SRavitheja Addepally error.SetErrorString(error_messg); 507dab1d5f3SRavitheja Addepally } 508fa73e340SRavitheja Addepally } 509dab1d5f3SRavitheja Addepally return error; 510dab1d5f3SRavitheja Addepally } 511dab1d5f3SRavitheja Addepally 512b9c1b51eSKate Stone size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) { 513b9c1b51eSKate Stone // Just get the data bytes in the string as 51405097246SAdrian Prantl // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped 51505097246SAdrian Prantl // characters. If any 0x7d characters are left in the packet, then they are 51605097246SAdrian Prantl // supposed to be there... 517e0f8f574SDaniel Malea str.clear(); 518109534cbSGreg Clayton const size_t bytes_left = GetBytesLeft(); 519b9c1b51eSKate Stone if (bytes_left > 0) { 520109534cbSGreg Clayton str.assign(m_packet, m_index, bytes_left); 521109534cbSGreg Clayton m_index += bytes_left; 522e0f8f574SDaniel Malea } 523e0f8f574SDaniel Malea return str.size(); 524e0f8f574SDaniel Malea } 525e0f8f574SDaniel Malea 526830c81d5SGreg Clayton static bool 527b9c1b51eSKate Stone OKErrorNotSupportedResponseValidator(void *, 528b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 529b9c1b51eSKate Stone switch (response.GetResponseType()) { 530830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 531830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 532830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 533830c81d5SGreg Clayton return true; 534830c81d5SGreg Clayton 535830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 536830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 537830c81d5SGreg Clayton case StringExtractorGDBRemote::eResponse: 538830c81d5SGreg Clayton break; 539830c81d5SGreg Clayton } 540830c81d5SGreg Clayton return false; 541830c81d5SGreg Clayton } 542830c81d5SGreg Clayton 543b9c1b51eSKate Stone static bool JSONResponseValidator(void *, 544b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 545b9c1b51eSKate Stone switch (response.GetResponseType()) { 546830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 547830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 548830c81d5SGreg Clayton return true; // Accept unsupported or EXX as valid responses 549830c81d5SGreg Clayton 550830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 551830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 552830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 553830c81d5SGreg Clayton break; 554830c81d5SGreg Clayton 555830c81d5SGreg Clayton case StringExtractorGDBRemote::eResponse: 556830c81d5SGreg Clayton // JSON that is returned in from JSON query packets is currently always 55705097246SAdrian Prantl // either a dictionary which starts with a '{', or an array which starts 55805097246SAdrian Prantl // with a '['. This is a quick validator to just make sure the response 55905097246SAdrian Prantl // could be valid JSON without having to validate all of the 560830c81d5SGreg Clayton // JSON content. 561b9c1b51eSKate Stone switch (response.GetStringRef()[0]) { 562b9c1b51eSKate Stone case '{': 563b9c1b51eSKate Stone return true; 564b9c1b51eSKate Stone case '[': 565b9c1b51eSKate Stone return true; 566830c81d5SGreg Clayton default: 567830c81d5SGreg Clayton break; 568830c81d5SGreg Clayton } 569830c81d5SGreg Clayton break; 570830c81d5SGreg Clayton } 571830c81d5SGreg Clayton return false; 572830c81d5SGreg Clayton } 573830c81d5SGreg Clayton 574830c81d5SGreg Clayton static bool 575b9c1b51eSKate Stone ASCIIHexBytesResponseValidator(void *, 576b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 577b9c1b51eSKate Stone switch (response.GetResponseType()) { 578830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 579830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 580830c81d5SGreg Clayton return true; // Accept unsupported or EXX as valid responses 581830c81d5SGreg Clayton 582830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 583830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 584830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 585830c81d5SGreg Clayton break; 586830c81d5SGreg Clayton 587b9c1b51eSKate Stone case StringExtractorGDBRemote::eResponse: { 588830c81d5SGreg Clayton uint32_t valid_count = 0; 589b9c1b51eSKate Stone for (const char ch : response.GetStringRef()) { 590b9c1b51eSKate Stone if (!isxdigit(ch)) { 591830c81d5SGreg Clayton return false; 592830c81d5SGreg Clayton } 593830c81d5SGreg Clayton if (++valid_count >= 16) 594b9c1b51eSKate Stone break; // Don't validate all the characters in case the packet is very 595b9c1b51eSKate Stone // large 596830c81d5SGreg Clayton } 597830c81d5SGreg Clayton return true; 598b9c1b51eSKate Stone } break; 599830c81d5SGreg Clayton } 600830c81d5SGreg Clayton return false; 601830c81d5SGreg Clayton } 602830c81d5SGreg Clayton 603b9c1b51eSKate Stone void StringExtractorGDBRemote::CopyResponseValidator( 604b9c1b51eSKate Stone const StringExtractorGDBRemote &rhs) { 605830c81d5SGreg Clayton m_validator = rhs.m_validator; 606830c81d5SGreg Clayton m_validator_baton = rhs.m_validator_baton; 607830c81d5SGreg Clayton } 608830c81d5SGreg Clayton 609b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidator( 610b9c1b51eSKate Stone ResponseValidatorCallback callback, void *baton) { 611830c81d5SGreg Clayton m_validator = callback; 612830c81d5SGreg Clayton m_validator_baton = baton; 613830c81d5SGreg Clayton } 614830c81d5SGreg Clayton 615b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() { 616830c81d5SGreg Clayton m_validator = OKErrorNotSupportedResponseValidator; 617830c81d5SGreg Clayton m_validator_baton = nullptr; 618830c81d5SGreg Clayton } 619830c81d5SGreg Clayton 620b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() { 621830c81d5SGreg Clayton m_validator = ASCIIHexBytesResponseValidator; 622830c81d5SGreg Clayton m_validator_baton = nullptr; 623830c81d5SGreg Clayton } 624830c81d5SGreg Clayton 625b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToJSON() { 626830c81d5SGreg Clayton m_validator = JSONResponseValidator; 627830c81d5SGreg Clayton m_validator_baton = nullptr; 628830c81d5SGreg Clayton } 629830c81d5SGreg Clayton 630b9c1b51eSKate Stone bool StringExtractorGDBRemote::ValidateResponse() const { 631830c81d5SGreg Clayton // If we have a validator callback, try to validate the callback 632830c81d5SGreg Clayton if (m_validator) 633830c81d5SGreg Clayton return m_validator(m_validator_baton, *this); 634830c81d5SGreg Clayton else 635830c81d5SGreg Clayton return true; // No validator, so response is valid 636830c81d5SGreg Clayton } 6376c1a8039SMichał Górny 6386c1a8039SMichał Górny llvm::Optional<std::pair<lldb::pid_t, lldb::tid_t>> 6396c1a8039SMichał Górny StringExtractorGDBRemote::GetPidTid(lldb::pid_t default_pid) { 6406c1a8039SMichał Górny llvm::StringRef view = llvm::StringRef(m_packet).substr(m_index); 6416c1a8039SMichał Górny size_t initial_length = view.size(); 6426c1a8039SMichał Górny lldb::pid_t pid = default_pid; 6436c1a8039SMichał Górny lldb::tid_t tid; 6446c1a8039SMichał Górny 6456c1a8039SMichał Górny if (view.consume_front("p")) { 6466c1a8039SMichał Górny // process identifier 6476c1a8039SMichał Górny if (view.consume_front("-1")) { 6486c1a8039SMichał Górny // -1 is a special case 6496c1a8039SMichał Górny pid = AllProcesses; 6506c1a8039SMichał Górny } else if (view.consumeInteger(16, pid) || pid == 0) { 6516c1a8039SMichał Górny // not a valid hex integer OR unsupported pid 0 6526c1a8039SMichał Górny m_index = UINT64_MAX; 6536c1a8039SMichał Górny return llvm::None; 6546c1a8039SMichał Górny } 6556c1a8039SMichał Górny 6566c1a8039SMichał Górny // "." must follow if we expect TID too; otherwise, we assume -1 6576c1a8039SMichał Górny if (!view.consume_front(".")) { 6586c1a8039SMichał Górny // update m_index 6596c1a8039SMichał Górny m_index += initial_length - view.size(); 6606c1a8039SMichał Górny 6616c1a8039SMichał Górny return {{pid, AllThreads}}; 6626c1a8039SMichał Górny } 6636c1a8039SMichał Górny } 6646c1a8039SMichał Górny 6656c1a8039SMichał Górny // thread identifier 6666c1a8039SMichał Górny if (view.consume_front("-1")) { 6676c1a8039SMichał Górny // -1 is a special case 6686c1a8039SMichał Górny tid = AllThreads; 6696c1a8039SMichał Górny } else if (view.consumeInteger(16, tid) || tid == 0 || pid == AllProcesses) { 6706c1a8039SMichał Górny // not a valid hex integer OR tid 0 OR pid -1 + a specific tid 6716c1a8039SMichał Górny m_index = UINT64_MAX; 6726c1a8039SMichał Górny return llvm::None; 6736c1a8039SMichał Górny } 6746c1a8039SMichał Górny 6756c1a8039SMichał Górny // update m_index 6766c1a8039SMichał Górny m_index += initial_length - view.size(); 6776c1a8039SMichał Górny 6786c1a8039SMichał Górny return {{pid, tid}}; 6796c1a8039SMichał Górny } 680