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 11672d2c12SJonas Devlieghere #include <ctype.h> 124479ac15SZachary Turner #include <string.h> 134479ac15SZachary Turner 14576d8834SGreg Clayton StringExtractorGDBRemote::ResponseType 15b9c1b51eSKate Stone StringExtractorGDBRemote::GetResponseType() const { 1630fdc8d8SChris Lattner if (m_packet.empty()) 1730fdc8d8SChris Lattner return eUnsupported; 1830fdc8d8SChris Lattner 19b9c1b51eSKate Stone switch (m_packet[0]) { 2030fdc8d8SChris Lattner case 'E': 21dab1d5f3SRavitheja Addepally if (isxdigit(m_packet[1]) && isxdigit(m_packet[2])) { 22dab1d5f3SRavitheja Addepally if (m_packet.size() == 3) 2330fdc8d8SChris Lattner return eError; 24dab1d5f3SRavitheja Addepally llvm::StringRef packet_ref(m_packet); 25dab1d5f3SRavitheja Addepally if (packet_ref[3] == ';') { 26dab1d5f3SRavitheja Addepally auto err_string = packet_ref.substr(4); 27dab1d5f3SRavitheja Addepally for (auto e : err_string) 28dab1d5f3SRavitheja Addepally if (!isxdigit(e)) 29dab1d5f3SRavitheja Addepally return eResponse; 30dab1d5f3SRavitheja Addepally return eError; 31dab1d5f3SRavitheja Addepally } 32dab1d5f3SRavitheja Addepally } 3330fdc8d8SChris Lattner break; 3430fdc8d8SChris Lattner 3530fdc8d8SChris Lattner case 'O': 3630fdc8d8SChris Lattner if (m_packet.size() == 2 && m_packet[1] == 'K') 3730fdc8d8SChris Lattner return eOK; 3830fdc8d8SChris Lattner break; 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner case '+': 4130fdc8d8SChris Lattner if (m_packet.size() == 1) 4230fdc8d8SChris Lattner return eAck; 4330fdc8d8SChris Lattner break; 4430fdc8d8SChris Lattner 4530fdc8d8SChris Lattner case '-': 4630fdc8d8SChris Lattner if (m_packet.size() == 1) 4730fdc8d8SChris Lattner return eNack; 4830fdc8d8SChris Lattner break; 4930fdc8d8SChris Lattner } 5030fdc8d8SChris Lattner return eResponse; 5130fdc8d8SChris Lattner } 5230fdc8d8SChris Lattner 53576d8834SGreg Clayton StringExtractorGDBRemote::ServerPacketType 54b9c1b51eSKate Stone StringExtractorGDBRemote::GetServerPacketType() const { 55b9c1b51eSKate Stone #define PACKET_MATCHES(s) \ 56b9c1b51eSKate Stone ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0)) 57b9c1b51eSKate Stone #define PACKET_STARTS_WITH(s) \ 58b9c1b51eSKate Stone ((packet_size >= (sizeof(s) - 1)) && \ 59b9c1b51eSKate Stone ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0) 608b82f087SGreg Clayton 61576d8834SGreg Clayton // Empty is not a supported packet... 62576d8834SGreg Clayton if (m_packet.empty()) 63576d8834SGreg Clayton return eServerPacketType_invalid; 64576d8834SGreg Clayton 658b82f087SGreg Clayton const size_t packet_size = m_packet.size(); 66576d8834SGreg Clayton const char *packet_cstr = m_packet.c_str(); 67b9c1b51eSKate Stone switch (m_packet[0]) { 6878baa197SEwan Crawford 6978baa197SEwan Crawford case '%': 7078baa197SEwan Crawford return eServerPacketType_notify; 7178baa197SEwan Crawford 72d314e810SGreg Clayton case '\x03': 73b9c1b51eSKate Stone if (packet_size == 1) 74b9c1b51eSKate Stone return eServerPacketType_interrupt; 75d314e810SGreg Clayton break; 76d314e810SGreg Clayton 77576d8834SGreg Clayton case '-': 78b9c1b51eSKate Stone if (packet_size == 1) 79b9c1b51eSKate Stone return eServerPacketType_nack; 80576d8834SGreg Clayton break; 81576d8834SGreg Clayton 82576d8834SGreg Clayton case '+': 83b9c1b51eSKate Stone if (packet_size == 1) 84b9c1b51eSKate Stone return eServerPacketType_ack; 85576d8834SGreg Clayton break; 86576d8834SGreg Clayton 878b82f087SGreg Clayton case 'A': 888b82f087SGreg Clayton return eServerPacketType_A; 898b82f087SGreg Clayton 901cb6496eSGreg Clayton case 'Q': 910fefa676SJean-Daniel Dupas 92b9c1b51eSKate Stone switch (packet_cstr[1]) { 938b82f087SGreg Clayton case 'E': 94b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QEnvironment:")) 95b9c1b51eSKate Stone return eServerPacketType_QEnvironment; 96b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:")) 97b9c1b51eSKate Stone return eServerPacketType_QEnvironmentHexEncoded; 98dab1d5f3SRavitheja Addepally if (PACKET_STARTS_WITH("QEnableErrorStrings")) 99dab1d5f3SRavitheja Addepally return eServerPacketType_QEnableErrorStrings; 1008b82f087SGreg Clayton break; 1018b82f087SGreg Clayton 1024a705e7eSPavel Labath case 'P': 1034a705e7eSPavel Labath if (PACKET_STARTS_WITH("QPassSignals:")) 1044a705e7eSPavel Labath return eServerPacketType_QPassSignals; 1055b075d63SGreg Clayton break; 1064a705e7eSPavel Labath 1078b82f087SGreg Clayton case 'S': 108b9c1b51eSKate Stone if (PACKET_MATCHES("QStartNoAckMode")) 109b9c1b51eSKate Stone return eServerPacketType_QStartNoAckMode; 110b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSaveRegisterState")) 111b9c1b51eSKate Stone return eServerPacketType_QSaveRegisterState; 112b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetDisableASLR:")) 113b9c1b51eSKate Stone return eServerPacketType_QSetDisableASLR; 114b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetDetachOnError:")) 115b9c1b51eSKate Stone return eServerPacketType_QSetDetachOnError; 116b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDIN:")) 117b9c1b51eSKate Stone return eServerPacketType_QSetSTDIN; 118b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDOUT:")) 119b9c1b51eSKate Stone return eServerPacketType_QSetSTDOUT; 120b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDERR:")) 121b9c1b51eSKate Stone return eServerPacketType_QSetSTDERR; 122b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetWorkingDir:")) 123b9c1b51eSKate Stone return eServerPacketType_QSetWorkingDir; 124b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetLogging:")) 125b9c1b51eSKate Stone return eServerPacketType_QSetLogging; 126b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetMaxPacketSize:")) 127b9c1b51eSKate Stone return eServerPacketType_QSetMaxPacketSize; 128b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetMaxPayloadSize:")) 129b9c1b51eSKate Stone return eServerPacketType_QSetMaxPayloadSize; 130b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;")) 131b9c1b51eSKate Stone return eServerPacketType_QSetEnableAsyncProfiling; 132b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSyncThreadState:")) 133b9c1b51eSKate Stone return eServerPacketType_QSyncThreadState; 1348b82f087SGreg Clayton break; 1350fefa676SJean-Daniel Dupas 136e0f8f574SDaniel Malea case 'L': 137b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QLaunchArch:")) 138b9c1b51eSKate Stone return eServerPacketType_QLaunchArch; 139b9c1b51eSKate Stone if (PACKET_MATCHES("QListThreadsInStopReply")) 140b9c1b51eSKate Stone return eServerPacketType_QListThreadsInStopReply; 1410fefa676SJean-Daniel Dupas break; 1420fefa676SJean-Daniel Dupas 1430fefa676SJean-Daniel Dupas case 'R': 144b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QRestoreRegisterState:")) 145b9c1b51eSKate Stone return eServerPacketType_QRestoreRegisterState; 1460fefa676SJean-Daniel Dupas break; 1470fefa676SJean-Daniel Dupas 1480fefa676SJean-Daniel Dupas case 'T': 149b9c1b51eSKate Stone if (PACKET_MATCHES("QThreadSuffixSupported")) 150b9c1b51eSKate Stone return eServerPacketType_QThreadSuffixSupported; 151e0f8f574SDaniel Malea break; 1528b82f087SGreg Clayton } 1531cb6496eSGreg Clayton break; 1541cb6496eSGreg Clayton 155576d8834SGreg Clayton case 'q': 156b9c1b51eSKate Stone switch (packet_cstr[1]) { 1578b82f087SGreg Clayton case 's': 158b9c1b51eSKate Stone if (PACKET_MATCHES("qsProcessInfo")) 159b9c1b51eSKate Stone return eServerPacketType_qsProcessInfo; 160b9c1b51eSKate Stone if (PACKET_MATCHES("qsThreadInfo")) 161b9c1b51eSKate Stone return eServerPacketType_qsThreadInfo; 1628b82f087SGreg Clayton break; 1638b82f087SGreg Clayton 1648b82f087SGreg Clayton case 'f': 165b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qfProcessInfo")) 166b9c1b51eSKate Stone return eServerPacketType_qfProcessInfo; 167b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qfThreadInfo")) 168b9c1b51eSKate Stone return eServerPacketType_qfThreadInfo; 1698b82f087SGreg Clayton break; 1708b82f087SGreg Clayton 1718b82f087SGreg Clayton case 'C': 172b9c1b51eSKate Stone if (packet_size == 2) 173b9c1b51eSKate Stone return eServerPacketType_qC; 1748b82f087SGreg Clayton break; 1758b82f087SGreg Clayton 176420562aaSGreg Clayton case 'E': 177b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qEcho:")) 178b9c1b51eSKate Stone return eServerPacketType_qEcho; 179420562aaSGreg Clayton break; 180420562aaSGreg Clayton 181783bfc8cSTamas Berghammer case 'F': 182b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qFileLoadAddress:")) 183b9c1b51eSKate Stone return eServerPacketType_qFileLoadAddress; 184783bfc8cSTamas Berghammer break; 185783bfc8cSTamas Berghammer 1868b82f087SGreg Clayton case 'G': 187b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qGroupName:")) 188b9c1b51eSKate Stone return eServerPacketType_qGroupName; 189b9c1b51eSKate Stone if (PACKET_MATCHES("qGetWorkingDir")) 190b9c1b51eSKate Stone return eServerPacketType_qGetWorkingDir; 191b9c1b51eSKate Stone if (PACKET_MATCHES("qGetPid")) 192b9c1b51eSKate Stone return eServerPacketType_qGetPid; 193b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qGetProfileData;")) 194b9c1b51eSKate Stone return eServerPacketType_qGetProfileData; 195b9c1b51eSKate Stone if (PACKET_MATCHES("qGDBServerVersion")) 196b9c1b51eSKate Stone return eServerPacketType_qGDBServerVersion; 1978b82f087SGreg Clayton break; 1988b82f087SGreg Clayton 1998b82f087SGreg Clayton case 'H': 200b9c1b51eSKate Stone if (PACKET_MATCHES("qHostInfo")) 201b9c1b51eSKate Stone return eServerPacketType_qHostInfo; 2028b82f087SGreg Clayton break; 2038b82f087SGreg Clayton 204e0f8f574SDaniel Malea case 'K': 205b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qKillSpawnedProcess")) 206b9c1b51eSKate Stone return eServerPacketType_qKillSpawnedProcess; 207e0f8f574SDaniel Malea break; 208e0f8f574SDaniel Malea 2098b82f087SGreg Clayton case 'L': 210b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qLaunchGDBServer")) 211b9c1b51eSKate Stone return eServerPacketType_qLaunchGDBServer; 212b9c1b51eSKate Stone if (PACKET_MATCHES("qLaunchSuccess")) 213b9c1b51eSKate Stone return eServerPacketType_qLaunchSuccess; 2148b82f087SGreg Clayton break; 2158b82f087SGreg Clayton 2160fefa676SJean-Daniel Dupas case 'M': 217b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qMemoryRegionInfo:")) 218b9c1b51eSKate Stone return eServerPacketType_qMemoryRegionInfo; 219b9c1b51eSKate Stone if (PACKET_MATCHES("qMemoryRegionInfo")) 220b9c1b51eSKate Stone return eServerPacketType_qMemoryRegionInfoSupported; 221b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qModuleInfo:")) 222b9c1b51eSKate Stone return eServerPacketType_qModuleInfo; 2230fefa676SJean-Daniel Dupas break; 2240fefa676SJean-Daniel Dupas 2258b82f087SGreg Clayton case 'P': 226b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qProcessInfoPID:")) 227b9c1b51eSKate Stone return eServerPacketType_qProcessInfoPID; 228b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_shell:")) 229b9c1b51eSKate Stone return eServerPacketType_qPlatform_shell; 230b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_mkdir:")) 231b9c1b51eSKate Stone return eServerPacketType_qPlatform_mkdir; 232b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_chmod:")) 233b9c1b51eSKate Stone return eServerPacketType_qPlatform_chmod; 234b9c1b51eSKate Stone if (PACKET_MATCHES("qProcessInfo")) 235b9c1b51eSKate Stone return eServerPacketType_qProcessInfo; 236*3cd8d7b1SGongyu Deng if (PACKET_STARTS_WITH("qPathComplete:")) 237*3cd8d7b1SGongyu Deng return eServerPacketType_qPathComplete; 2388b82f087SGreg Clayton break; 2398b82f087SGreg Clayton 240ccd6cffbSTamas Berghammer case 'Q': 241b9c1b51eSKate Stone if (PACKET_MATCHES("qQueryGDBServer")) 242b9c1b51eSKate Stone return eServerPacketType_qQueryGDBServer; 243ccd6cffbSTamas Berghammer break; 244ccd6cffbSTamas Berghammer 2450fefa676SJean-Daniel Dupas case 'R': 246b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qRcmd,")) 247b9c1b51eSKate Stone return eServerPacketType_qRcmd; 248b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qRegisterInfo")) 249b9c1b51eSKate Stone return eServerPacketType_qRegisterInfo; 2500fefa676SJean-Daniel Dupas break; 251e0f8f574SDaniel Malea 2528b82f087SGreg Clayton case 'S': 253b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qSpeedTest:")) 254b9c1b51eSKate Stone return eServerPacketType_qSpeedTest; 255b9c1b51eSKate Stone if (PACKET_MATCHES("qShlibInfoAddr")) 256b9c1b51eSKate Stone return eServerPacketType_qShlibInfoAddr; 257b9c1b51eSKate Stone if (PACKET_MATCHES("qStepPacketSupported")) 258b9c1b51eSKate Stone return eServerPacketType_qStepPacketSupported; 259b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qSupported")) 260b9c1b51eSKate Stone return eServerPacketType_qSupported; 261b9c1b51eSKate Stone if (PACKET_MATCHES("qSyncThreadStateSupported")) 262b9c1b51eSKate Stone return eServerPacketType_qSyncThreadStateSupported; 2630fefa676SJean-Daniel Dupas break; 2640fefa676SJean-Daniel Dupas 2650fefa676SJean-Daniel Dupas case 'T': 266b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qThreadExtraInfo,")) 267b9c1b51eSKate Stone return eServerPacketType_qThreadExtraInfo; 268b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qThreadStopInfo")) 269b9c1b51eSKate Stone return eServerPacketType_qThreadStopInfo; 2708b82f087SGreg Clayton break; 2718b82f087SGreg Clayton 2728b82f087SGreg Clayton case 'U': 273b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qUserName:")) 274b9c1b51eSKate Stone return eServerPacketType_qUserName; 2758b82f087SGreg Clayton break; 2760fefa676SJean-Daniel Dupas 2770fefa676SJean-Daniel Dupas case 'V': 278b9c1b51eSKate Stone if (PACKET_MATCHES("qVAttachOrWaitSupported")) 279b9c1b51eSKate Stone return eServerPacketType_qVAttachOrWaitSupported; 2800fefa676SJean-Daniel Dupas break; 2810fefa676SJean-Daniel Dupas 2820fefa676SJean-Daniel Dupas case 'W': 283b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qWatchpointSupportInfo:")) 284b9c1b51eSKate Stone return eServerPacketType_qWatchpointSupportInfo; 285b9c1b51eSKate Stone if (PACKET_MATCHES("qWatchpointSupportInfo")) 286b9c1b51eSKate Stone return eServerPacketType_qWatchpointSupportInfoSupported; 2870fefa676SJean-Daniel Dupas break; 288af245d11STodd Fiala 289af245d11STodd Fiala case 'X': 29057e2da4fSAntonio Afonso if (PACKET_STARTS_WITH("qXfer:")) 29157e2da4fSAntonio Afonso return eServerPacketType_qXfer; 292af245d11STodd Fiala break; 2938b82f087SGreg Clayton } 294576d8834SGreg Clayton break; 29598d0a4b3SChaoren Lin 29698d0a4b3SChaoren Lin case 'j': 2972f1fbaebSPavel Labath if (PACKET_STARTS_WITH("jModulesInfo:")) 2982f1fbaebSPavel Labath return eServerPacketType_jModulesInfo; 299b9c1b51eSKate Stone if (PACKET_MATCHES("jSignalsInfo")) 300b9c1b51eSKate Stone return eServerPacketType_jSignalsInfo; 301b9c1b51eSKate Stone if (PACKET_MATCHES("jThreadsInfo")) 302b9c1b51eSKate Stone return eServerPacketType_jThreadsInfo; 303e714c4f5SRavitheja Addepally if (PACKET_STARTS_WITH("jTraceBufferRead:")) 304e714c4f5SRavitheja Addepally return eServerPacketType_jTraceBufferRead; 305e714c4f5SRavitheja Addepally if (PACKET_STARTS_WITH("jTraceConfigRead:")) 306e714c4f5SRavitheja Addepally return eServerPacketType_jTraceConfigRead; 307e714c4f5SRavitheja Addepally if (PACKET_STARTS_WITH("jTraceMetaRead:")) 308e714c4f5SRavitheja Addepally return eServerPacketType_jTraceMetaRead; 309e714c4f5SRavitheja Addepally if (PACKET_STARTS_WITH("jTraceStart:")) 310e714c4f5SRavitheja Addepally return eServerPacketType_jTraceStart; 311e714c4f5SRavitheja Addepally if (PACKET_STARTS_WITH("jTraceStop:")) 312e714c4f5SRavitheja Addepally return eServerPacketType_jTraceStop; 313cec91ef9SGreg Clayton break; 31498d0a4b3SChaoren Lin 315e0f8f574SDaniel Malea case 'v': 316b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vFile:")) { 317b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vFile:open:")) 318b9c1b51eSKate Stone return eServerPacketType_vFile_open; 319b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:close:")) 320b9c1b51eSKate Stone return eServerPacketType_vFile_close; 321b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:pread")) 322b9c1b51eSKate Stone return eServerPacketType_vFile_pread; 323b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:pwrite")) 324b9c1b51eSKate Stone return eServerPacketType_vFile_pwrite; 325b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:size")) 326b9c1b51eSKate Stone return eServerPacketType_vFile_size; 327b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:exists")) 328b9c1b51eSKate Stone return eServerPacketType_vFile_exists; 329b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:stat")) 330b9c1b51eSKate Stone return eServerPacketType_vFile_stat; 331b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:mode")) 332b9c1b51eSKate Stone return eServerPacketType_vFile_mode; 333b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:MD5")) 334b9c1b51eSKate Stone return eServerPacketType_vFile_md5; 335b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:symlink")) 336b9c1b51eSKate Stone return eServerPacketType_vFile_symlink; 337b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:unlink")) 338b9c1b51eSKate Stone return eServerPacketType_vFile_unlink; 339e0f8f574SDaniel Malea 3400fefa676SJean-Daniel Dupas } else { 341b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttach;")) 342b9c1b51eSKate Stone return eServerPacketType_vAttach; 343b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachWait;")) 344b9c1b51eSKate Stone return eServerPacketType_vAttachWait; 345b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachOrWait;")) 346b9c1b51eSKate Stone return eServerPacketType_vAttachOrWait; 347b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachName;")) 348b9c1b51eSKate Stone return eServerPacketType_vAttachName; 349b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vCont;")) 350b9c1b51eSKate Stone return eServerPacketType_vCont; 351b9c1b51eSKate Stone if (PACKET_MATCHES("vCont?")) 352b9c1b51eSKate Stone return eServerPacketType_vCont_actions; 353e0f8f574SDaniel Malea } 354e0f8f574SDaniel Malea break; 3550fefa676SJean-Daniel Dupas case '_': 356b9c1b51eSKate Stone switch (packet_cstr[1]) { 3570fefa676SJean-Daniel Dupas case 'M': 3580fefa676SJean-Daniel Dupas return eServerPacketType__M; 3590fefa676SJean-Daniel Dupas 3600fefa676SJean-Daniel Dupas case 'm': 3610fefa676SJean-Daniel Dupas return eServerPacketType__m; 3620fefa676SJean-Daniel Dupas } 3630fefa676SJean-Daniel Dupas break; 3640fefa676SJean-Daniel Dupas 3650fefa676SJean-Daniel Dupas case '?': 366b9c1b51eSKate Stone if (packet_size == 1) 367b9c1b51eSKate Stone return eServerPacketType_stop_reason; 3680fefa676SJean-Daniel Dupas break; 3690fefa676SJean-Daniel Dupas 3700fefa676SJean-Daniel Dupas case 'c': 3710fefa676SJean-Daniel Dupas return eServerPacketType_c; 3720fefa676SJean-Daniel Dupas 3730fefa676SJean-Daniel Dupas case 'C': 3740fefa676SJean-Daniel Dupas return eServerPacketType_C; 3750fefa676SJean-Daniel Dupas 3760fefa676SJean-Daniel Dupas case 'D': 377b9c1b51eSKate Stone if (packet_size == 1) 378b9c1b51eSKate Stone return eServerPacketType_D; 3790fefa676SJean-Daniel Dupas break; 3800fefa676SJean-Daniel Dupas 3810fefa676SJean-Daniel Dupas case 'g': 382b9c1b51eSKate Stone return eServerPacketType_g; 3830fefa676SJean-Daniel Dupas 3840fefa676SJean-Daniel Dupas case 'G': 3850fefa676SJean-Daniel Dupas return eServerPacketType_G; 3860fefa676SJean-Daniel Dupas 3870fefa676SJean-Daniel Dupas case 'H': 3880fefa676SJean-Daniel Dupas return eServerPacketType_H; 3890fefa676SJean-Daniel Dupas 390e0be425aSVince Harron case 'I': 391e0be425aSVince Harron return eServerPacketType_I; 392e0be425aSVince Harron 3930fefa676SJean-Daniel Dupas case 'k': 394b9c1b51eSKate Stone if (packet_size == 1) 395b9c1b51eSKate Stone return eServerPacketType_k; 3960fefa676SJean-Daniel Dupas break; 3970fefa676SJean-Daniel Dupas 3980fefa676SJean-Daniel Dupas case 'm': 3990fefa676SJean-Daniel Dupas return eServerPacketType_m; 4000fefa676SJean-Daniel Dupas 4010fefa676SJean-Daniel Dupas case 'M': 4020fefa676SJean-Daniel Dupas return eServerPacketType_M; 4030fefa676SJean-Daniel Dupas 4040fefa676SJean-Daniel Dupas case 'p': 4050fefa676SJean-Daniel Dupas return eServerPacketType_p; 4060fefa676SJean-Daniel Dupas 4070fefa676SJean-Daniel Dupas case 'P': 4080fefa676SJean-Daniel Dupas return eServerPacketType_P; 4090fefa676SJean-Daniel Dupas 4100fefa676SJean-Daniel Dupas case 's': 411b9c1b51eSKate Stone if (packet_size == 1) 412b9c1b51eSKate Stone return eServerPacketType_s; 4130fefa676SJean-Daniel Dupas break; 4140fefa676SJean-Daniel Dupas 4150fefa676SJean-Daniel Dupas case 'S': 4160fefa676SJean-Daniel Dupas return eServerPacketType_S; 4170fefa676SJean-Daniel Dupas 4183bf11256SPavel Labath case 'x': 4193bf11256SPavel Labath return eServerPacketType_x; 4203bf11256SPavel Labath 4213bf11256SPavel Labath case 'X': 4223bf11256SPavel Labath return eServerPacketType_X; 4233bf11256SPavel Labath 4240fefa676SJean-Daniel Dupas case 'T': 4250fefa676SJean-Daniel Dupas return eServerPacketType_T; 4260fefa676SJean-Daniel Dupas 4270fefa676SJean-Daniel Dupas case 'z': 4280fefa676SJean-Daniel Dupas if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 4290fefa676SJean-Daniel Dupas return eServerPacketType_z; 4300fefa676SJean-Daniel Dupas break; 4310fefa676SJean-Daniel Dupas 4320fefa676SJean-Daniel Dupas case 'Z': 4330fefa676SJean-Daniel Dupas if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 4340fefa676SJean-Daniel Dupas return eServerPacketType_Z; 4350fefa676SJean-Daniel Dupas break; 436576d8834SGreg Clayton } 437576d8834SGreg Clayton return eServerPacketType_unimplemented; 438576d8834SGreg Clayton } 439576d8834SGreg Clayton 440b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsOKResponse() const { 441576d8834SGreg Clayton return GetResponseType() == eOK; 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner 444b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsUnsupportedResponse() const { 445576d8834SGreg Clayton return GetResponseType() == eUnsupported; 44630fdc8d8SChris Lattner } 44730fdc8d8SChris Lattner 448b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsNormalResponse() const { 449576d8834SGreg Clayton return GetResponseType() == eResponse; 45030fdc8d8SChris Lattner } 45130fdc8d8SChris Lattner 452b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsErrorResponse() const { 453dab1d5f3SRavitheja Addepally return GetResponseType() == eError && isxdigit(m_packet[1]) && 454dab1d5f3SRavitheja Addepally isxdigit(m_packet[2]); 45530fdc8d8SChris Lattner } 45630fdc8d8SChris Lattner 457b9c1b51eSKate Stone uint8_t StringExtractorGDBRemote::GetError() { 458b9c1b51eSKate Stone if (GetResponseType() == eError) { 45930fdc8d8SChris Lattner SetFilePos(1); 46030fdc8d8SChris Lattner return GetHexU8(255); 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner return 0; 46330fdc8d8SChris Lattner } 464e0f8f574SDaniel Malea 465dab1d5f3SRavitheja Addepally lldb_private::Status StringExtractorGDBRemote::GetStatus() { 466dab1d5f3SRavitheja Addepally lldb_private::Status error; 467dab1d5f3SRavitheja Addepally if (GetResponseType() == eError) { 468dab1d5f3SRavitheja Addepally SetFilePos(1); 469dab1d5f3SRavitheja Addepally uint8_t errc = GetHexU8(255); 470dab1d5f3SRavitheja Addepally error.SetError(errc, lldb::eErrorTypeGeneric); 471dab1d5f3SRavitheja Addepally 472fa73e340SRavitheja Addepally error.SetErrorStringWithFormat("Error %u", errc); 473fa73e340SRavitheja Addepally std::string error_messg; 474fa73e340SRavitheja Addepally if (GetChar() == ';') { 475dab1d5f3SRavitheja Addepally GetHexByteString(error_messg); 476dab1d5f3SRavitheja Addepally error.SetErrorString(error_messg); 477dab1d5f3SRavitheja Addepally } 478fa73e340SRavitheja Addepally } 479dab1d5f3SRavitheja Addepally return error; 480dab1d5f3SRavitheja Addepally } 481dab1d5f3SRavitheja Addepally 482b9c1b51eSKate Stone size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) { 483b9c1b51eSKate Stone // Just get the data bytes in the string as 48405097246SAdrian Prantl // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped 48505097246SAdrian Prantl // characters. If any 0x7d characters are left in the packet, then they are 48605097246SAdrian Prantl // supposed to be there... 487e0f8f574SDaniel Malea str.clear(); 488109534cbSGreg Clayton const size_t bytes_left = GetBytesLeft(); 489b9c1b51eSKate Stone if (bytes_left > 0) { 490109534cbSGreg Clayton str.assign(m_packet, m_index, bytes_left); 491109534cbSGreg Clayton m_index += bytes_left; 492e0f8f574SDaniel Malea } 493e0f8f574SDaniel Malea return str.size(); 494e0f8f574SDaniel Malea } 495e0f8f574SDaniel Malea 496830c81d5SGreg Clayton static bool 497b9c1b51eSKate Stone OKErrorNotSupportedResponseValidator(void *, 498b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 499b9c1b51eSKate Stone switch (response.GetResponseType()) { 500830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 501830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 502830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 503830c81d5SGreg Clayton return true; 504830c81d5SGreg Clayton 505830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 506830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 507830c81d5SGreg Clayton case StringExtractorGDBRemote::eResponse: 508830c81d5SGreg Clayton break; 509830c81d5SGreg Clayton } 510830c81d5SGreg Clayton return false; 511830c81d5SGreg Clayton } 512830c81d5SGreg Clayton 513b9c1b51eSKate Stone static bool JSONResponseValidator(void *, 514b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 515b9c1b51eSKate Stone switch (response.GetResponseType()) { 516830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 517830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 518830c81d5SGreg Clayton return true; // Accept unsupported or EXX as valid responses 519830c81d5SGreg Clayton 520830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 521830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 522830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 523830c81d5SGreg Clayton break; 524830c81d5SGreg Clayton 525830c81d5SGreg Clayton case StringExtractorGDBRemote::eResponse: 526830c81d5SGreg Clayton // JSON that is returned in from JSON query packets is currently always 52705097246SAdrian Prantl // either a dictionary which starts with a '{', or an array which starts 52805097246SAdrian Prantl // with a '['. This is a quick validator to just make sure the response 52905097246SAdrian Prantl // could be valid JSON without having to validate all of the 530830c81d5SGreg Clayton // JSON content. 531b9c1b51eSKate Stone switch (response.GetStringRef()[0]) { 532b9c1b51eSKate Stone case '{': 533b9c1b51eSKate Stone return true; 534b9c1b51eSKate Stone case '[': 535b9c1b51eSKate Stone return true; 536830c81d5SGreg Clayton default: 537830c81d5SGreg Clayton break; 538830c81d5SGreg Clayton } 539830c81d5SGreg Clayton break; 540830c81d5SGreg Clayton } 541830c81d5SGreg Clayton return false; 542830c81d5SGreg Clayton } 543830c81d5SGreg Clayton 544830c81d5SGreg Clayton static bool 545b9c1b51eSKate Stone ASCIIHexBytesResponseValidator(void *, 546b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 547b9c1b51eSKate Stone switch (response.GetResponseType()) { 548830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 549830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 550830c81d5SGreg Clayton return true; // Accept unsupported or EXX as valid responses 551830c81d5SGreg Clayton 552830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 553830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 554830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 555830c81d5SGreg Clayton break; 556830c81d5SGreg Clayton 557b9c1b51eSKate Stone case StringExtractorGDBRemote::eResponse: { 558830c81d5SGreg Clayton uint32_t valid_count = 0; 559b9c1b51eSKate Stone for (const char ch : response.GetStringRef()) { 560b9c1b51eSKate Stone if (!isxdigit(ch)) { 561830c81d5SGreg Clayton return false; 562830c81d5SGreg Clayton } 563830c81d5SGreg Clayton if (++valid_count >= 16) 564b9c1b51eSKate Stone break; // Don't validate all the characters in case the packet is very 565b9c1b51eSKate Stone // large 566830c81d5SGreg Clayton } 567830c81d5SGreg Clayton return true; 568b9c1b51eSKate Stone } break; 569830c81d5SGreg Clayton } 570830c81d5SGreg Clayton return false; 571830c81d5SGreg Clayton } 572830c81d5SGreg Clayton 573b9c1b51eSKate Stone void StringExtractorGDBRemote::CopyResponseValidator( 574b9c1b51eSKate Stone const StringExtractorGDBRemote &rhs) { 575830c81d5SGreg Clayton m_validator = rhs.m_validator; 576830c81d5SGreg Clayton m_validator_baton = rhs.m_validator_baton; 577830c81d5SGreg Clayton } 578830c81d5SGreg Clayton 579b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidator( 580b9c1b51eSKate Stone ResponseValidatorCallback callback, void *baton) { 581830c81d5SGreg Clayton m_validator = callback; 582830c81d5SGreg Clayton m_validator_baton = baton; 583830c81d5SGreg Clayton } 584830c81d5SGreg Clayton 585b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() { 586830c81d5SGreg Clayton m_validator = OKErrorNotSupportedResponseValidator; 587830c81d5SGreg Clayton m_validator_baton = nullptr; 588830c81d5SGreg Clayton } 589830c81d5SGreg Clayton 590b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() { 591830c81d5SGreg Clayton m_validator = ASCIIHexBytesResponseValidator; 592830c81d5SGreg Clayton m_validator_baton = nullptr; 593830c81d5SGreg Clayton } 594830c81d5SGreg Clayton 595b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToJSON() { 596830c81d5SGreg Clayton m_validator = JSONResponseValidator; 597830c81d5SGreg Clayton m_validator_baton = nullptr; 598830c81d5SGreg Clayton } 599830c81d5SGreg Clayton 600b9c1b51eSKate Stone bool StringExtractorGDBRemote::ValidateResponse() const { 601830c81d5SGreg Clayton // If we have a validator callback, try to validate the callback 602830c81d5SGreg Clayton if (m_validator) 603830c81d5SGreg Clayton return m_validator(m_validator_baton, *this); 604830c81d5SGreg Clayton else 605830c81d5SGreg Clayton return true; // No validator, so response is valid 606830c81d5SGreg Clayton } 607