130fdc8d8SChris Lattner //===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner // C Includes 11ad65c051SStephen Wilson #include <string.h> 12ad65c051SStephen Wilson 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 16ad65c051SStephen Wilson #include "Utility/StringExtractorGDBRemote.h" 1730fdc8d8SChris Lattner 18576d8834SGreg Clayton StringExtractorGDBRemote::ResponseType 19*b9c1b51eSKate Stone StringExtractorGDBRemote::GetResponseType() const { 2030fdc8d8SChris Lattner if (m_packet.empty()) 2130fdc8d8SChris Lattner return eUnsupported; 2230fdc8d8SChris Lattner 23*b9c1b51eSKate Stone switch (m_packet[0]) { 2430fdc8d8SChris Lattner case 'E': 25*b9c1b51eSKate Stone if (m_packet.size() == 3 && isxdigit(m_packet[1]) && isxdigit(m_packet[2])) 2630fdc8d8SChris Lattner return eError; 2730fdc8d8SChris Lattner break; 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner case 'O': 3030fdc8d8SChris Lattner if (m_packet.size() == 2 && m_packet[1] == 'K') 3130fdc8d8SChris Lattner return eOK; 3230fdc8d8SChris Lattner break; 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner case '+': 3530fdc8d8SChris Lattner if (m_packet.size() == 1) 3630fdc8d8SChris Lattner return eAck; 3730fdc8d8SChris Lattner break; 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner case '-': 4030fdc8d8SChris Lattner if (m_packet.size() == 1) 4130fdc8d8SChris Lattner return eNack; 4230fdc8d8SChris Lattner break; 4330fdc8d8SChris Lattner } 4430fdc8d8SChris Lattner return eResponse; 4530fdc8d8SChris Lattner } 4630fdc8d8SChris Lattner 47576d8834SGreg Clayton StringExtractorGDBRemote::ServerPacketType 48*b9c1b51eSKate Stone StringExtractorGDBRemote::GetServerPacketType() const { 49*b9c1b51eSKate Stone #define PACKET_MATCHES(s) \ 50*b9c1b51eSKate Stone ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0)) 51*b9c1b51eSKate Stone #define PACKET_STARTS_WITH(s) \ 52*b9c1b51eSKate Stone ((packet_size >= (sizeof(s) - 1)) && \ 53*b9c1b51eSKate Stone ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0) 548b82f087SGreg Clayton 55576d8834SGreg Clayton // Empty is not a supported packet... 56576d8834SGreg Clayton if (m_packet.empty()) 57576d8834SGreg Clayton return eServerPacketType_invalid; 58576d8834SGreg Clayton 598b82f087SGreg Clayton const size_t packet_size = m_packet.size(); 60576d8834SGreg Clayton const char *packet_cstr = m_packet.c_str(); 61*b9c1b51eSKate Stone switch (m_packet[0]) { 6278baa197SEwan Crawford 6378baa197SEwan Crawford case '%': 6478baa197SEwan Crawford return eServerPacketType_notify; 6578baa197SEwan Crawford 66d314e810SGreg Clayton case '\x03': 67*b9c1b51eSKate Stone if (packet_size == 1) 68*b9c1b51eSKate Stone return eServerPacketType_interrupt; 69d314e810SGreg Clayton break; 70d314e810SGreg Clayton 71576d8834SGreg Clayton case '-': 72*b9c1b51eSKate Stone if (packet_size == 1) 73*b9c1b51eSKate Stone return eServerPacketType_nack; 74576d8834SGreg Clayton break; 75576d8834SGreg Clayton 76576d8834SGreg Clayton case '+': 77*b9c1b51eSKate Stone if (packet_size == 1) 78*b9c1b51eSKate Stone return eServerPacketType_ack; 79576d8834SGreg Clayton break; 80576d8834SGreg Clayton 818b82f087SGreg Clayton case 'A': 828b82f087SGreg Clayton return eServerPacketType_A; 838b82f087SGreg Clayton 841cb6496eSGreg Clayton case 'Q': 850fefa676SJean-Daniel Dupas 86*b9c1b51eSKate Stone switch (packet_cstr[1]) { 878b82f087SGreg Clayton case 'E': 88*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QEnvironment:")) 89*b9c1b51eSKate Stone return eServerPacketType_QEnvironment; 90*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:")) 91*b9c1b51eSKate Stone return eServerPacketType_QEnvironmentHexEncoded; 928b82f087SGreg Clayton break; 938b82f087SGreg Clayton 948b82f087SGreg Clayton case 'S': 95*b9c1b51eSKate Stone if (PACKET_MATCHES("QStartNoAckMode")) 96*b9c1b51eSKate Stone return eServerPacketType_QStartNoAckMode; 97*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSaveRegisterState")) 98*b9c1b51eSKate Stone return eServerPacketType_QSaveRegisterState; 99*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetDisableASLR:")) 100*b9c1b51eSKate Stone return eServerPacketType_QSetDisableASLR; 101*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetDetachOnError:")) 102*b9c1b51eSKate Stone return eServerPacketType_QSetDetachOnError; 103*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDIN:")) 104*b9c1b51eSKate Stone return eServerPacketType_QSetSTDIN; 105*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDOUT:")) 106*b9c1b51eSKate Stone return eServerPacketType_QSetSTDOUT; 107*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetSTDERR:")) 108*b9c1b51eSKate Stone return eServerPacketType_QSetSTDERR; 109*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetWorkingDir:")) 110*b9c1b51eSKate Stone return eServerPacketType_QSetWorkingDir; 111*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetLogging:")) 112*b9c1b51eSKate Stone return eServerPacketType_QSetLogging; 113*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetMaxPacketSize:")) 114*b9c1b51eSKate Stone return eServerPacketType_QSetMaxPacketSize; 115*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetMaxPayloadSize:")) 116*b9c1b51eSKate Stone return eServerPacketType_QSetMaxPayloadSize; 117*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;")) 118*b9c1b51eSKate Stone return eServerPacketType_QSetEnableAsyncProfiling; 119*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QSyncThreadState:")) 120*b9c1b51eSKate Stone return eServerPacketType_QSyncThreadState; 1218b82f087SGreg Clayton break; 1220fefa676SJean-Daniel Dupas 123e0f8f574SDaniel Malea case 'L': 124*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QLaunchArch:")) 125*b9c1b51eSKate Stone return eServerPacketType_QLaunchArch; 126*b9c1b51eSKate Stone if (PACKET_MATCHES("QListThreadsInStopReply")) 127*b9c1b51eSKate Stone return eServerPacketType_QListThreadsInStopReply; 1280fefa676SJean-Daniel Dupas break; 1290fefa676SJean-Daniel Dupas 1300fefa676SJean-Daniel Dupas case 'R': 131*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("QRestoreRegisterState:")) 132*b9c1b51eSKate Stone return eServerPacketType_QRestoreRegisterState; 1330fefa676SJean-Daniel Dupas break; 1340fefa676SJean-Daniel Dupas 1350fefa676SJean-Daniel Dupas case 'T': 136*b9c1b51eSKate Stone if (PACKET_MATCHES("QThreadSuffixSupported")) 137*b9c1b51eSKate Stone return eServerPacketType_QThreadSuffixSupported; 138e0f8f574SDaniel Malea break; 1398b82f087SGreg Clayton } 1401cb6496eSGreg Clayton break; 1411cb6496eSGreg Clayton 142576d8834SGreg Clayton case 'q': 143*b9c1b51eSKate Stone switch (packet_cstr[1]) { 1448b82f087SGreg Clayton case 's': 145*b9c1b51eSKate Stone if (PACKET_MATCHES("qsProcessInfo")) 146*b9c1b51eSKate Stone return eServerPacketType_qsProcessInfo; 147*b9c1b51eSKate Stone if (PACKET_MATCHES("qsThreadInfo")) 148*b9c1b51eSKate Stone return eServerPacketType_qsThreadInfo; 1498b82f087SGreg Clayton break; 1508b82f087SGreg Clayton 1518b82f087SGreg Clayton case 'f': 152*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qfProcessInfo")) 153*b9c1b51eSKate Stone return eServerPacketType_qfProcessInfo; 154*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qfThreadInfo")) 155*b9c1b51eSKate Stone return eServerPacketType_qfThreadInfo; 1568b82f087SGreg Clayton break; 1578b82f087SGreg Clayton 1588b82f087SGreg Clayton case 'C': 159*b9c1b51eSKate Stone if (packet_size == 2) 160*b9c1b51eSKate Stone return eServerPacketType_qC; 1618b82f087SGreg Clayton break; 1628b82f087SGreg Clayton 163420562aaSGreg Clayton case 'E': 164*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qEcho:")) 165*b9c1b51eSKate Stone return eServerPacketType_qEcho; 166420562aaSGreg Clayton break; 167420562aaSGreg Clayton 168783bfc8cSTamas Berghammer case 'F': 169*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qFileLoadAddress:")) 170*b9c1b51eSKate Stone return eServerPacketType_qFileLoadAddress; 171783bfc8cSTamas Berghammer break; 172783bfc8cSTamas Berghammer 1738b82f087SGreg Clayton case 'G': 174*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qGroupName:")) 175*b9c1b51eSKate Stone return eServerPacketType_qGroupName; 176*b9c1b51eSKate Stone if (PACKET_MATCHES("qGetWorkingDir")) 177*b9c1b51eSKate Stone return eServerPacketType_qGetWorkingDir; 178*b9c1b51eSKate Stone if (PACKET_MATCHES("qGetPid")) 179*b9c1b51eSKate Stone return eServerPacketType_qGetPid; 180*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qGetProfileData;")) 181*b9c1b51eSKate Stone return eServerPacketType_qGetProfileData; 182*b9c1b51eSKate Stone if (PACKET_MATCHES("qGDBServerVersion")) 183*b9c1b51eSKate Stone return eServerPacketType_qGDBServerVersion; 1848b82f087SGreg Clayton break; 1858b82f087SGreg Clayton 1868b82f087SGreg Clayton case 'H': 187*b9c1b51eSKate Stone if (PACKET_MATCHES("qHostInfo")) 188*b9c1b51eSKate Stone return eServerPacketType_qHostInfo; 1898b82f087SGreg Clayton break; 1908b82f087SGreg Clayton 191e0f8f574SDaniel Malea case 'K': 192*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qKillSpawnedProcess")) 193*b9c1b51eSKate Stone return eServerPacketType_qKillSpawnedProcess; 194e0f8f574SDaniel Malea break; 195e0f8f574SDaniel Malea 1968b82f087SGreg Clayton case 'L': 197*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qLaunchGDBServer")) 198*b9c1b51eSKate Stone return eServerPacketType_qLaunchGDBServer; 199*b9c1b51eSKate Stone if (PACKET_MATCHES("qLaunchSuccess")) 200*b9c1b51eSKate Stone return eServerPacketType_qLaunchSuccess; 2018b82f087SGreg Clayton break; 2028b82f087SGreg Clayton 2030fefa676SJean-Daniel Dupas case 'M': 204*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qMemoryRegionInfo:")) 205*b9c1b51eSKate Stone return eServerPacketType_qMemoryRegionInfo; 206*b9c1b51eSKate Stone if (PACKET_MATCHES("qMemoryRegionInfo")) 207*b9c1b51eSKate Stone return eServerPacketType_qMemoryRegionInfoSupported; 208*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qModuleInfo:")) 209*b9c1b51eSKate Stone return eServerPacketType_qModuleInfo; 2100fefa676SJean-Daniel Dupas break; 2110fefa676SJean-Daniel Dupas 2128b82f087SGreg Clayton case 'P': 213*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qProcessInfoPID:")) 214*b9c1b51eSKate Stone return eServerPacketType_qProcessInfoPID; 215*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_shell:")) 216*b9c1b51eSKate Stone return eServerPacketType_qPlatform_shell; 217*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_mkdir:")) 218*b9c1b51eSKate Stone return eServerPacketType_qPlatform_mkdir; 219*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qPlatform_chmod:")) 220*b9c1b51eSKate Stone return eServerPacketType_qPlatform_chmod; 221*b9c1b51eSKate Stone if (PACKET_MATCHES("qProcessInfo")) 222*b9c1b51eSKate Stone return eServerPacketType_qProcessInfo; 2238b82f087SGreg Clayton break; 2248b82f087SGreg Clayton 225ccd6cffbSTamas Berghammer case 'Q': 226*b9c1b51eSKate Stone if (PACKET_MATCHES("qQueryGDBServer")) 227*b9c1b51eSKate Stone return eServerPacketType_qQueryGDBServer; 228ccd6cffbSTamas Berghammer break; 229ccd6cffbSTamas Berghammer 2300fefa676SJean-Daniel Dupas case 'R': 231*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qRcmd,")) 232*b9c1b51eSKate Stone return eServerPacketType_qRcmd; 233*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qRegisterInfo")) 234*b9c1b51eSKate Stone return eServerPacketType_qRegisterInfo; 2350fefa676SJean-Daniel Dupas break; 236e0f8f574SDaniel Malea 2378b82f087SGreg Clayton case 'S': 238*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qSpeedTest:")) 239*b9c1b51eSKate Stone return eServerPacketType_qSpeedTest; 240*b9c1b51eSKate Stone if (PACKET_MATCHES("qShlibInfoAddr")) 241*b9c1b51eSKate Stone return eServerPacketType_qShlibInfoAddr; 242*b9c1b51eSKate Stone if (PACKET_MATCHES("qStepPacketSupported")) 243*b9c1b51eSKate Stone return eServerPacketType_qStepPacketSupported; 244*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qSupported")) 245*b9c1b51eSKate Stone return eServerPacketType_qSupported; 246*b9c1b51eSKate Stone if (PACKET_MATCHES("qSyncThreadStateSupported")) 247*b9c1b51eSKate Stone return eServerPacketType_qSyncThreadStateSupported; 2480fefa676SJean-Daniel Dupas break; 2490fefa676SJean-Daniel Dupas 2500fefa676SJean-Daniel Dupas case 'T': 251*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qThreadExtraInfo,")) 252*b9c1b51eSKate Stone return eServerPacketType_qThreadExtraInfo; 253*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qThreadStopInfo")) 254*b9c1b51eSKate Stone return eServerPacketType_qThreadStopInfo; 2558b82f087SGreg Clayton break; 2568b82f087SGreg Clayton 2578b82f087SGreg Clayton case 'U': 258*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qUserName:")) 259*b9c1b51eSKate Stone return eServerPacketType_qUserName; 2608b82f087SGreg Clayton break; 2610fefa676SJean-Daniel Dupas 2620fefa676SJean-Daniel Dupas case 'V': 263*b9c1b51eSKate Stone if (PACKET_MATCHES("qVAttachOrWaitSupported")) 264*b9c1b51eSKate Stone return eServerPacketType_qVAttachOrWaitSupported; 2650fefa676SJean-Daniel Dupas break; 2660fefa676SJean-Daniel Dupas 2670fefa676SJean-Daniel Dupas case 'W': 268*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qWatchpointSupportInfo:")) 269*b9c1b51eSKate Stone return eServerPacketType_qWatchpointSupportInfo; 270*b9c1b51eSKate Stone if (PACKET_MATCHES("qWatchpointSupportInfo")) 271*b9c1b51eSKate Stone return eServerPacketType_qWatchpointSupportInfoSupported; 2720fefa676SJean-Daniel Dupas break; 273af245d11STodd Fiala 274af245d11STodd Fiala case 'X': 275*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("qXfer:auxv:read::")) 276*b9c1b51eSKate Stone return eServerPacketType_qXfer_auxv_read; 277af245d11STodd Fiala break; 2788b82f087SGreg Clayton } 279576d8834SGreg Clayton break; 28098d0a4b3SChaoren Lin 28198d0a4b3SChaoren Lin case 'j': 282*b9c1b51eSKate Stone if (PACKET_MATCHES("jSignalsInfo")) 283*b9c1b51eSKate Stone return eServerPacketType_jSignalsInfo; 284*b9c1b51eSKate Stone if (PACKET_MATCHES("jThreadsInfo")) 285*b9c1b51eSKate Stone return eServerPacketType_jThreadsInfo; 286cec91ef9SGreg Clayton break; 28798d0a4b3SChaoren Lin 288e0f8f574SDaniel Malea case 'v': 289*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vFile:")) { 290*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vFile:open:")) 291*b9c1b51eSKate Stone return eServerPacketType_vFile_open; 292*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:close:")) 293*b9c1b51eSKate Stone return eServerPacketType_vFile_close; 294*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:pread")) 295*b9c1b51eSKate Stone return eServerPacketType_vFile_pread; 296*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:pwrite")) 297*b9c1b51eSKate Stone return eServerPacketType_vFile_pwrite; 298*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:size")) 299*b9c1b51eSKate Stone return eServerPacketType_vFile_size; 300*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:exists")) 301*b9c1b51eSKate Stone return eServerPacketType_vFile_exists; 302*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:stat")) 303*b9c1b51eSKate Stone return eServerPacketType_vFile_stat; 304*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:mode")) 305*b9c1b51eSKate Stone return eServerPacketType_vFile_mode; 306*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:MD5")) 307*b9c1b51eSKate Stone return eServerPacketType_vFile_md5; 308*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:symlink")) 309*b9c1b51eSKate Stone return eServerPacketType_vFile_symlink; 310*b9c1b51eSKate Stone else if (PACKET_STARTS_WITH("vFile:unlink")) 311*b9c1b51eSKate Stone return eServerPacketType_vFile_unlink; 312e0f8f574SDaniel Malea 3130fefa676SJean-Daniel Dupas } else { 314*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttach;")) 315*b9c1b51eSKate Stone return eServerPacketType_vAttach; 316*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachWait;")) 317*b9c1b51eSKate Stone return eServerPacketType_vAttachWait; 318*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachOrWait;")) 319*b9c1b51eSKate Stone return eServerPacketType_vAttachOrWait; 320*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vAttachName;")) 321*b9c1b51eSKate Stone return eServerPacketType_vAttachName; 322*b9c1b51eSKate Stone if (PACKET_STARTS_WITH("vCont;")) 323*b9c1b51eSKate Stone return eServerPacketType_vCont; 324*b9c1b51eSKate Stone if (PACKET_MATCHES("vCont?")) 325*b9c1b51eSKate Stone return eServerPacketType_vCont_actions; 326e0f8f574SDaniel Malea } 327e0f8f574SDaniel Malea break; 3280fefa676SJean-Daniel Dupas case '_': 329*b9c1b51eSKate Stone switch (packet_cstr[1]) { 3300fefa676SJean-Daniel Dupas case 'M': 3310fefa676SJean-Daniel Dupas return eServerPacketType__M; 3320fefa676SJean-Daniel Dupas 3330fefa676SJean-Daniel Dupas case 'm': 3340fefa676SJean-Daniel Dupas return eServerPacketType__m; 3350fefa676SJean-Daniel Dupas } 3360fefa676SJean-Daniel Dupas break; 3370fefa676SJean-Daniel Dupas 3380fefa676SJean-Daniel Dupas case '?': 339*b9c1b51eSKate Stone if (packet_size == 1) 340*b9c1b51eSKate Stone return eServerPacketType_stop_reason; 3410fefa676SJean-Daniel Dupas break; 3420fefa676SJean-Daniel Dupas 3430fefa676SJean-Daniel Dupas case 'c': 3440fefa676SJean-Daniel Dupas return eServerPacketType_c; 3450fefa676SJean-Daniel Dupas 3460fefa676SJean-Daniel Dupas case 'C': 3470fefa676SJean-Daniel Dupas return eServerPacketType_C; 3480fefa676SJean-Daniel Dupas 3490fefa676SJean-Daniel Dupas case 'D': 350*b9c1b51eSKate Stone if (packet_size == 1) 351*b9c1b51eSKate Stone return eServerPacketType_D; 3520fefa676SJean-Daniel Dupas break; 3530fefa676SJean-Daniel Dupas 3540fefa676SJean-Daniel Dupas case 'g': 355*b9c1b51eSKate Stone if (packet_size == 1) 356*b9c1b51eSKate Stone return eServerPacketType_g; 3570fefa676SJean-Daniel Dupas break; 3580fefa676SJean-Daniel Dupas 3590fefa676SJean-Daniel Dupas case 'G': 3600fefa676SJean-Daniel Dupas return eServerPacketType_G; 3610fefa676SJean-Daniel Dupas 3620fefa676SJean-Daniel Dupas case 'H': 3630fefa676SJean-Daniel Dupas return eServerPacketType_H; 3640fefa676SJean-Daniel Dupas 365e0be425aSVince Harron case 'I': 366e0be425aSVince Harron return eServerPacketType_I; 367e0be425aSVince Harron 3680fefa676SJean-Daniel Dupas case 'k': 369*b9c1b51eSKate Stone if (packet_size == 1) 370*b9c1b51eSKate Stone return eServerPacketType_k; 3710fefa676SJean-Daniel Dupas break; 3720fefa676SJean-Daniel Dupas 3730fefa676SJean-Daniel Dupas case 'm': 3740fefa676SJean-Daniel Dupas return eServerPacketType_m; 3750fefa676SJean-Daniel Dupas 3760fefa676SJean-Daniel Dupas case 'M': 3770fefa676SJean-Daniel Dupas return eServerPacketType_M; 3780fefa676SJean-Daniel Dupas 3790fefa676SJean-Daniel Dupas case 'p': 3800fefa676SJean-Daniel Dupas return eServerPacketType_p; 3810fefa676SJean-Daniel Dupas 3820fefa676SJean-Daniel Dupas case 'P': 3830fefa676SJean-Daniel Dupas return eServerPacketType_P; 3840fefa676SJean-Daniel Dupas 3850fefa676SJean-Daniel Dupas case 's': 386*b9c1b51eSKate Stone if (packet_size == 1) 387*b9c1b51eSKate Stone return eServerPacketType_s; 3880fefa676SJean-Daniel Dupas break; 3890fefa676SJean-Daniel Dupas 3900fefa676SJean-Daniel Dupas case 'S': 3910fefa676SJean-Daniel Dupas return eServerPacketType_S; 3920fefa676SJean-Daniel Dupas 3933bf11256SPavel Labath case 'x': 3943bf11256SPavel Labath return eServerPacketType_x; 3953bf11256SPavel Labath 3963bf11256SPavel Labath case 'X': 3973bf11256SPavel Labath return eServerPacketType_X; 3983bf11256SPavel Labath 3990fefa676SJean-Daniel Dupas case 'T': 4000fefa676SJean-Daniel Dupas return eServerPacketType_T; 4010fefa676SJean-Daniel Dupas 4020fefa676SJean-Daniel Dupas case 'z': 4030fefa676SJean-Daniel Dupas if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 4040fefa676SJean-Daniel Dupas return eServerPacketType_z; 4050fefa676SJean-Daniel Dupas break; 4060fefa676SJean-Daniel Dupas 4070fefa676SJean-Daniel Dupas case 'Z': 4080fefa676SJean-Daniel Dupas if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 4090fefa676SJean-Daniel Dupas return eServerPacketType_Z; 4100fefa676SJean-Daniel Dupas break; 411576d8834SGreg Clayton } 412576d8834SGreg Clayton return eServerPacketType_unimplemented; 413576d8834SGreg Clayton } 414576d8834SGreg Clayton 415*b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsOKResponse() const { 416576d8834SGreg Clayton return GetResponseType() == eOK; 41730fdc8d8SChris Lattner } 41830fdc8d8SChris Lattner 419*b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsUnsupportedResponse() const { 420576d8834SGreg Clayton return GetResponseType() == eUnsupported; 42130fdc8d8SChris Lattner } 42230fdc8d8SChris Lattner 423*b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsNormalResponse() const { 424576d8834SGreg Clayton return GetResponseType() == eResponse; 42530fdc8d8SChris Lattner } 42630fdc8d8SChris Lattner 427*b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsErrorResponse() const { 428*b9c1b51eSKate Stone return GetResponseType() == eError && m_packet.size() == 3 && 429*b9c1b51eSKate Stone isxdigit(m_packet[1]) && isxdigit(m_packet[2]); 43030fdc8d8SChris Lattner } 43130fdc8d8SChris Lattner 432*b9c1b51eSKate Stone uint8_t StringExtractorGDBRemote::GetError() { 433*b9c1b51eSKate Stone if (GetResponseType() == eError) { 43430fdc8d8SChris Lattner SetFilePos(1); 43530fdc8d8SChris Lattner return GetHexU8(255); 43630fdc8d8SChris Lattner } 43730fdc8d8SChris Lattner return 0; 43830fdc8d8SChris Lattner } 439e0f8f574SDaniel Malea 440*b9c1b51eSKate Stone size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) { 441*b9c1b51eSKate Stone // Just get the data bytes in the string as 442*b9c1b51eSKate Stone // GDBRemoteCommunication::CheckForPacket() 443*b9c1b51eSKate Stone // already removes any 0x7d escaped characters. If any 0x7d characters are 444*b9c1b51eSKate Stone // left in 445109534cbSGreg Clayton // the packet, then they are supposed to be there... 446e0f8f574SDaniel Malea str.clear(); 447109534cbSGreg Clayton const size_t bytes_left = GetBytesLeft(); 448*b9c1b51eSKate Stone if (bytes_left > 0) { 449109534cbSGreg Clayton str.assign(m_packet, m_index, bytes_left); 450109534cbSGreg Clayton m_index += bytes_left; 451e0f8f574SDaniel Malea } 452e0f8f574SDaniel Malea return str.size(); 453e0f8f574SDaniel Malea } 454e0f8f574SDaniel Malea 455830c81d5SGreg Clayton static bool 456*b9c1b51eSKate Stone OKErrorNotSupportedResponseValidator(void *, 457*b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 458*b9c1b51eSKate Stone switch (response.GetResponseType()) { 459830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 460830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 461830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 462830c81d5SGreg Clayton return true; 463830c81d5SGreg Clayton 464830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 465830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 466830c81d5SGreg Clayton case StringExtractorGDBRemote::eResponse: 467830c81d5SGreg Clayton break; 468830c81d5SGreg Clayton } 469830c81d5SGreg Clayton return false; 470830c81d5SGreg Clayton } 471830c81d5SGreg Clayton 472*b9c1b51eSKate Stone static bool JSONResponseValidator(void *, 473*b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 474*b9c1b51eSKate Stone switch (response.GetResponseType()) { 475830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 476830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 477830c81d5SGreg Clayton return true; // Accept unsupported or EXX as valid responses 478830c81d5SGreg Clayton 479830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 480830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 481830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 482830c81d5SGreg Clayton break; 483830c81d5SGreg Clayton 484830c81d5SGreg Clayton case StringExtractorGDBRemote::eResponse: 485830c81d5SGreg Clayton // JSON that is returned in from JSON query packets is currently always 486830c81d5SGreg Clayton // either a dictionary which starts with a '{', or an array which 487830c81d5SGreg Clayton // starts with a '['. This is a quick validator to just make sure the 488830c81d5SGreg Clayton // response could be valid JSON without having to validate all of the 489830c81d5SGreg Clayton // JSON content. 490*b9c1b51eSKate Stone switch (response.GetStringRef()[0]) { 491*b9c1b51eSKate Stone case '{': 492*b9c1b51eSKate Stone return true; 493*b9c1b51eSKate Stone case '[': 494*b9c1b51eSKate Stone return true; 495830c81d5SGreg Clayton default: 496830c81d5SGreg Clayton break; 497830c81d5SGreg Clayton } 498830c81d5SGreg Clayton break; 499830c81d5SGreg Clayton } 500830c81d5SGreg Clayton return false; 501830c81d5SGreg Clayton } 502830c81d5SGreg Clayton 503830c81d5SGreg Clayton static bool 504*b9c1b51eSKate Stone ASCIIHexBytesResponseValidator(void *, 505*b9c1b51eSKate Stone const StringExtractorGDBRemote &response) { 506*b9c1b51eSKate Stone switch (response.GetResponseType()) { 507830c81d5SGreg Clayton case StringExtractorGDBRemote::eUnsupported: 508830c81d5SGreg Clayton case StringExtractorGDBRemote::eError: 509830c81d5SGreg Clayton return true; // Accept unsupported or EXX as valid responses 510830c81d5SGreg Clayton 511830c81d5SGreg Clayton case StringExtractorGDBRemote::eOK: 512830c81d5SGreg Clayton case StringExtractorGDBRemote::eAck: 513830c81d5SGreg Clayton case StringExtractorGDBRemote::eNack: 514830c81d5SGreg Clayton break; 515830c81d5SGreg Clayton 516*b9c1b51eSKate Stone case StringExtractorGDBRemote::eResponse: { 517830c81d5SGreg Clayton uint32_t valid_count = 0; 518*b9c1b51eSKate Stone for (const char ch : response.GetStringRef()) { 519*b9c1b51eSKate Stone if (!isxdigit(ch)) { 520830c81d5SGreg Clayton return false; 521830c81d5SGreg Clayton } 522830c81d5SGreg Clayton if (++valid_count >= 16) 523*b9c1b51eSKate Stone break; // Don't validate all the characters in case the packet is very 524*b9c1b51eSKate Stone // large 525830c81d5SGreg Clayton } 526830c81d5SGreg Clayton return true; 527*b9c1b51eSKate Stone } break; 528830c81d5SGreg Clayton } 529830c81d5SGreg Clayton return false; 530830c81d5SGreg Clayton } 531830c81d5SGreg Clayton 532*b9c1b51eSKate Stone void StringExtractorGDBRemote::CopyResponseValidator( 533*b9c1b51eSKate Stone const StringExtractorGDBRemote &rhs) { 534830c81d5SGreg Clayton m_validator = rhs.m_validator; 535830c81d5SGreg Clayton m_validator_baton = rhs.m_validator_baton; 536830c81d5SGreg Clayton } 537830c81d5SGreg Clayton 538*b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidator( 539*b9c1b51eSKate Stone ResponseValidatorCallback callback, void *baton) { 540830c81d5SGreg Clayton m_validator = callback; 541830c81d5SGreg Clayton m_validator_baton = baton; 542830c81d5SGreg Clayton } 543830c81d5SGreg Clayton 544*b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() { 545830c81d5SGreg Clayton m_validator = OKErrorNotSupportedResponseValidator; 546830c81d5SGreg Clayton m_validator_baton = nullptr; 547830c81d5SGreg Clayton } 548830c81d5SGreg Clayton 549*b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() { 550830c81d5SGreg Clayton m_validator = ASCIIHexBytesResponseValidator; 551830c81d5SGreg Clayton m_validator_baton = nullptr; 552830c81d5SGreg Clayton } 553830c81d5SGreg Clayton 554*b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToJSON() { 555830c81d5SGreg Clayton m_validator = JSONResponseValidator; 556830c81d5SGreg Clayton m_validator_baton = nullptr; 557830c81d5SGreg Clayton } 558830c81d5SGreg Clayton 559*b9c1b51eSKate Stone bool StringExtractorGDBRemote::ValidateResponse() const { 560830c81d5SGreg Clayton // If we have a validator callback, try to validate the callback 561830c81d5SGreg Clayton if (m_validator) 562830c81d5SGreg Clayton return m_validator(m_validator_baton, *this); 563830c81d5SGreg Clayton else 564830c81d5SGreg Clayton return true; // No validator, so response is valid 565830c81d5SGreg Clayton } 566