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 
10ad65c051SStephen Wilson #include "Utility/StringExtractorGDBRemote.h"
1130fdc8d8SChris Lattner 
124479ac15SZachary Turner #include <ctype.h> // for isxdigit
134479ac15SZachary Turner #include <string.h>
144479ac15SZachary Turner 
15576d8834SGreg Clayton StringExtractorGDBRemote::ResponseType
16b9c1b51eSKate Stone StringExtractorGDBRemote::GetResponseType() const {
1730fdc8d8SChris Lattner   if (m_packet.empty())
1830fdc8d8SChris Lattner     return eUnsupported;
1930fdc8d8SChris Lattner 
20b9c1b51eSKate Stone   switch (m_packet[0]) {
2130fdc8d8SChris Lattner   case 'E':
22b9c1b51eSKate Stone     if (m_packet.size() == 3 && isxdigit(m_packet[1]) && isxdigit(m_packet[2]))
2330fdc8d8SChris Lattner       return eError;
2430fdc8d8SChris Lattner     break;
2530fdc8d8SChris Lattner 
2630fdc8d8SChris Lattner   case 'O':
2730fdc8d8SChris Lattner     if (m_packet.size() == 2 && m_packet[1] == 'K')
2830fdc8d8SChris Lattner       return eOK;
2930fdc8d8SChris Lattner     break;
3030fdc8d8SChris Lattner 
3130fdc8d8SChris Lattner   case '+':
3230fdc8d8SChris Lattner     if (m_packet.size() == 1)
3330fdc8d8SChris Lattner       return eAck;
3430fdc8d8SChris Lattner     break;
3530fdc8d8SChris Lattner 
3630fdc8d8SChris Lattner   case '-':
3730fdc8d8SChris Lattner     if (m_packet.size() == 1)
3830fdc8d8SChris Lattner       return eNack;
3930fdc8d8SChris Lattner     break;
4030fdc8d8SChris Lattner   }
4130fdc8d8SChris Lattner   return eResponse;
4230fdc8d8SChris Lattner }
4330fdc8d8SChris Lattner 
44576d8834SGreg Clayton StringExtractorGDBRemote::ServerPacketType
45b9c1b51eSKate Stone StringExtractorGDBRemote::GetServerPacketType() const {
46b9c1b51eSKate Stone #define PACKET_MATCHES(s)                                                      \
47b9c1b51eSKate Stone   ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0))
48b9c1b51eSKate Stone #define PACKET_STARTS_WITH(s)                                                  \
49b9c1b51eSKate Stone   ((packet_size >= (sizeof(s) - 1)) &&                                         \
50b9c1b51eSKate Stone    ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0)
518b82f087SGreg Clayton 
52576d8834SGreg Clayton   // Empty is not a supported packet...
53576d8834SGreg Clayton   if (m_packet.empty())
54576d8834SGreg Clayton     return eServerPacketType_invalid;
55576d8834SGreg Clayton 
568b82f087SGreg Clayton   const size_t packet_size = m_packet.size();
57576d8834SGreg Clayton   const char *packet_cstr = m_packet.c_str();
58b9c1b51eSKate Stone   switch (m_packet[0]) {
5978baa197SEwan Crawford 
6078baa197SEwan Crawford   case '%':
6178baa197SEwan Crawford     return eServerPacketType_notify;
6278baa197SEwan Crawford 
63d314e810SGreg Clayton   case '\x03':
64b9c1b51eSKate Stone     if (packet_size == 1)
65b9c1b51eSKate Stone       return eServerPacketType_interrupt;
66d314e810SGreg Clayton     break;
67d314e810SGreg Clayton 
68576d8834SGreg Clayton   case '-':
69b9c1b51eSKate Stone     if (packet_size == 1)
70b9c1b51eSKate Stone       return eServerPacketType_nack;
71576d8834SGreg Clayton     break;
72576d8834SGreg Clayton 
73576d8834SGreg Clayton   case '+':
74b9c1b51eSKate Stone     if (packet_size == 1)
75b9c1b51eSKate Stone       return eServerPacketType_ack;
76576d8834SGreg Clayton     break;
77576d8834SGreg Clayton 
788b82f087SGreg Clayton   case 'A':
798b82f087SGreg Clayton     return eServerPacketType_A;
808b82f087SGreg Clayton 
811cb6496eSGreg Clayton   case 'Q':
820fefa676SJean-Daniel Dupas 
83b9c1b51eSKate Stone     switch (packet_cstr[1]) {
848b82f087SGreg Clayton     case 'E':
85b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QEnvironment:"))
86b9c1b51eSKate Stone         return eServerPacketType_QEnvironment;
87b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:"))
88b9c1b51eSKate Stone         return eServerPacketType_QEnvironmentHexEncoded;
898b82f087SGreg Clayton       break;
908b82f087SGreg Clayton 
914a705e7eSPavel Labath     case 'P':
924a705e7eSPavel Labath       if (PACKET_STARTS_WITH("QPassSignals:"))
934a705e7eSPavel Labath         return eServerPacketType_QPassSignals;
944a705e7eSPavel Labath 
958b82f087SGreg Clayton     case 'S':
96b9c1b51eSKate Stone       if (PACKET_MATCHES("QStartNoAckMode"))
97b9c1b51eSKate Stone         return eServerPacketType_QStartNoAckMode;
98b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSaveRegisterState"))
99b9c1b51eSKate Stone         return eServerPacketType_QSaveRegisterState;
100b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetDisableASLR:"))
101b9c1b51eSKate Stone         return eServerPacketType_QSetDisableASLR;
102b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetDetachOnError:"))
103b9c1b51eSKate Stone         return eServerPacketType_QSetDetachOnError;
104b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetSTDIN:"))
105b9c1b51eSKate Stone         return eServerPacketType_QSetSTDIN;
106b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetSTDOUT:"))
107b9c1b51eSKate Stone         return eServerPacketType_QSetSTDOUT;
108b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetSTDERR:"))
109b9c1b51eSKate Stone         return eServerPacketType_QSetSTDERR;
110b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetWorkingDir:"))
111b9c1b51eSKate Stone         return eServerPacketType_QSetWorkingDir;
112b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetLogging:"))
113b9c1b51eSKate Stone         return eServerPacketType_QSetLogging;
114b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetMaxPacketSize:"))
115b9c1b51eSKate Stone         return eServerPacketType_QSetMaxPacketSize;
116b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetMaxPayloadSize:"))
117b9c1b51eSKate Stone         return eServerPacketType_QSetMaxPayloadSize;
118b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;"))
119b9c1b51eSKate Stone         return eServerPacketType_QSetEnableAsyncProfiling;
120b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QSyncThreadState:"))
121b9c1b51eSKate Stone         return eServerPacketType_QSyncThreadState;
1228b82f087SGreg Clayton       break;
1230fefa676SJean-Daniel Dupas 
124e0f8f574SDaniel Malea     case 'L':
125b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QLaunchArch:"))
126b9c1b51eSKate Stone         return eServerPacketType_QLaunchArch;
127b9c1b51eSKate Stone       if (PACKET_MATCHES("QListThreadsInStopReply"))
128b9c1b51eSKate Stone         return eServerPacketType_QListThreadsInStopReply;
1290fefa676SJean-Daniel Dupas       break;
1300fefa676SJean-Daniel Dupas 
1310fefa676SJean-Daniel Dupas     case 'R':
132b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("QRestoreRegisterState:"))
133b9c1b51eSKate Stone         return eServerPacketType_QRestoreRegisterState;
1340fefa676SJean-Daniel Dupas       break;
1350fefa676SJean-Daniel Dupas 
1360fefa676SJean-Daniel Dupas     case 'T':
137b9c1b51eSKate Stone       if (PACKET_MATCHES("QThreadSuffixSupported"))
138b9c1b51eSKate Stone         return eServerPacketType_QThreadSuffixSupported;
139e0f8f574SDaniel Malea       break;
1408b82f087SGreg Clayton     }
1411cb6496eSGreg Clayton     break;
1421cb6496eSGreg Clayton 
143576d8834SGreg Clayton   case 'q':
144b9c1b51eSKate Stone     switch (packet_cstr[1]) {
1458b82f087SGreg Clayton     case 's':
146b9c1b51eSKate Stone       if (PACKET_MATCHES("qsProcessInfo"))
147b9c1b51eSKate Stone         return eServerPacketType_qsProcessInfo;
148b9c1b51eSKate Stone       if (PACKET_MATCHES("qsThreadInfo"))
149b9c1b51eSKate Stone         return eServerPacketType_qsThreadInfo;
1508b82f087SGreg Clayton       break;
1518b82f087SGreg Clayton 
1528b82f087SGreg Clayton     case 'f':
153b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qfProcessInfo"))
154b9c1b51eSKate Stone         return eServerPacketType_qfProcessInfo;
155b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qfThreadInfo"))
156b9c1b51eSKate Stone         return eServerPacketType_qfThreadInfo;
1578b82f087SGreg Clayton       break;
1588b82f087SGreg Clayton 
1598b82f087SGreg Clayton     case 'C':
160b9c1b51eSKate Stone       if (packet_size == 2)
161b9c1b51eSKate Stone         return eServerPacketType_qC;
1628b82f087SGreg Clayton       break;
1638b82f087SGreg Clayton 
164420562aaSGreg Clayton     case 'E':
165b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qEcho:"))
166b9c1b51eSKate Stone         return eServerPacketType_qEcho;
167420562aaSGreg Clayton       break;
168420562aaSGreg Clayton 
169783bfc8cSTamas Berghammer     case 'F':
170b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qFileLoadAddress:"))
171b9c1b51eSKate Stone         return eServerPacketType_qFileLoadAddress;
172783bfc8cSTamas Berghammer       break;
173783bfc8cSTamas Berghammer 
1748b82f087SGreg Clayton     case 'G':
175b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qGroupName:"))
176b9c1b51eSKate Stone         return eServerPacketType_qGroupName;
177b9c1b51eSKate Stone       if (PACKET_MATCHES("qGetWorkingDir"))
178b9c1b51eSKate Stone         return eServerPacketType_qGetWorkingDir;
179b9c1b51eSKate Stone       if (PACKET_MATCHES("qGetPid"))
180b9c1b51eSKate Stone         return eServerPacketType_qGetPid;
181b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qGetProfileData;"))
182b9c1b51eSKate Stone         return eServerPacketType_qGetProfileData;
183b9c1b51eSKate Stone       if (PACKET_MATCHES("qGDBServerVersion"))
184b9c1b51eSKate Stone         return eServerPacketType_qGDBServerVersion;
1858b82f087SGreg Clayton       break;
1868b82f087SGreg Clayton 
1878b82f087SGreg Clayton     case 'H':
188b9c1b51eSKate Stone       if (PACKET_MATCHES("qHostInfo"))
189b9c1b51eSKate Stone         return eServerPacketType_qHostInfo;
1908b82f087SGreg Clayton       break;
1918b82f087SGreg Clayton 
192e0f8f574SDaniel Malea     case 'K':
193b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qKillSpawnedProcess"))
194b9c1b51eSKate Stone         return eServerPacketType_qKillSpawnedProcess;
195e0f8f574SDaniel Malea       break;
196e0f8f574SDaniel Malea 
1978b82f087SGreg Clayton     case 'L':
198b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qLaunchGDBServer"))
199b9c1b51eSKate Stone         return eServerPacketType_qLaunchGDBServer;
200b9c1b51eSKate Stone       if (PACKET_MATCHES("qLaunchSuccess"))
201b9c1b51eSKate Stone         return eServerPacketType_qLaunchSuccess;
2028b82f087SGreg Clayton       break;
2038b82f087SGreg Clayton 
2040fefa676SJean-Daniel Dupas     case 'M':
205b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qMemoryRegionInfo:"))
206b9c1b51eSKate Stone         return eServerPacketType_qMemoryRegionInfo;
207b9c1b51eSKate Stone       if (PACKET_MATCHES("qMemoryRegionInfo"))
208b9c1b51eSKate Stone         return eServerPacketType_qMemoryRegionInfoSupported;
209b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qModuleInfo:"))
210b9c1b51eSKate Stone         return eServerPacketType_qModuleInfo;
2110fefa676SJean-Daniel Dupas       break;
2120fefa676SJean-Daniel Dupas 
2138b82f087SGreg Clayton     case 'P':
214b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qProcessInfoPID:"))
215b9c1b51eSKate Stone         return eServerPacketType_qProcessInfoPID;
216b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qPlatform_shell:"))
217b9c1b51eSKate Stone         return eServerPacketType_qPlatform_shell;
218b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qPlatform_mkdir:"))
219b9c1b51eSKate Stone         return eServerPacketType_qPlatform_mkdir;
220b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qPlatform_chmod:"))
221b9c1b51eSKate Stone         return eServerPacketType_qPlatform_chmod;
222b9c1b51eSKate Stone       if (PACKET_MATCHES("qProcessInfo"))
223b9c1b51eSKate Stone         return eServerPacketType_qProcessInfo;
2248b82f087SGreg Clayton       break;
2258b82f087SGreg Clayton 
226ccd6cffbSTamas Berghammer     case 'Q':
227b9c1b51eSKate Stone       if (PACKET_MATCHES("qQueryGDBServer"))
228b9c1b51eSKate Stone         return eServerPacketType_qQueryGDBServer;
229ccd6cffbSTamas Berghammer       break;
230ccd6cffbSTamas Berghammer 
2310fefa676SJean-Daniel Dupas     case 'R':
232b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qRcmd,"))
233b9c1b51eSKate Stone         return eServerPacketType_qRcmd;
234b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qRegisterInfo"))
235b9c1b51eSKate Stone         return eServerPacketType_qRegisterInfo;
2360fefa676SJean-Daniel Dupas       break;
237e0f8f574SDaniel Malea 
2388b82f087SGreg Clayton     case 'S':
239b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qSpeedTest:"))
240b9c1b51eSKate Stone         return eServerPacketType_qSpeedTest;
241b9c1b51eSKate Stone       if (PACKET_MATCHES("qShlibInfoAddr"))
242b9c1b51eSKate Stone         return eServerPacketType_qShlibInfoAddr;
243b9c1b51eSKate Stone       if (PACKET_MATCHES("qStepPacketSupported"))
244b9c1b51eSKate Stone         return eServerPacketType_qStepPacketSupported;
245b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qSupported"))
246b9c1b51eSKate Stone         return eServerPacketType_qSupported;
247b9c1b51eSKate Stone       if (PACKET_MATCHES("qSyncThreadStateSupported"))
248b9c1b51eSKate Stone         return eServerPacketType_qSyncThreadStateSupported;
2490fefa676SJean-Daniel Dupas       break;
2500fefa676SJean-Daniel Dupas 
2510fefa676SJean-Daniel Dupas     case 'T':
252b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qThreadExtraInfo,"))
253b9c1b51eSKate Stone         return eServerPacketType_qThreadExtraInfo;
254b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qThreadStopInfo"))
255b9c1b51eSKate Stone         return eServerPacketType_qThreadStopInfo;
2568b82f087SGreg Clayton       break;
2578b82f087SGreg Clayton 
2588b82f087SGreg Clayton     case 'U':
259b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qUserName:"))
260b9c1b51eSKate Stone         return eServerPacketType_qUserName;
2618b82f087SGreg Clayton       break;
2620fefa676SJean-Daniel Dupas 
2630fefa676SJean-Daniel Dupas     case 'V':
264b9c1b51eSKate Stone       if (PACKET_MATCHES("qVAttachOrWaitSupported"))
265b9c1b51eSKate Stone         return eServerPacketType_qVAttachOrWaitSupported;
2660fefa676SJean-Daniel Dupas       break;
2670fefa676SJean-Daniel Dupas 
2680fefa676SJean-Daniel Dupas     case 'W':
269b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qWatchpointSupportInfo:"))
270b9c1b51eSKate Stone         return eServerPacketType_qWatchpointSupportInfo;
271b9c1b51eSKate Stone       if (PACKET_MATCHES("qWatchpointSupportInfo"))
272b9c1b51eSKate Stone         return eServerPacketType_qWatchpointSupportInfoSupported;
2730fefa676SJean-Daniel Dupas       break;
274af245d11STodd Fiala 
275af245d11STodd Fiala     case 'X':
276b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("qXfer:auxv:read::"))
277b9c1b51eSKate Stone         return eServerPacketType_qXfer_auxv_read;
278af245d11STodd Fiala       break;
2798b82f087SGreg Clayton     }
280576d8834SGreg Clayton     break;
28198d0a4b3SChaoren Lin 
28298d0a4b3SChaoren Lin   case 'j':
2832f1fbaebSPavel Labath     if (PACKET_STARTS_WITH("jModulesInfo:"))
2842f1fbaebSPavel Labath       return eServerPacketType_jModulesInfo;
285b9c1b51eSKate Stone     if (PACKET_MATCHES("jSignalsInfo"))
286b9c1b51eSKate Stone       return eServerPacketType_jSignalsInfo;
287b9c1b51eSKate Stone     if (PACKET_MATCHES("jThreadsInfo"))
288b9c1b51eSKate Stone       return eServerPacketType_jThreadsInfo;
289*e714c4f5SRavitheja Addepally     if (PACKET_STARTS_WITH("jTraceBufferRead:"))
290*e714c4f5SRavitheja Addepally       return eServerPacketType_jTraceBufferRead;
291*e714c4f5SRavitheja Addepally     if (PACKET_STARTS_WITH("jTraceConfigRead:"))
292*e714c4f5SRavitheja Addepally       return eServerPacketType_jTraceConfigRead;
293*e714c4f5SRavitheja Addepally     if (PACKET_STARTS_WITH("jTraceMetaRead:"))
294*e714c4f5SRavitheja Addepally       return eServerPacketType_jTraceMetaRead;
295*e714c4f5SRavitheja Addepally     if (PACKET_STARTS_WITH("jTraceStart:"))
296*e714c4f5SRavitheja Addepally       return eServerPacketType_jTraceStart;
297*e714c4f5SRavitheja Addepally     if (PACKET_STARTS_WITH("jTraceStop:"))
298*e714c4f5SRavitheja Addepally       return eServerPacketType_jTraceStop;
299cec91ef9SGreg Clayton     break;
30098d0a4b3SChaoren Lin 
301e0f8f574SDaniel Malea   case 'v':
302b9c1b51eSKate Stone     if (PACKET_STARTS_WITH("vFile:")) {
303b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("vFile:open:"))
304b9c1b51eSKate Stone         return eServerPacketType_vFile_open;
305b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:close:"))
306b9c1b51eSKate Stone         return eServerPacketType_vFile_close;
307b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:pread"))
308b9c1b51eSKate Stone         return eServerPacketType_vFile_pread;
309b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:pwrite"))
310b9c1b51eSKate Stone         return eServerPacketType_vFile_pwrite;
311b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:size"))
312b9c1b51eSKate Stone         return eServerPacketType_vFile_size;
313b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:exists"))
314b9c1b51eSKate Stone         return eServerPacketType_vFile_exists;
315b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:stat"))
316b9c1b51eSKate Stone         return eServerPacketType_vFile_stat;
317b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:mode"))
318b9c1b51eSKate Stone         return eServerPacketType_vFile_mode;
319b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:MD5"))
320b9c1b51eSKate Stone         return eServerPacketType_vFile_md5;
321b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:symlink"))
322b9c1b51eSKate Stone         return eServerPacketType_vFile_symlink;
323b9c1b51eSKate Stone       else if (PACKET_STARTS_WITH("vFile:unlink"))
324b9c1b51eSKate Stone         return eServerPacketType_vFile_unlink;
325e0f8f574SDaniel Malea 
3260fefa676SJean-Daniel Dupas     } else {
327b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("vAttach;"))
328b9c1b51eSKate Stone         return eServerPacketType_vAttach;
329b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("vAttachWait;"))
330b9c1b51eSKate Stone         return eServerPacketType_vAttachWait;
331b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("vAttachOrWait;"))
332b9c1b51eSKate Stone         return eServerPacketType_vAttachOrWait;
333b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("vAttachName;"))
334b9c1b51eSKate Stone         return eServerPacketType_vAttachName;
335b9c1b51eSKate Stone       if (PACKET_STARTS_WITH("vCont;"))
336b9c1b51eSKate Stone         return eServerPacketType_vCont;
337b9c1b51eSKate Stone       if (PACKET_MATCHES("vCont?"))
338b9c1b51eSKate Stone         return eServerPacketType_vCont_actions;
339e0f8f574SDaniel Malea     }
340e0f8f574SDaniel Malea     break;
3410fefa676SJean-Daniel Dupas   case '_':
342b9c1b51eSKate Stone     switch (packet_cstr[1]) {
3430fefa676SJean-Daniel Dupas     case 'M':
3440fefa676SJean-Daniel Dupas       return eServerPacketType__M;
3450fefa676SJean-Daniel Dupas 
3460fefa676SJean-Daniel Dupas     case 'm':
3470fefa676SJean-Daniel Dupas       return eServerPacketType__m;
3480fefa676SJean-Daniel Dupas     }
3490fefa676SJean-Daniel Dupas     break;
3500fefa676SJean-Daniel Dupas 
3510fefa676SJean-Daniel Dupas   case '?':
352b9c1b51eSKate Stone     if (packet_size == 1)
353b9c1b51eSKate Stone       return eServerPacketType_stop_reason;
3540fefa676SJean-Daniel Dupas     break;
3550fefa676SJean-Daniel Dupas 
3560fefa676SJean-Daniel Dupas   case 'c':
3570fefa676SJean-Daniel Dupas     return eServerPacketType_c;
3580fefa676SJean-Daniel Dupas 
3590fefa676SJean-Daniel Dupas   case 'C':
3600fefa676SJean-Daniel Dupas     return eServerPacketType_C;
3610fefa676SJean-Daniel Dupas 
3620fefa676SJean-Daniel Dupas   case 'D':
363b9c1b51eSKate Stone     if (packet_size == 1)
364b9c1b51eSKate Stone       return eServerPacketType_D;
3650fefa676SJean-Daniel Dupas     break;
3660fefa676SJean-Daniel Dupas 
3670fefa676SJean-Daniel Dupas   case 'g':
368b9c1b51eSKate Stone     if (packet_size == 1)
369b9c1b51eSKate Stone       return eServerPacketType_g;
3700fefa676SJean-Daniel Dupas     break;
3710fefa676SJean-Daniel Dupas 
3720fefa676SJean-Daniel Dupas   case 'G':
3730fefa676SJean-Daniel Dupas     return eServerPacketType_G;
3740fefa676SJean-Daniel Dupas 
3750fefa676SJean-Daniel Dupas   case 'H':
3760fefa676SJean-Daniel Dupas     return eServerPacketType_H;
3770fefa676SJean-Daniel Dupas 
378e0be425aSVince Harron   case 'I':
379e0be425aSVince Harron     return eServerPacketType_I;
380e0be425aSVince Harron 
3810fefa676SJean-Daniel Dupas   case 'k':
382b9c1b51eSKate Stone     if (packet_size == 1)
383b9c1b51eSKate Stone       return eServerPacketType_k;
3840fefa676SJean-Daniel Dupas     break;
3850fefa676SJean-Daniel Dupas 
3860fefa676SJean-Daniel Dupas   case 'm':
3870fefa676SJean-Daniel Dupas     return eServerPacketType_m;
3880fefa676SJean-Daniel Dupas 
3890fefa676SJean-Daniel Dupas   case 'M':
3900fefa676SJean-Daniel Dupas     return eServerPacketType_M;
3910fefa676SJean-Daniel Dupas 
3920fefa676SJean-Daniel Dupas   case 'p':
3930fefa676SJean-Daniel Dupas     return eServerPacketType_p;
3940fefa676SJean-Daniel Dupas 
3950fefa676SJean-Daniel Dupas   case 'P':
3960fefa676SJean-Daniel Dupas     return eServerPacketType_P;
3970fefa676SJean-Daniel Dupas 
3980fefa676SJean-Daniel Dupas   case 's':
399b9c1b51eSKate Stone     if (packet_size == 1)
400b9c1b51eSKate Stone       return eServerPacketType_s;
4010fefa676SJean-Daniel Dupas     break;
4020fefa676SJean-Daniel Dupas 
4030fefa676SJean-Daniel Dupas   case 'S':
4040fefa676SJean-Daniel Dupas     return eServerPacketType_S;
4050fefa676SJean-Daniel Dupas 
4063bf11256SPavel Labath   case 'x':
4073bf11256SPavel Labath     return eServerPacketType_x;
4083bf11256SPavel Labath 
4093bf11256SPavel Labath   case 'X':
4103bf11256SPavel Labath     return eServerPacketType_X;
4113bf11256SPavel Labath 
4120fefa676SJean-Daniel Dupas   case 'T':
4130fefa676SJean-Daniel Dupas     return eServerPacketType_T;
4140fefa676SJean-Daniel Dupas 
4150fefa676SJean-Daniel Dupas   case 'z':
4160fefa676SJean-Daniel Dupas     if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
4170fefa676SJean-Daniel Dupas       return eServerPacketType_z;
4180fefa676SJean-Daniel Dupas     break;
4190fefa676SJean-Daniel Dupas 
4200fefa676SJean-Daniel Dupas   case 'Z':
4210fefa676SJean-Daniel Dupas     if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
4220fefa676SJean-Daniel Dupas       return eServerPacketType_Z;
4230fefa676SJean-Daniel Dupas     break;
424576d8834SGreg Clayton   }
425576d8834SGreg Clayton   return eServerPacketType_unimplemented;
426576d8834SGreg Clayton }
427576d8834SGreg Clayton 
428b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsOKResponse() const {
429576d8834SGreg Clayton   return GetResponseType() == eOK;
43030fdc8d8SChris Lattner }
43130fdc8d8SChris Lattner 
432b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsUnsupportedResponse() const {
433576d8834SGreg Clayton   return GetResponseType() == eUnsupported;
43430fdc8d8SChris Lattner }
43530fdc8d8SChris Lattner 
436b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsNormalResponse() const {
437576d8834SGreg Clayton   return GetResponseType() == eResponse;
43830fdc8d8SChris Lattner }
43930fdc8d8SChris Lattner 
440b9c1b51eSKate Stone bool StringExtractorGDBRemote::IsErrorResponse() const {
441b9c1b51eSKate Stone   return GetResponseType() == eError && m_packet.size() == 3 &&
442b9c1b51eSKate Stone          isxdigit(m_packet[1]) && isxdigit(m_packet[2]);
44330fdc8d8SChris Lattner }
44430fdc8d8SChris Lattner 
445b9c1b51eSKate Stone uint8_t StringExtractorGDBRemote::GetError() {
446b9c1b51eSKate Stone   if (GetResponseType() == eError) {
44730fdc8d8SChris Lattner     SetFilePos(1);
44830fdc8d8SChris Lattner     return GetHexU8(255);
44930fdc8d8SChris Lattner   }
45030fdc8d8SChris Lattner   return 0;
45130fdc8d8SChris Lattner }
452e0f8f574SDaniel Malea 
453b9c1b51eSKate Stone size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
454b9c1b51eSKate Stone   // Just get the data bytes in the string as
455b9c1b51eSKate Stone   // GDBRemoteCommunication::CheckForPacket()
456b9c1b51eSKate Stone   // already removes any 0x7d escaped characters. If any 0x7d characters are
457b9c1b51eSKate Stone   // left in
458109534cbSGreg Clayton   // the packet, then they are supposed to be there...
459e0f8f574SDaniel Malea   str.clear();
460109534cbSGreg Clayton   const size_t bytes_left = GetBytesLeft();
461b9c1b51eSKate Stone   if (bytes_left > 0) {
462109534cbSGreg Clayton     str.assign(m_packet, m_index, bytes_left);
463109534cbSGreg Clayton     m_index += bytes_left;
464e0f8f574SDaniel Malea   }
465e0f8f574SDaniel Malea   return str.size();
466e0f8f574SDaniel Malea }
467e0f8f574SDaniel Malea 
468830c81d5SGreg Clayton static bool
469b9c1b51eSKate Stone OKErrorNotSupportedResponseValidator(void *,
470b9c1b51eSKate Stone                                      const StringExtractorGDBRemote &response) {
471b9c1b51eSKate Stone   switch (response.GetResponseType()) {
472830c81d5SGreg Clayton   case StringExtractorGDBRemote::eOK:
473830c81d5SGreg Clayton   case StringExtractorGDBRemote::eError:
474830c81d5SGreg Clayton   case StringExtractorGDBRemote::eUnsupported:
475830c81d5SGreg Clayton     return true;
476830c81d5SGreg Clayton 
477830c81d5SGreg Clayton   case StringExtractorGDBRemote::eAck:
478830c81d5SGreg Clayton   case StringExtractorGDBRemote::eNack:
479830c81d5SGreg Clayton   case StringExtractorGDBRemote::eResponse:
480830c81d5SGreg Clayton     break;
481830c81d5SGreg Clayton   }
482830c81d5SGreg Clayton   return false;
483830c81d5SGreg Clayton }
484830c81d5SGreg Clayton 
485b9c1b51eSKate Stone static bool JSONResponseValidator(void *,
486b9c1b51eSKate Stone                                   const StringExtractorGDBRemote &response) {
487b9c1b51eSKate Stone   switch (response.GetResponseType()) {
488830c81d5SGreg Clayton   case StringExtractorGDBRemote::eUnsupported:
489830c81d5SGreg Clayton   case StringExtractorGDBRemote::eError:
490830c81d5SGreg Clayton     return true; // Accept unsupported or EXX as valid responses
491830c81d5SGreg Clayton 
492830c81d5SGreg Clayton   case StringExtractorGDBRemote::eOK:
493830c81d5SGreg Clayton   case StringExtractorGDBRemote::eAck:
494830c81d5SGreg Clayton   case StringExtractorGDBRemote::eNack:
495830c81d5SGreg Clayton     break;
496830c81d5SGreg Clayton 
497830c81d5SGreg Clayton   case StringExtractorGDBRemote::eResponse:
498830c81d5SGreg Clayton     // JSON that is returned in from JSON query packets is currently always
499830c81d5SGreg Clayton     // either a dictionary which starts with a '{', or an array which
500830c81d5SGreg Clayton     // starts with a '['. This is a quick validator to just make sure the
501830c81d5SGreg Clayton     // response could be valid JSON without having to validate all of the
502830c81d5SGreg Clayton     // JSON content.
503b9c1b51eSKate Stone     switch (response.GetStringRef()[0]) {
504b9c1b51eSKate Stone     case '{':
505b9c1b51eSKate Stone       return true;
506b9c1b51eSKate Stone     case '[':
507b9c1b51eSKate Stone       return true;
508830c81d5SGreg Clayton     default:
509830c81d5SGreg Clayton       break;
510830c81d5SGreg Clayton     }
511830c81d5SGreg Clayton     break;
512830c81d5SGreg Clayton   }
513830c81d5SGreg Clayton   return false;
514830c81d5SGreg Clayton }
515830c81d5SGreg Clayton 
516830c81d5SGreg Clayton static bool
517b9c1b51eSKate Stone ASCIIHexBytesResponseValidator(void *,
518b9c1b51eSKate Stone                                const StringExtractorGDBRemote &response) {
519b9c1b51eSKate Stone   switch (response.GetResponseType()) {
520830c81d5SGreg Clayton   case StringExtractorGDBRemote::eUnsupported:
521830c81d5SGreg Clayton   case StringExtractorGDBRemote::eError:
522830c81d5SGreg Clayton     return true; // Accept unsupported or EXX as valid responses
523830c81d5SGreg Clayton 
524830c81d5SGreg Clayton   case StringExtractorGDBRemote::eOK:
525830c81d5SGreg Clayton   case StringExtractorGDBRemote::eAck:
526830c81d5SGreg Clayton   case StringExtractorGDBRemote::eNack:
527830c81d5SGreg Clayton     break;
528830c81d5SGreg Clayton 
529b9c1b51eSKate Stone   case StringExtractorGDBRemote::eResponse: {
530830c81d5SGreg Clayton     uint32_t valid_count = 0;
531b9c1b51eSKate Stone     for (const char ch : response.GetStringRef()) {
532b9c1b51eSKate Stone       if (!isxdigit(ch)) {
533830c81d5SGreg Clayton         return false;
534830c81d5SGreg Clayton       }
535830c81d5SGreg Clayton       if (++valid_count >= 16)
536b9c1b51eSKate Stone         break; // Don't validate all the characters in case the packet is very
537b9c1b51eSKate Stone                // large
538830c81d5SGreg Clayton     }
539830c81d5SGreg Clayton     return true;
540b9c1b51eSKate Stone   } break;
541830c81d5SGreg Clayton   }
542830c81d5SGreg Clayton   return false;
543830c81d5SGreg Clayton }
544830c81d5SGreg Clayton 
545b9c1b51eSKate Stone void StringExtractorGDBRemote::CopyResponseValidator(
546b9c1b51eSKate Stone     const StringExtractorGDBRemote &rhs) {
547830c81d5SGreg Clayton   m_validator = rhs.m_validator;
548830c81d5SGreg Clayton   m_validator_baton = rhs.m_validator_baton;
549830c81d5SGreg Clayton }
550830c81d5SGreg Clayton 
551b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidator(
552b9c1b51eSKate Stone     ResponseValidatorCallback callback, void *baton) {
553830c81d5SGreg Clayton   m_validator = callback;
554830c81d5SGreg Clayton   m_validator_baton = baton;
555830c81d5SGreg Clayton }
556830c81d5SGreg Clayton 
557b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() {
558830c81d5SGreg Clayton   m_validator = OKErrorNotSupportedResponseValidator;
559830c81d5SGreg Clayton   m_validator_baton = nullptr;
560830c81d5SGreg Clayton }
561830c81d5SGreg Clayton 
562b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() {
563830c81d5SGreg Clayton   m_validator = ASCIIHexBytesResponseValidator;
564830c81d5SGreg Clayton   m_validator_baton = nullptr;
565830c81d5SGreg Clayton }
566830c81d5SGreg Clayton 
567b9c1b51eSKate Stone void StringExtractorGDBRemote::SetResponseValidatorToJSON() {
568830c81d5SGreg Clayton   m_validator = JSONResponseValidator;
569830c81d5SGreg Clayton   m_validator_baton = nullptr;
570830c81d5SGreg Clayton }
571830c81d5SGreg Clayton 
572b9c1b51eSKate Stone bool StringExtractorGDBRemote::ValidateResponse() const {
573830c81d5SGreg Clayton   // If we have a validator callback, try to validate the callback
574830c81d5SGreg Clayton   if (m_validator)
575830c81d5SGreg Clayton     return m_validator(m_validator_baton, *this);
576830c81d5SGreg Clayton   else
577830c81d5SGreg Clayton     return true; // No validator, so response is valid
578830c81d5SGreg Clayton }
579