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"
17*830c81d5SGreg Clayton #include "lldb/Utility/LLDBAssert.h"
1830fdc8d8SChris Lattner 
19576d8834SGreg Clayton StringExtractorGDBRemote::ResponseType
20576d8834SGreg Clayton StringExtractorGDBRemote::GetResponseType () const
2130fdc8d8SChris Lattner {
2230fdc8d8SChris Lattner     if (m_packet.empty())
2330fdc8d8SChris Lattner         return eUnsupported;
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner     switch (m_packet[0])
2630fdc8d8SChris Lattner     {
2730fdc8d8SChris Lattner     case 'E':
2830fdc8d8SChris Lattner         if (m_packet.size() == 3 &&
2930fdc8d8SChris Lattner             isxdigit(m_packet[1]) &&
3030fdc8d8SChris Lattner             isxdigit(m_packet[2]))
3130fdc8d8SChris Lattner             return eError;
3230fdc8d8SChris Lattner         break;
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner     case 'O':
3530fdc8d8SChris Lattner         if (m_packet.size() == 2 && m_packet[1] == 'K')
3630fdc8d8SChris Lattner             return eOK;
3730fdc8d8SChris Lattner         break;
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner     case '+':
4030fdc8d8SChris Lattner         if (m_packet.size() == 1)
4130fdc8d8SChris Lattner             return eAck;
4230fdc8d8SChris Lattner         break;
4330fdc8d8SChris Lattner 
4430fdc8d8SChris Lattner     case '-':
4530fdc8d8SChris Lattner         if (m_packet.size() == 1)
4630fdc8d8SChris Lattner             return eNack;
4730fdc8d8SChris Lattner         break;
4830fdc8d8SChris Lattner     }
4930fdc8d8SChris Lattner     return eResponse;
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner 
52576d8834SGreg Clayton StringExtractorGDBRemote::ServerPacketType
53576d8834SGreg Clayton StringExtractorGDBRemote::GetServerPacketType () const
5430fdc8d8SChris Lattner {
558b82f087SGreg Clayton #define PACKET_MATCHES(s) ((packet_size == (sizeof(s)-1)) && (strcmp((packet_cstr),(s)) == 0))
568b82f087SGreg Clayton #define PACKET_STARTS_WITH(s) ((packet_size >= (sizeof(s)-1)) && ::strncmp(packet_cstr, s, (sizeof(s)-1))==0)
578b82f087SGreg Clayton 
58576d8834SGreg Clayton     // Empty is not a supported packet...
59576d8834SGreg Clayton     if (m_packet.empty())
60576d8834SGreg Clayton         return eServerPacketType_invalid;
61576d8834SGreg Clayton 
628b82f087SGreg Clayton     const size_t packet_size = m_packet.size();
63576d8834SGreg Clayton     const char *packet_cstr = m_packet.c_str();
64576d8834SGreg Clayton     switch (m_packet[0])
65576d8834SGreg Clayton     {
6678baa197SEwan Crawford 
6778baa197SEwan Crawford     case '%':
6878baa197SEwan Crawford         return eServerPacketType_notify;
6978baa197SEwan Crawford 
70d314e810SGreg Clayton     case '\x03':
718b82f087SGreg Clayton         if (packet_size == 1) return eServerPacketType_interrupt;
72d314e810SGreg Clayton         break;
73d314e810SGreg Clayton 
74576d8834SGreg Clayton     case '-':
758b82f087SGreg Clayton         if (packet_size == 1) return eServerPacketType_nack;
76576d8834SGreg Clayton         break;
77576d8834SGreg Clayton 
78576d8834SGreg Clayton     case '+':
798b82f087SGreg Clayton         if (packet_size == 1) return eServerPacketType_ack;
80576d8834SGreg Clayton         break;
81576d8834SGreg Clayton 
828b82f087SGreg Clayton     case 'A':
838b82f087SGreg Clayton         return eServerPacketType_A;
848b82f087SGreg Clayton 
851cb6496eSGreg Clayton     case 'Q':
860fefa676SJean-Daniel Dupas 
878b82f087SGreg Clayton         switch (packet_cstr[1])
888b82f087SGreg Clayton         {
898b82f087SGreg Clayton         case 'E':
908b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("QEnvironment:"))           return eServerPacketType_QEnvironment;
910fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QEnvironmentHexEncoded:")) return eServerPacketType_QEnvironmentHexEncoded;
928b82f087SGreg Clayton             break;
938b82f087SGreg Clayton 
948b82f087SGreg Clayton         case 'S':
958b82f087SGreg Clayton             if (PACKET_MATCHES ("QStartNoAckMode"))               return eServerPacketType_QStartNoAckMode;
960fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSaveRegisterState"))        return eServerPacketType_QSaveRegisterState;
970fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetDisableASLR:"))          return eServerPacketType_QSetDisableASLR;
98106d0286SJim Ingham             if (PACKET_STARTS_WITH ("QSetDetachOnError:"))        return eServerPacketType_QSetDetachOnError;
990fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetSTDIN:"))                return eServerPacketType_QSetSTDIN;
1000fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetSTDOUT:"))               return eServerPacketType_QSetSTDOUT;
1010fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetSTDERR:"))               return eServerPacketType_QSetSTDERR;
1020fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetWorkingDir:"))           return eServerPacketType_QSetWorkingDir;
1030fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetLogging:"))              return eServerPacketType_QSetLogging;
1040fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetMaxPacketSize:"))        return eServerPacketType_QSetMaxPacketSize;
1050fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetMaxPayloadSize:"))       return eServerPacketType_QSetMaxPayloadSize;
1060fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSetEnableAsyncProfiling;")) return eServerPacketType_QSetEnableAsyncProfiling;
1070fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QSyncThreadState:"))         return eServerPacketType_QSyncThreadState;
1088b82f087SGreg Clayton             break;
1090fefa676SJean-Daniel Dupas 
110e0f8f574SDaniel Malea         case 'L':
111e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH ("QLaunchArch:"))              return eServerPacketType_QLaunchArch;
1120fefa676SJean-Daniel Dupas             if (PACKET_MATCHES("QListThreadsInStopReply"))        return eServerPacketType_QListThreadsInStopReply;
1130fefa676SJean-Daniel Dupas             break;
1140fefa676SJean-Daniel Dupas 
1150fefa676SJean-Daniel Dupas         case 'R':
1160fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("QRestoreRegisterState:"))    return eServerPacketType_QRestoreRegisterState;
1170fefa676SJean-Daniel Dupas             break;
1180fefa676SJean-Daniel Dupas 
1190fefa676SJean-Daniel Dupas         case 'T':
1200fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("QThreadSuffixSupported"))        return eServerPacketType_QThreadSuffixSupported;
121e0f8f574SDaniel Malea             break;
1228b82f087SGreg Clayton         }
1231cb6496eSGreg Clayton         break;
1241cb6496eSGreg Clayton 
125576d8834SGreg Clayton     case 'q':
1268b82f087SGreg Clayton         switch (packet_cstr[1])
1278b82f087SGreg Clayton         {
1288b82f087SGreg Clayton         case 's':
1298b82f087SGreg Clayton             if (PACKET_MATCHES ("qsProcessInfo"))               return eServerPacketType_qsProcessInfo;
1300fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qsThreadInfo"))                return eServerPacketType_qsThreadInfo;
1318b82f087SGreg Clayton             break;
1328b82f087SGreg Clayton 
1338b82f087SGreg Clayton         case 'f':
1348b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qfProcessInfo"))           return eServerPacketType_qfProcessInfo;
1350fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qfThreadInfo"))            return eServerPacketType_qfThreadInfo;
1368b82f087SGreg Clayton             break;
1378b82f087SGreg Clayton 
1388b82f087SGreg Clayton         case 'C':
1398b82f087SGreg Clayton             if (packet_size == 2)                               return eServerPacketType_qC;
1408b82f087SGreg Clayton             break;
1418b82f087SGreg Clayton 
142420562aaSGreg Clayton         case 'E':
143420562aaSGreg Clayton             if (PACKET_STARTS_WITH ("qEcho:"))                  return eServerPacketType_qEcho;
144420562aaSGreg Clayton             break;
145420562aaSGreg Clayton 
146783bfc8cSTamas Berghammer         case 'F':
147783bfc8cSTamas Berghammer             if (PACKET_STARTS_WITH ("qFileLoadAddress:"))       return eServerPacketType_qFileLoadAddress;
148783bfc8cSTamas Berghammer             break;
149783bfc8cSTamas Berghammer 
1508b82f087SGreg Clayton         case 'G':
1518b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qGroupName:"))             return eServerPacketType_qGroupName;
152fbb76349SGreg Clayton             if (PACKET_MATCHES ("qGetWorkingDir"))              return eServerPacketType_qGetWorkingDir;
1530fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qGetPid"))                     return eServerPacketType_qGetPid;
1540fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qGetProfileData;"))        return eServerPacketType_qGetProfileData;
1550fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qGDBServerVersion"))           return eServerPacketType_qGDBServerVersion;
1568b82f087SGreg Clayton             break;
1578b82f087SGreg Clayton 
1588b82f087SGreg Clayton         case 'H':
1598b82f087SGreg Clayton             if (PACKET_MATCHES ("qHostInfo"))                   return eServerPacketType_qHostInfo;
1608b82f087SGreg Clayton             break;
1618b82f087SGreg Clayton 
162e0f8f574SDaniel Malea         case 'K':
163e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH ("qKillSpawnedProcess"))     return eServerPacketType_qKillSpawnedProcess;
164e0f8f574SDaniel Malea             break;
165e0f8f574SDaniel Malea 
1668b82f087SGreg Clayton         case 'L':
167e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH ("qLaunchGDBServer"))        return eServerPacketType_qLaunchGDBServer;
1688b82f087SGreg Clayton             if (PACKET_MATCHES ("qLaunchSuccess"))              return eServerPacketType_qLaunchSuccess;
1698b82f087SGreg Clayton             break;
1708b82f087SGreg Clayton 
1710fefa676SJean-Daniel Dupas         case 'M':
1720fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qMemoryRegionInfo:"))      return eServerPacketType_qMemoryRegionInfo;
1730fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qMemoryRegionInfo"))           return eServerPacketType_qMemoryRegionInfoSupported;
1746801be33SOleksiy Vyalov             if (PACKET_STARTS_WITH ("qModuleInfo:"))             return eServerPacketType_qModuleInfo;
1750fefa676SJean-Daniel Dupas             break;
1760fefa676SJean-Daniel Dupas 
1778b82f087SGreg Clayton         case 'P':
1788b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
179fbb76349SGreg Clayton             if (PACKET_STARTS_WITH ("qPlatform_shell:"))        return eServerPacketType_qPlatform_shell;
180fbb76349SGreg Clayton             if (PACKET_STARTS_WITH ("qPlatform_mkdir:"))        return eServerPacketType_qPlatform_mkdir;
181fbb76349SGreg Clayton             if (PACKET_STARTS_WITH ("qPlatform_chmod:"))        return eServerPacketType_qPlatform_chmod;
1820fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qProcessInfo"))                return eServerPacketType_qProcessInfo;
1838b82f087SGreg Clayton             break;
1848b82f087SGreg Clayton 
185ccd6cffbSTamas Berghammer         case 'Q':
186ccd6cffbSTamas Berghammer             if (PACKET_MATCHES ("qQueryGDBServer"))             return eServerPacketType_qQueryGDBServer;
187ccd6cffbSTamas Berghammer             break;
188ccd6cffbSTamas Berghammer 
1890fefa676SJean-Daniel Dupas         case 'R':
1900fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qRcmd,"))                  return eServerPacketType_qRcmd;
1910fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qRegisterInfo"))           return eServerPacketType_qRegisterInfo;
1920fefa676SJean-Daniel Dupas             break;
193e0f8f574SDaniel Malea 
1948b82f087SGreg Clayton         case 'S':
1958b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qSpeedTest:"))             return eServerPacketType_qSpeedTest;
1960fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qShlibInfoAddr"))              return eServerPacketType_qShlibInfoAddr;
1970fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qStepPacketSupported"))        return eServerPacketType_qStepPacketSupported;
198af245d11STodd Fiala             if (PACKET_STARTS_WITH ("qSupported"))              return eServerPacketType_qSupported;
1990fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qSyncThreadStateSupported"))   return eServerPacketType_qSyncThreadStateSupported;
2000fefa676SJean-Daniel Dupas             break;
2010fefa676SJean-Daniel Dupas 
2020fefa676SJean-Daniel Dupas         case 'T':
2030fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qThreadExtraInfo,"))       return eServerPacketType_qThreadExtraInfo;
2040fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qThreadStopInfo"))         return eServerPacketType_qThreadStopInfo;
2058b82f087SGreg Clayton             break;
2068b82f087SGreg Clayton 
2078b82f087SGreg Clayton         case 'U':
2088b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qUserName:"))              return eServerPacketType_qUserName;
2098b82f087SGreg Clayton             break;
2100fefa676SJean-Daniel Dupas 
2110fefa676SJean-Daniel Dupas         case 'V':
2120fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qVAttachOrWaitSupported"))     return eServerPacketType_qVAttachOrWaitSupported;
2130fefa676SJean-Daniel Dupas             break;
2140fefa676SJean-Daniel Dupas 
2150fefa676SJean-Daniel Dupas         case 'W':
2160fefa676SJean-Daniel Dupas             if (PACKET_STARTS_WITH ("qWatchpointSupportInfo:")) return eServerPacketType_qWatchpointSupportInfo;
2170fefa676SJean-Daniel Dupas             if (PACKET_MATCHES ("qWatchpointSupportInfo"))      return eServerPacketType_qWatchpointSupportInfoSupported;
2180fefa676SJean-Daniel Dupas             break;
219af245d11STodd Fiala 
220af245d11STodd Fiala         case 'X':
221af245d11STodd Fiala             if (PACKET_STARTS_WITH ("qXfer:auxv:read::"))       return eServerPacketType_qXfer_auxv_read;
222af245d11STodd Fiala             break;
2238b82f087SGreg Clayton         }
224576d8834SGreg Clayton         break;
22598d0a4b3SChaoren Lin 
22698d0a4b3SChaoren Lin     case 'j':
227e837e6c7SOleksiy Vyalov         if (PACKET_MATCHES("jSignalsInfo"))                     return eServerPacketType_jSignalsInfo;
2284a4bb12eSPavel Labath         if (PACKET_MATCHES("jThreadsInfo"))                     return eServerPacketType_jThreadsInfo;
229cec91ef9SGreg Clayton         break;
23098d0a4b3SChaoren Lin 
231e0f8f574SDaniel Malea     case 'v':
232e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH("vFile:"))
233e0f8f574SDaniel Malea             {
234fbb76349SGreg Clayton                 if (PACKET_STARTS_WITH("vFile:open:"))          return eServerPacketType_vFile_open;
235fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:close:"))    return eServerPacketType_vFile_close;
236fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:pread"))     return eServerPacketType_vFile_pread;
237fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:pwrite"))    return eServerPacketType_vFile_pwrite;
238fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:size"))      return eServerPacketType_vFile_size;
239fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:exists"))    return eServerPacketType_vFile_exists;
240fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:stat"))      return eServerPacketType_vFile_stat;
241fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:mode"))      return eServerPacketType_vFile_mode;
242fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:MD5"))       return eServerPacketType_vFile_md5;
243fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:symlink"))   return eServerPacketType_vFile_symlink;
244fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:unlink"))    return eServerPacketType_vFile_unlink;
245e0f8f574SDaniel Malea 
2460fefa676SJean-Daniel Dupas             } else {
2470fefa676SJean-Daniel Dupas               if (PACKET_STARTS_WITH ("vAttach;"))              return eServerPacketType_vAttach;
2480fefa676SJean-Daniel Dupas               if (PACKET_STARTS_WITH ("vAttachWait;"))          return eServerPacketType_vAttachWait;
2490fefa676SJean-Daniel Dupas               if (PACKET_STARTS_WITH ("vAttachOrWait;"))        return eServerPacketType_vAttachOrWait;
2500fefa676SJean-Daniel Dupas               if (PACKET_STARTS_WITH ("vAttachName;"))          return eServerPacketType_vAttachName;
2510fefa676SJean-Daniel Dupas               if (PACKET_STARTS_WITH("vCont;"))                 return eServerPacketType_vCont;
2520fefa676SJean-Daniel Dupas               if (PACKET_MATCHES ("vCont?"))                    return eServerPacketType_vCont_actions;
253e0f8f574SDaniel Malea             }
254e0f8f574SDaniel Malea             break;
2550fefa676SJean-Daniel Dupas       case '_':
2560fefa676SJean-Daniel Dupas         switch (packet_cstr[1])
2570fefa676SJean-Daniel Dupas         {
2580fefa676SJean-Daniel Dupas         case 'M':
2590fefa676SJean-Daniel Dupas             return eServerPacketType__M;
2600fefa676SJean-Daniel Dupas 
2610fefa676SJean-Daniel Dupas         case 'm':
2620fefa676SJean-Daniel Dupas             return eServerPacketType__m;
2630fefa676SJean-Daniel Dupas         }
2640fefa676SJean-Daniel Dupas         break;
2650fefa676SJean-Daniel Dupas 
2660fefa676SJean-Daniel Dupas       case '?':
2670fefa676SJean-Daniel Dupas         if (packet_size == 1) return eServerPacketType_stop_reason;
2680fefa676SJean-Daniel Dupas         break;
2690fefa676SJean-Daniel Dupas 
2700fefa676SJean-Daniel Dupas       case 'c':
2710fefa676SJean-Daniel Dupas         return eServerPacketType_c;
2720fefa676SJean-Daniel Dupas 
2730fefa676SJean-Daniel Dupas       case 'C':
2740fefa676SJean-Daniel Dupas         return eServerPacketType_C;
2750fefa676SJean-Daniel Dupas 
2760fefa676SJean-Daniel Dupas       case 'D':
2770fefa676SJean-Daniel Dupas         if (packet_size == 1) return eServerPacketType_D;
2780fefa676SJean-Daniel Dupas         break;
2790fefa676SJean-Daniel Dupas 
2800fefa676SJean-Daniel Dupas       case 'g':
2810fefa676SJean-Daniel Dupas         if (packet_size == 1) return eServerPacketType_g;
2820fefa676SJean-Daniel Dupas         break;
2830fefa676SJean-Daniel Dupas 
2840fefa676SJean-Daniel Dupas       case 'G':
2850fefa676SJean-Daniel Dupas         return eServerPacketType_G;
2860fefa676SJean-Daniel Dupas 
2870fefa676SJean-Daniel Dupas       case 'H':
2880fefa676SJean-Daniel Dupas         return eServerPacketType_H;
2890fefa676SJean-Daniel Dupas 
290e0be425aSVince Harron       case 'I':
291e0be425aSVince Harron         return eServerPacketType_I;
292e0be425aSVince Harron 
2930fefa676SJean-Daniel Dupas       case 'k':
2940fefa676SJean-Daniel Dupas         if (packet_size == 1) return eServerPacketType_k;
2950fefa676SJean-Daniel Dupas         break;
2960fefa676SJean-Daniel Dupas 
2970fefa676SJean-Daniel Dupas       case 'm':
2980fefa676SJean-Daniel Dupas         return eServerPacketType_m;
2990fefa676SJean-Daniel Dupas 
3000fefa676SJean-Daniel Dupas       case 'M':
3010fefa676SJean-Daniel Dupas         return eServerPacketType_M;
3020fefa676SJean-Daniel Dupas 
3030fefa676SJean-Daniel Dupas       case 'p':
3040fefa676SJean-Daniel Dupas         return eServerPacketType_p;
3050fefa676SJean-Daniel Dupas 
3060fefa676SJean-Daniel Dupas       case 'P':
3070fefa676SJean-Daniel Dupas         return eServerPacketType_P;
3080fefa676SJean-Daniel Dupas 
3090fefa676SJean-Daniel Dupas       case 's':
3100fefa676SJean-Daniel Dupas         if (packet_size == 1) return eServerPacketType_s;
3110fefa676SJean-Daniel Dupas         break;
3120fefa676SJean-Daniel Dupas 
3130fefa676SJean-Daniel Dupas       case 'S':
3140fefa676SJean-Daniel Dupas         return eServerPacketType_S;
3150fefa676SJean-Daniel Dupas 
3163bf11256SPavel Labath       case 'x':
3173bf11256SPavel Labath         return eServerPacketType_x;
3183bf11256SPavel Labath 
3193bf11256SPavel Labath       case 'X':
3203bf11256SPavel Labath         return eServerPacketType_X;
3213bf11256SPavel Labath 
3220fefa676SJean-Daniel Dupas       case 'T':
3230fefa676SJean-Daniel Dupas         return eServerPacketType_T;
3240fefa676SJean-Daniel Dupas 
3250fefa676SJean-Daniel Dupas       case 'z':
3260fefa676SJean-Daniel Dupas         if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
3270fefa676SJean-Daniel Dupas           return eServerPacketType_z;
3280fefa676SJean-Daniel Dupas         break;
3290fefa676SJean-Daniel Dupas 
3300fefa676SJean-Daniel Dupas       case 'Z':
3310fefa676SJean-Daniel Dupas         if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
3320fefa676SJean-Daniel Dupas           return eServerPacketType_Z;
3330fefa676SJean-Daniel Dupas         break;
334576d8834SGreg Clayton     }
335576d8834SGreg Clayton     return eServerPacketType_unimplemented;
336576d8834SGreg Clayton }
337576d8834SGreg Clayton 
338576d8834SGreg Clayton bool
339576d8834SGreg Clayton StringExtractorGDBRemote::IsOKResponse() const
340576d8834SGreg Clayton {
341576d8834SGreg Clayton     return GetResponseType () == eOK;
34230fdc8d8SChris Lattner }
34330fdc8d8SChris Lattner 
34430fdc8d8SChris Lattner 
34530fdc8d8SChris Lattner bool
346576d8834SGreg Clayton StringExtractorGDBRemote::IsUnsupportedResponse() const
34730fdc8d8SChris Lattner {
348576d8834SGreg Clayton     return GetResponseType () == eUnsupported;
34930fdc8d8SChris Lattner }
35030fdc8d8SChris Lattner 
35130fdc8d8SChris Lattner bool
352576d8834SGreg Clayton StringExtractorGDBRemote::IsNormalResponse() const
35330fdc8d8SChris Lattner {
354576d8834SGreg Clayton     return GetResponseType () == eResponse;
35530fdc8d8SChris Lattner }
35630fdc8d8SChris Lattner 
35730fdc8d8SChris Lattner bool
358576d8834SGreg Clayton StringExtractorGDBRemote::IsErrorResponse() const
35930fdc8d8SChris Lattner {
360576d8834SGreg Clayton     return GetResponseType () == eError &&
36130fdc8d8SChris Lattner            m_packet.size() == 3 &&
36230fdc8d8SChris Lattner            isxdigit(m_packet[1]) &&
36330fdc8d8SChris Lattner            isxdigit(m_packet[2]);
36430fdc8d8SChris Lattner }
36530fdc8d8SChris Lattner 
36630fdc8d8SChris Lattner uint8_t
36730fdc8d8SChris Lattner StringExtractorGDBRemote::GetError ()
36830fdc8d8SChris Lattner {
369576d8834SGreg Clayton     if (GetResponseType() == eError)
37030fdc8d8SChris Lattner     {
37130fdc8d8SChris Lattner         SetFilePos(1);
37230fdc8d8SChris Lattner         return GetHexU8(255);
37330fdc8d8SChris Lattner     }
37430fdc8d8SChris Lattner     return 0;
37530fdc8d8SChris Lattner }
376e0f8f574SDaniel Malea 
377e0f8f574SDaniel Malea size_t
378e0f8f574SDaniel Malea StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)
379e0f8f574SDaniel Malea {
380109534cbSGreg Clayton     // Just get the data bytes in the string as GDBRemoteCommunication::CheckForPacket()
381109534cbSGreg Clayton     // already removes any 0x7d escaped characters. If any 0x7d characters are left in
382109534cbSGreg Clayton     // the packet, then they are supposed to be there...
383e0f8f574SDaniel Malea     str.clear();
384109534cbSGreg Clayton     const size_t bytes_left = GetBytesLeft();
385109534cbSGreg Clayton     if (bytes_left > 0)
386e0f8f574SDaniel Malea     {
387109534cbSGreg Clayton         str.assign(m_packet, m_index, bytes_left);
388109534cbSGreg Clayton         m_index += bytes_left;
389e0f8f574SDaniel Malea     }
390e0f8f574SDaniel Malea     return str.size();
391e0f8f574SDaniel Malea }
392e0f8f574SDaniel Malea 
393*830c81d5SGreg Clayton static bool
394*830c81d5SGreg Clayton OKErrorNotSupportedResponseValidator(void *, const StringExtractorGDBRemote &response)
395*830c81d5SGreg Clayton {
396*830c81d5SGreg Clayton     switch (response.GetResponseType())
397*830c81d5SGreg Clayton     {
398*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eOK:
399*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eError:
400*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eUnsupported:
401*830c81d5SGreg Clayton             return true;
402*830c81d5SGreg Clayton 
403*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eAck:
404*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eNack:
405*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eResponse:
406*830c81d5SGreg Clayton             break;
407*830c81d5SGreg Clayton     }
408*830c81d5SGreg Clayton     lldbassert(!"Packet validatation failed, check why this is happening");
409*830c81d5SGreg Clayton     return false;
410*830c81d5SGreg Clayton }
411*830c81d5SGreg Clayton 
412*830c81d5SGreg Clayton static bool
413*830c81d5SGreg Clayton JSONResponseValidator(void *, const StringExtractorGDBRemote &response)
414*830c81d5SGreg Clayton {
415*830c81d5SGreg Clayton     switch (response.GetResponseType())
416*830c81d5SGreg Clayton     {
417*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eUnsupported:
418*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eError:
419*830c81d5SGreg Clayton             return true; // Accept unsupported or EXX as valid responses
420*830c81d5SGreg Clayton 
421*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eOK:
422*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eAck:
423*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eNack:
424*830c81d5SGreg Clayton             break;
425*830c81d5SGreg Clayton 
426*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eResponse:
427*830c81d5SGreg Clayton             // JSON that is returned in from JSON query packets is currently always
428*830c81d5SGreg Clayton             // either a dictionary which starts with a '{', or an array which
429*830c81d5SGreg Clayton             // starts with a '['. This is a quick validator to just make sure the
430*830c81d5SGreg Clayton             // response could be valid JSON without having to validate all of the
431*830c81d5SGreg Clayton             // JSON content.
432*830c81d5SGreg Clayton             switch (response.GetStringRef()[0])
433*830c81d5SGreg Clayton             {
434*830c81d5SGreg Clayton                 case '{': return true;
435*830c81d5SGreg Clayton                 case '[': return true;
436*830c81d5SGreg Clayton                 default:
437*830c81d5SGreg Clayton                     break;
438*830c81d5SGreg Clayton             }
439*830c81d5SGreg Clayton             break;
440*830c81d5SGreg Clayton     }
441*830c81d5SGreg Clayton     lldbassert(!"Packet validatation failed, check why this is happening");
442*830c81d5SGreg Clayton     return false;
443*830c81d5SGreg Clayton }
444*830c81d5SGreg Clayton 
445*830c81d5SGreg Clayton static bool
446*830c81d5SGreg Clayton ASCIIHexBytesResponseValidator(void *, const StringExtractorGDBRemote &response)
447*830c81d5SGreg Clayton {
448*830c81d5SGreg Clayton     switch (response.GetResponseType())
449*830c81d5SGreg Clayton     {
450*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eUnsupported:
451*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eError:
452*830c81d5SGreg Clayton             return true; // Accept unsupported or EXX as valid responses
453*830c81d5SGreg Clayton 
454*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eOK:
455*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eAck:
456*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eNack:
457*830c81d5SGreg Clayton             break;
458*830c81d5SGreg Clayton 
459*830c81d5SGreg Clayton         case StringExtractorGDBRemote::eResponse:
460*830c81d5SGreg Clayton             {
461*830c81d5SGreg Clayton                 uint32_t valid_count = 0;
462*830c81d5SGreg Clayton                 for (const char ch : response.GetStringRef())
463*830c81d5SGreg Clayton                 {
464*830c81d5SGreg Clayton                     if (!isxdigit(ch))
465*830c81d5SGreg Clayton                     {
466*830c81d5SGreg Clayton                         lldbassert(!"Packet validatation failed, check why this is happening");
467*830c81d5SGreg Clayton                         return false;
468*830c81d5SGreg Clayton                     }
469*830c81d5SGreg Clayton                     if (++valid_count >= 16)
470*830c81d5SGreg Clayton                         break; // Don't validate all the characters in case the packet is very large
471*830c81d5SGreg Clayton                 }
472*830c81d5SGreg Clayton                 return true;
473*830c81d5SGreg Clayton             }
474*830c81d5SGreg Clayton             break;
475*830c81d5SGreg Clayton     }
476*830c81d5SGreg Clayton     lldbassert(!"Packet validatation failed, check why this is happening");
477*830c81d5SGreg Clayton     return false;
478*830c81d5SGreg Clayton }
479*830c81d5SGreg Clayton 
480*830c81d5SGreg Clayton void
481*830c81d5SGreg Clayton StringExtractorGDBRemote::CopyResponseValidator(const StringExtractorGDBRemote& rhs)
482*830c81d5SGreg Clayton {
483*830c81d5SGreg Clayton     m_validator = rhs.m_validator;
484*830c81d5SGreg Clayton     m_validator_baton = rhs.m_validator_baton;
485*830c81d5SGreg Clayton }
486*830c81d5SGreg Clayton 
487*830c81d5SGreg Clayton void
488*830c81d5SGreg Clayton StringExtractorGDBRemote::SetResponseValidator(ResponseValidatorCallback callback, void *baton)
489*830c81d5SGreg Clayton {
490*830c81d5SGreg Clayton     m_validator = callback;
491*830c81d5SGreg Clayton     m_validator_baton = baton;
492*830c81d5SGreg Clayton }
493*830c81d5SGreg Clayton 
494*830c81d5SGreg Clayton void
495*830c81d5SGreg Clayton StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported()
496*830c81d5SGreg Clayton {
497*830c81d5SGreg Clayton     m_validator = OKErrorNotSupportedResponseValidator;
498*830c81d5SGreg Clayton     m_validator_baton = nullptr;
499*830c81d5SGreg Clayton }
500*830c81d5SGreg Clayton 
501*830c81d5SGreg Clayton void
502*830c81d5SGreg Clayton StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes()
503*830c81d5SGreg Clayton {
504*830c81d5SGreg Clayton     m_validator = ASCIIHexBytesResponseValidator;
505*830c81d5SGreg Clayton     m_validator_baton = nullptr;
506*830c81d5SGreg Clayton }
507*830c81d5SGreg Clayton 
508*830c81d5SGreg Clayton void
509*830c81d5SGreg Clayton StringExtractorGDBRemote::SetResponseValidatorToJSON()
510*830c81d5SGreg Clayton {
511*830c81d5SGreg Clayton     m_validator = JSONResponseValidator;
512*830c81d5SGreg Clayton     m_validator_baton = nullptr;
513*830c81d5SGreg Clayton }
514*830c81d5SGreg Clayton 
515*830c81d5SGreg Clayton bool
516*830c81d5SGreg Clayton StringExtractorGDBRemote::ValidateResponse() const
517*830c81d5SGreg Clayton {
518*830c81d5SGreg Clayton     // If we have a validator callback, try to validate the callback
519*830c81d5SGreg Clayton     if (m_validator)
520*830c81d5SGreg Clayton         return m_validator(m_validator_baton, *this);
521*830c81d5SGreg Clayton     else
522*830c81d5SGreg Clayton         return true; // No validator, so response is valid
523*830c81d5SGreg Clayton }
524*830c81d5SGreg Clayton 
525*830c81d5SGreg Clayton 
526