1ac7ddfbfSEd Maste //===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
104ba319b5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h"
11ac7ddfbfSEd Maste
12*b5893f02SDimitry Andric #include <ctype.h>
13f678e45dSDimitry Andric #include <string.h>
14f678e45dSDimitry Andric
15ac7ddfbfSEd Maste StringExtractorGDBRemote::ResponseType
GetResponseType() const16435933ddSDimitry Andric StringExtractorGDBRemote::GetResponseType() const {
17ac7ddfbfSEd Maste if (m_packet.empty())
18ac7ddfbfSEd Maste return eUnsupported;
19ac7ddfbfSEd Maste
20435933ddSDimitry Andric switch (m_packet[0]) {
21ac7ddfbfSEd Maste case 'E':
22c4394386SDimitry Andric if (isxdigit(m_packet[1]) && isxdigit(m_packet[2])) {
23c4394386SDimitry Andric if (m_packet.size() == 3)
24ac7ddfbfSEd Maste return eError;
25c4394386SDimitry Andric llvm::StringRef packet_ref(m_packet);
26c4394386SDimitry Andric if (packet_ref[3] == ';') {
27c4394386SDimitry Andric auto err_string = packet_ref.substr(4);
28c4394386SDimitry Andric for (auto e : err_string)
29c4394386SDimitry Andric if (!isxdigit(e))
30c4394386SDimitry Andric return eResponse;
31c4394386SDimitry Andric return eError;
32c4394386SDimitry Andric }
33c4394386SDimitry Andric }
34ac7ddfbfSEd Maste break;
35ac7ddfbfSEd Maste
36ac7ddfbfSEd Maste case 'O':
37ac7ddfbfSEd Maste if (m_packet.size() == 2 && m_packet[1] == 'K')
38ac7ddfbfSEd Maste return eOK;
39ac7ddfbfSEd Maste break;
40ac7ddfbfSEd Maste
41ac7ddfbfSEd Maste case '+':
42ac7ddfbfSEd Maste if (m_packet.size() == 1)
43ac7ddfbfSEd Maste return eAck;
44ac7ddfbfSEd Maste break;
45ac7ddfbfSEd Maste
46ac7ddfbfSEd Maste case '-':
47ac7ddfbfSEd Maste if (m_packet.size() == 1)
48ac7ddfbfSEd Maste return eNack;
49ac7ddfbfSEd Maste break;
50ac7ddfbfSEd Maste }
51ac7ddfbfSEd Maste return eResponse;
52ac7ddfbfSEd Maste }
53ac7ddfbfSEd Maste
54ac7ddfbfSEd Maste StringExtractorGDBRemote::ServerPacketType
GetServerPacketType() const55435933ddSDimitry Andric StringExtractorGDBRemote::GetServerPacketType() const {
56435933ddSDimitry Andric #define PACKET_MATCHES(s) \
57435933ddSDimitry Andric ((packet_size == (sizeof(s) - 1)) && (strcmp((packet_cstr), (s)) == 0))
58435933ddSDimitry Andric #define PACKET_STARTS_WITH(s) \
59435933ddSDimitry Andric ((packet_size >= (sizeof(s) - 1)) && \
60435933ddSDimitry Andric ::strncmp(packet_cstr, s, (sizeof(s) - 1)) == 0)
61ac7ddfbfSEd Maste
62ac7ddfbfSEd Maste // Empty is not a supported packet...
63ac7ddfbfSEd Maste if (m_packet.empty())
64ac7ddfbfSEd Maste return eServerPacketType_invalid;
65ac7ddfbfSEd Maste
66ac7ddfbfSEd Maste const size_t packet_size = m_packet.size();
67ac7ddfbfSEd Maste const char *packet_cstr = m_packet.c_str();
68435933ddSDimitry Andric switch (m_packet[0]) {
691c3bbb01SEd Maste
701c3bbb01SEd Maste case '%':
711c3bbb01SEd Maste return eServerPacketType_notify;
721c3bbb01SEd Maste
73ac7ddfbfSEd Maste case '\x03':
74435933ddSDimitry Andric if (packet_size == 1)
75435933ddSDimitry Andric return eServerPacketType_interrupt;
76ac7ddfbfSEd Maste break;
77ac7ddfbfSEd Maste
78ac7ddfbfSEd Maste case '-':
79435933ddSDimitry Andric if (packet_size == 1)
80435933ddSDimitry Andric return eServerPacketType_nack;
81ac7ddfbfSEd Maste break;
82ac7ddfbfSEd Maste
83ac7ddfbfSEd Maste case '+':
84435933ddSDimitry Andric if (packet_size == 1)
85435933ddSDimitry Andric return eServerPacketType_ack;
86ac7ddfbfSEd Maste break;
87ac7ddfbfSEd Maste
88ac7ddfbfSEd Maste case 'A':
89ac7ddfbfSEd Maste return eServerPacketType_A;
90ac7ddfbfSEd Maste
91ac7ddfbfSEd Maste case 'Q':
9212b93ac6SEd Maste
93435933ddSDimitry Andric switch (packet_cstr[1]) {
94ac7ddfbfSEd Maste case 'E':
95435933ddSDimitry Andric if (PACKET_STARTS_WITH("QEnvironment:"))
96435933ddSDimitry Andric return eServerPacketType_QEnvironment;
97435933ddSDimitry Andric if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:"))
98435933ddSDimitry Andric return eServerPacketType_QEnvironmentHexEncoded;
99c4394386SDimitry Andric if (PACKET_STARTS_WITH("QEnableErrorStrings"))
100c4394386SDimitry Andric return eServerPacketType_QEnableErrorStrings;
101ac7ddfbfSEd Maste break;
102ac7ddfbfSEd Maste
103f678e45dSDimitry Andric case 'P':
104f678e45dSDimitry Andric if (PACKET_STARTS_WITH("QPassSignals:"))
105f678e45dSDimitry Andric return eServerPacketType_QPassSignals;
106acac075bSDimitry Andric break;
107f678e45dSDimitry Andric
108ac7ddfbfSEd Maste case 'S':
109435933ddSDimitry Andric if (PACKET_MATCHES("QStartNoAckMode"))
110435933ddSDimitry Andric return eServerPacketType_QStartNoAckMode;
111435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSaveRegisterState"))
112435933ddSDimitry Andric return eServerPacketType_QSaveRegisterState;
113435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetDisableASLR:"))
114435933ddSDimitry Andric return eServerPacketType_QSetDisableASLR;
115435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetDetachOnError:"))
116435933ddSDimitry Andric return eServerPacketType_QSetDetachOnError;
117435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetSTDIN:"))
118435933ddSDimitry Andric return eServerPacketType_QSetSTDIN;
119435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetSTDOUT:"))
120435933ddSDimitry Andric return eServerPacketType_QSetSTDOUT;
121435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetSTDERR:"))
122435933ddSDimitry Andric return eServerPacketType_QSetSTDERR;
123435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetWorkingDir:"))
124435933ddSDimitry Andric return eServerPacketType_QSetWorkingDir;
125435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetLogging:"))
126435933ddSDimitry Andric return eServerPacketType_QSetLogging;
127435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetMaxPacketSize:"))
128435933ddSDimitry Andric return eServerPacketType_QSetMaxPacketSize;
129435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetMaxPayloadSize:"))
130435933ddSDimitry Andric return eServerPacketType_QSetMaxPayloadSize;
131435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSetEnableAsyncProfiling;"))
132435933ddSDimitry Andric return eServerPacketType_QSetEnableAsyncProfiling;
133435933ddSDimitry Andric if (PACKET_STARTS_WITH("QSyncThreadState:"))
134435933ddSDimitry Andric return eServerPacketType_QSyncThreadState;
135ac7ddfbfSEd Maste break;
13612b93ac6SEd Maste
13735617911SEd Maste case 'L':
138435933ddSDimitry Andric if (PACKET_STARTS_WITH("QLaunchArch:"))
139435933ddSDimitry Andric return eServerPacketType_QLaunchArch;
140435933ddSDimitry Andric if (PACKET_MATCHES("QListThreadsInStopReply"))
141435933ddSDimitry Andric return eServerPacketType_QListThreadsInStopReply;
14212b93ac6SEd Maste break;
14312b93ac6SEd Maste
14412b93ac6SEd Maste case 'R':
145435933ddSDimitry Andric if (PACKET_STARTS_WITH("QRestoreRegisterState:"))
146435933ddSDimitry Andric return eServerPacketType_QRestoreRegisterState;
14712b93ac6SEd Maste break;
14812b93ac6SEd Maste
14912b93ac6SEd Maste case 'T':
150435933ddSDimitry Andric if (PACKET_MATCHES("QThreadSuffixSupported"))
151435933ddSDimitry Andric return eServerPacketType_QThreadSuffixSupported;
15235617911SEd Maste break;
153ac7ddfbfSEd Maste }
154ac7ddfbfSEd Maste break;
155ac7ddfbfSEd Maste
156ac7ddfbfSEd Maste case 'q':
157435933ddSDimitry Andric switch (packet_cstr[1]) {
158ac7ddfbfSEd Maste case 's':
159435933ddSDimitry Andric if (PACKET_MATCHES("qsProcessInfo"))
160435933ddSDimitry Andric return eServerPacketType_qsProcessInfo;
161435933ddSDimitry Andric if (PACKET_MATCHES("qsThreadInfo"))
162435933ddSDimitry Andric return eServerPacketType_qsThreadInfo;
163ac7ddfbfSEd Maste break;
164ac7ddfbfSEd Maste
165ac7ddfbfSEd Maste case 'f':
166435933ddSDimitry Andric if (PACKET_STARTS_WITH("qfProcessInfo"))
167435933ddSDimitry Andric return eServerPacketType_qfProcessInfo;
168435933ddSDimitry Andric if (PACKET_STARTS_WITH("qfThreadInfo"))
169435933ddSDimitry Andric return eServerPacketType_qfThreadInfo;
170ac7ddfbfSEd Maste break;
171ac7ddfbfSEd Maste
172ac7ddfbfSEd Maste case 'C':
173435933ddSDimitry Andric if (packet_size == 2)
174435933ddSDimitry Andric return eServerPacketType_qC;
175ac7ddfbfSEd Maste break;
176ac7ddfbfSEd Maste
1771c3bbb01SEd Maste case 'E':
178435933ddSDimitry Andric if (PACKET_STARTS_WITH("qEcho:"))
179435933ddSDimitry Andric return eServerPacketType_qEcho;
1801c3bbb01SEd Maste break;
1811c3bbb01SEd Maste
1821c3bbb01SEd Maste case 'F':
183435933ddSDimitry Andric if (PACKET_STARTS_WITH("qFileLoadAddress:"))
184435933ddSDimitry Andric return eServerPacketType_qFileLoadAddress;
1851c3bbb01SEd Maste break;
1861c3bbb01SEd Maste
187ac7ddfbfSEd Maste case 'G':
188435933ddSDimitry Andric if (PACKET_STARTS_WITH("qGroupName:"))
189435933ddSDimitry Andric return eServerPacketType_qGroupName;
190435933ddSDimitry Andric if (PACKET_MATCHES("qGetWorkingDir"))
191435933ddSDimitry Andric return eServerPacketType_qGetWorkingDir;
192435933ddSDimitry Andric if (PACKET_MATCHES("qGetPid"))
193435933ddSDimitry Andric return eServerPacketType_qGetPid;
194435933ddSDimitry Andric if (PACKET_STARTS_WITH("qGetProfileData;"))
195435933ddSDimitry Andric return eServerPacketType_qGetProfileData;
196435933ddSDimitry Andric if (PACKET_MATCHES("qGDBServerVersion"))
197435933ddSDimitry Andric return eServerPacketType_qGDBServerVersion;
198ac7ddfbfSEd Maste break;
199ac7ddfbfSEd Maste
200ac7ddfbfSEd Maste case 'H':
201435933ddSDimitry Andric if (PACKET_MATCHES("qHostInfo"))
202435933ddSDimitry Andric return eServerPacketType_qHostInfo;
203ac7ddfbfSEd Maste break;
204ac7ddfbfSEd Maste
20535617911SEd Maste case 'K':
206435933ddSDimitry Andric if (PACKET_STARTS_WITH("qKillSpawnedProcess"))
207435933ddSDimitry Andric return eServerPacketType_qKillSpawnedProcess;
20835617911SEd Maste break;
20935617911SEd Maste
210ac7ddfbfSEd Maste case 'L':
211435933ddSDimitry Andric if (PACKET_STARTS_WITH("qLaunchGDBServer"))
212435933ddSDimitry Andric return eServerPacketType_qLaunchGDBServer;
213435933ddSDimitry Andric if (PACKET_MATCHES("qLaunchSuccess"))
214435933ddSDimitry Andric return eServerPacketType_qLaunchSuccess;
215ac7ddfbfSEd Maste break;
216ac7ddfbfSEd Maste
21712b93ac6SEd Maste case 'M':
218435933ddSDimitry Andric if (PACKET_STARTS_WITH("qMemoryRegionInfo:"))
219435933ddSDimitry Andric return eServerPacketType_qMemoryRegionInfo;
220435933ddSDimitry Andric if (PACKET_MATCHES("qMemoryRegionInfo"))
221435933ddSDimitry Andric return eServerPacketType_qMemoryRegionInfoSupported;
222435933ddSDimitry Andric if (PACKET_STARTS_WITH("qModuleInfo:"))
223435933ddSDimitry Andric return eServerPacketType_qModuleInfo;
22412b93ac6SEd Maste break;
22512b93ac6SEd Maste
226ac7ddfbfSEd Maste case 'P':
227435933ddSDimitry Andric if (PACKET_STARTS_WITH("qProcessInfoPID:"))
228435933ddSDimitry Andric return eServerPacketType_qProcessInfoPID;
229435933ddSDimitry Andric if (PACKET_STARTS_WITH("qPlatform_shell:"))
230435933ddSDimitry Andric return eServerPacketType_qPlatform_shell;
231435933ddSDimitry Andric if (PACKET_STARTS_WITH("qPlatform_mkdir:"))
232435933ddSDimitry Andric return eServerPacketType_qPlatform_mkdir;
233435933ddSDimitry Andric if (PACKET_STARTS_WITH("qPlatform_chmod:"))
234435933ddSDimitry Andric return eServerPacketType_qPlatform_chmod;
235435933ddSDimitry Andric if (PACKET_MATCHES("qProcessInfo"))
236435933ddSDimitry Andric return eServerPacketType_qProcessInfo;
237ac7ddfbfSEd Maste break;
238ac7ddfbfSEd Maste
2399f2f44ceSEd Maste case 'Q':
240435933ddSDimitry Andric if (PACKET_MATCHES("qQueryGDBServer"))
241435933ddSDimitry Andric return eServerPacketType_qQueryGDBServer;
2429f2f44ceSEd Maste break;
2439f2f44ceSEd Maste
24412b93ac6SEd Maste case 'R':
245435933ddSDimitry Andric if (PACKET_STARTS_WITH("qRcmd,"))
246435933ddSDimitry Andric return eServerPacketType_qRcmd;
247435933ddSDimitry Andric if (PACKET_STARTS_WITH("qRegisterInfo"))
248435933ddSDimitry Andric return eServerPacketType_qRegisterInfo;
24912b93ac6SEd Maste break;
25035617911SEd Maste
251ac7ddfbfSEd Maste case 'S':
252435933ddSDimitry Andric if (PACKET_STARTS_WITH("qSpeedTest:"))
253435933ddSDimitry Andric return eServerPacketType_qSpeedTest;
254435933ddSDimitry Andric if (PACKET_MATCHES("qShlibInfoAddr"))
255435933ddSDimitry Andric return eServerPacketType_qShlibInfoAddr;
256435933ddSDimitry Andric if (PACKET_MATCHES("qStepPacketSupported"))
257435933ddSDimitry Andric return eServerPacketType_qStepPacketSupported;
258435933ddSDimitry Andric if (PACKET_STARTS_WITH("qSupported"))
259435933ddSDimitry Andric return eServerPacketType_qSupported;
260435933ddSDimitry Andric if (PACKET_MATCHES("qSyncThreadStateSupported"))
261435933ddSDimitry Andric return eServerPacketType_qSyncThreadStateSupported;
26212b93ac6SEd Maste break;
26312b93ac6SEd Maste
26412b93ac6SEd Maste case 'T':
265435933ddSDimitry Andric if (PACKET_STARTS_WITH("qThreadExtraInfo,"))
266435933ddSDimitry Andric return eServerPacketType_qThreadExtraInfo;
267435933ddSDimitry Andric if (PACKET_STARTS_WITH("qThreadStopInfo"))
268435933ddSDimitry Andric return eServerPacketType_qThreadStopInfo;
269ac7ddfbfSEd Maste break;
270ac7ddfbfSEd Maste
271ac7ddfbfSEd Maste case 'U':
272435933ddSDimitry Andric if (PACKET_STARTS_WITH("qUserName:"))
273435933ddSDimitry Andric return eServerPacketType_qUserName;
274ac7ddfbfSEd Maste break;
27512b93ac6SEd Maste
27612b93ac6SEd Maste case 'V':
277435933ddSDimitry Andric if (PACKET_MATCHES("qVAttachOrWaitSupported"))
278435933ddSDimitry Andric return eServerPacketType_qVAttachOrWaitSupported;
27912b93ac6SEd Maste break;
28012b93ac6SEd Maste
28112b93ac6SEd Maste case 'W':
282435933ddSDimitry Andric if (PACKET_STARTS_WITH("qWatchpointSupportInfo:"))
283435933ddSDimitry Andric return eServerPacketType_qWatchpointSupportInfo;
284435933ddSDimitry Andric if (PACKET_MATCHES("qWatchpointSupportInfo"))
285435933ddSDimitry Andric return eServerPacketType_qWatchpointSupportInfoSupported;
28612b93ac6SEd Maste break;
2870127ef0fSEd Maste
2880127ef0fSEd Maste case 'X':
289435933ddSDimitry Andric if (PACKET_STARTS_WITH("qXfer:auxv:read::"))
290435933ddSDimitry Andric return eServerPacketType_qXfer_auxv_read;
2910127ef0fSEd Maste break;
292ac7ddfbfSEd Maste }
293ac7ddfbfSEd Maste break;
294b91a7dfcSDimitry Andric
295b91a7dfcSDimitry Andric case 'j':
296435933ddSDimitry Andric if (PACKET_STARTS_WITH("jModulesInfo:"))
297435933ddSDimitry Andric return eServerPacketType_jModulesInfo;
298435933ddSDimitry Andric if (PACKET_MATCHES("jSignalsInfo"))
299435933ddSDimitry Andric return eServerPacketType_jSignalsInfo;
300435933ddSDimitry Andric if (PACKET_MATCHES("jThreadsInfo"))
301435933ddSDimitry Andric return eServerPacketType_jThreadsInfo;
302302affcbSDimitry Andric if (PACKET_STARTS_WITH("jTraceBufferRead:"))
303302affcbSDimitry Andric return eServerPacketType_jTraceBufferRead;
304302affcbSDimitry Andric if (PACKET_STARTS_WITH("jTraceConfigRead:"))
305302affcbSDimitry Andric return eServerPacketType_jTraceConfigRead;
306302affcbSDimitry Andric if (PACKET_STARTS_WITH("jTraceMetaRead:"))
307302affcbSDimitry Andric return eServerPacketType_jTraceMetaRead;
308302affcbSDimitry Andric if (PACKET_STARTS_WITH("jTraceStart:"))
309302affcbSDimitry Andric return eServerPacketType_jTraceStart;
310302affcbSDimitry Andric if (PACKET_STARTS_WITH("jTraceStop:"))
311302affcbSDimitry Andric return eServerPacketType_jTraceStop;
3124bb0738eSEd Maste break;
313b91a7dfcSDimitry Andric
31435617911SEd Maste case 'v':
315435933ddSDimitry Andric if (PACKET_STARTS_WITH("vFile:")) {
316435933ddSDimitry Andric if (PACKET_STARTS_WITH("vFile:open:"))
317435933ddSDimitry Andric return eServerPacketType_vFile_open;
318435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:close:"))
319435933ddSDimitry Andric return eServerPacketType_vFile_close;
320435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:pread"))
321435933ddSDimitry Andric return eServerPacketType_vFile_pread;
322435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:pwrite"))
323435933ddSDimitry Andric return eServerPacketType_vFile_pwrite;
324435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:size"))
325435933ddSDimitry Andric return eServerPacketType_vFile_size;
326435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:exists"))
327435933ddSDimitry Andric return eServerPacketType_vFile_exists;
328435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:stat"))
329435933ddSDimitry Andric return eServerPacketType_vFile_stat;
330435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:mode"))
331435933ddSDimitry Andric return eServerPacketType_vFile_mode;
332435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:MD5"))
333435933ddSDimitry Andric return eServerPacketType_vFile_md5;
334435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:symlink"))
335435933ddSDimitry Andric return eServerPacketType_vFile_symlink;
336435933ddSDimitry Andric else if (PACKET_STARTS_WITH("vFile:unlink"))
337435933ddSDimitry Andric return eServerPacketType_vFile_unlink;
33835617911SEd Maste
33912b93ac6SEd Maste } else {
340435933ddSDimitry Andric if (PACKET_STARTS_WITH("vAttach;"))
341435933ddSDimitry Andric return eServerPacketType_vAttach;
342435933ddSDimitry Andric if (PACKET_STARTS_WITH("vAttachWait;"))
343435933ddSDimitry Andric return eServerPacketType_vAttachWait;
344435933ddSDimitry Andric if (PACKET_STARTS_WITH("vAttachOrWait;"))
345435933ddSDimitry Andric return eServerPacketType_vAttachOrWait;
346435933ddSDimitry Andric if (PACKET_STARTS_WITH("vAttachName;"))
347435933ddSDimitry Andric return eServerPacketType_vAttachName;
348435933ddSDimitry Andric if (PACKET_STARTS_WITH("vCont;"))
349435933ddSDimitry Andric return eServerPacketType_vCont;
350435933ddSDimitry Andric if (PACKET_MATCHES("vCont?"))
351435933ddSDimitry Andric return eServerPacketType_vCont_actions;
35235617911SEd Maste }
35335617911SEd Maste break;
35412b93ac6SEd Maste case '_':
355435933ddSDimitry Andric switch (packet_cstr[1]) {
35612b93ac6SEd Maste case 'M':
35712b93ac6SEd Maste return eServerPacketType__M;
35812b93ac6SEd Maste
35912b93ac6SEd Maste case 'm':
36012b93ac6SEd Maste return eServerPacketType__m;
36112b93ac6SEd Maste }
36212b93ac6SEd Maste break;
36312b93ac6SEd Maste
36412b93ac6SEd Maste case '?':
365435933ddSDimitry Andric if (packet_size == 1)
366435933ddSDimitry Andric return eServerPacketType_stop_reason;
36712b93ac6SEd Maste break;
36812b93ac6SEd Maste
36912b93ac6SEd Maste case 'c':
37012b93ac6SEd Maste return eServerPacketType_c;
37112b93ac6SEd Maste
37212b93ac6SEd Maste case 'C':
37312b93ac6SEd Maste return eServerPacketType_C;
37412b93ac6SEd Maste
37512b93ac6SEd Maste case 'D':
376435933ddSDimitry Andric if (packet_size == 1)
377435933ddSDimitry Andric return eServerPacketType_D;
37812b93ac6SEd Maste break;
37912b93ac6SEd Maste
38012b93ac6SEd Maste case 'g':
381435933ddSDimitry Andric if (packet_size == 1)
382435933ddSDimitry Andric return eServerPacketType_g;
38312b93ac6SEd Maste break;
38412b93ac6SEd Maste
38512b93ac6SEd Maste case 'G':
38612b93ac6SEd Maste return eServerPacketType_G;
38712b93ac6SEd Maste
38812b93ac6SEd Maste case 'H':
38912b93ac6SEd Maste return eServerPacketType_H;
39012b93ac6SEd Maste
3911c3bbb01SEd Maste case 'I':
3921c3bbb01SEd Maste return eServerPacketType_I;
3931c3bbb01SEd Maste
39412b93ac6SEd Maste case 'k':
395435933ddSDimitry Andric if (packet_size == 1)
396435933ddSDimitry Andric return eServerPacketType_k;
39712b93ac6SEd Maste break;
39812b93ac6SEd Maste
39912b93ac6SEd Maste case 'm':
40012b93ac6SEd Maste return eServerPacketType_m;
40112b93ac6SEd Maste
40212b93ac6SEd Maste case 'M':
40312b93ac6SEd Maste return eServerPacketType_M;
40412b93ac6SEd Maste
40512b93ac6SEd Maste case 'p':
40612b93ac6SEd Maste return eServerPacketType_p;
40712b93ac6SEd Maste
40812b93ac6SEd Maste case 'P':
40912b93ac6SEd Maste return eServerPacketType_P;
41012b93ac6SEd Maste
41112b93ac6SEd Maste case 's':
412435933ddSDimitry Andric if (packet_size == 1)
413435933ddSDimitry Andric return eServerPacketType_s;
41412b93ac6SEd Maste break;
41512b93ac6SEd Maste
41612b93ac6SEd Maste case 'S':
41712b93ac6SEd Maste return eServerPacketType_S;
41812b93ac6SEd Maste
4199f2f44ceSEd Maste case 'x':
4209f2f44ceSEd Maste return eServerPacketType_x;
4219f2f44ceSEd Maste
4229f2f44ceSEd Maste case 'X':
4239f2f44ceSEd Maste return eServerPacketType_X;
4249f2f44ceSEd Maste
42512b93ac6SEd Maste case 'T':
42612b93ac6SEd Maste return eServerPacketType_T;
42712b93ac6SEd Maste
42812b93ac6SEd Maste case 'z':
42912b93ac6SEd Maste if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
43012b93ac6SEd Maste return eServerPacketType_z;
43112b93ac6SEd Maste break;
43212b93ac6SEd Maste
43312b93ac6SEd Maste case 'Z':
43412b93ac6SEd Maste if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
43512b93ac6SEd Maste return eServerPacketType_Z;
43612b93ac6SEd Maste break;
437ac7ddfbfSEd Maste }
438ac7ddfbfSEd Maste return eServerPacketType_unimplemented;
439ac7ddfbfSEd Maste }
440ac7ddfbfSEd Maste
IsOKResponse() const441435933ddSDimitry Andric bool StringExtractorGDBRemote::IsOKResponse() const {
442ac7ddfbfSEd Maste return GetResponseType() == eOK;
443ac7ddfbfSEd Maste }
444ac7ddfbfSEd Maste
IsUnsupportedResponse() const445435933ddSDimitry Andric bool StringExtractorGDBRemote::IsUnsupportedResponse() const {
446ac7ddfbfSEd Maste return GetResponseType() == eUnsupported;
447ac7ddfbfSEd Maste }
448ac7ddfbfSEd Maste
IsNormalResponse() const449435933ddSDimitry Andric bool StringExtractorGDBRemote::IsNormalResponse() const {
450ac7ddfbfSEd Maste return GetResponseType() == eResponse;
451ac7ddfbfSEd Maste }
452ac7ddfbfSEd Maste
IsErrorResponse() const453435933ddSDimitry Andric bool StringExtractorGDBRemote::IsErrorResponse() const {
454c4394386SDimitry Andric return GetResponseType() == eError && isxdigit(m_packet[1]) &&
455c4394386SDimitry Andric isxdigit(m_packet[2]);
456ac7ddfbfSEd Maste }
457ac7ddfbfSEd Maste
GetError()458435933ddSDimitry Andric uint8_t StringExtractorGDBRemote::GetError() {
459435933ddSDimitry Andric if (GetResponseType() == eError) {
460ac7ddfbfSEd Maste SetFilePos(1);
461ac7ddfbfSEd Maste return GetHexU8(255);
462ac7ddfbfSEd Maste }
463ac7ddfbfSEd Maste return 0;
464ac7ddfbfSEd Maste }
46535617911SEd Maste
GetStatus()466c4394386SDimitry Andric lldb_private::Status StringExtractorGDBRemote::GetStatus() {
467c4394386SDimitry Andric lldb_private::Status error;
468c4394386SDimitry Andric if (GetResponseType() == eError) {
469c4394386SDimitry Andric SetFilePos(1);
470c4394386SDimitry Andric uint8_t errc = GetHexU8(255);
471c4394386SDimitry Andric error.SetError(errc, lldb::eErrorTypeGeneric);
472c4394386SDimitry Andric
473c4394386SDimitry Andric error.SetErrorStringWithFormat("Error %u", errc);
474c4394386SDimitry Andric std::string error_messg;
475c4394386SDimitry Andric if (GetChar() == ';') {
476c4394386SDimitry Andric GetHexByteString(error_messg);
477c4394386SDimitry Andric error.SetErrorString(error_messg);
478c4394386SDimitry Andric }
479c4394386SDimitry Andric }
480c4394386SDimitry Andric return error;
481c4394386SDimitry Andric }
482c4394386SDimitry Andric
GetEscapedBinaryData(std::string & str)483435933ddSDimitry Andric size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
484435933ddSDimitry Andric // Just get the data bytes in the string as
4854ba319b5SDimitry Andric // GDBRemoteCommunication::CheckForPacket() already removes any 0x7d escaped
4864ba319b5SDimitry Andric // characters. If any 0x7d characters are left in the packet, then they are
4874ba319b5SDimitry Andric // supposed to be there...
48835617911SEd Maste str.clear();
4897aa51b79SEd Maste const size_t bytes_left = GetBytesLeft();
490435933ddSDimitry Andric if (bytes_left > 0) {
4917aa51b79SEd Maste str.assign(m_packet, m_index, bytes_left);
4927aa51b79SEd Maste m_index += bytes_left;
49335617911SEd Maste }
49435617911SEd Maste return str.size();
49535617911SEd Maste }
49635617911SEd Maste
4974bb0738eSEd Maste static bool
OKErrorNotSupportedResponseValidator(void *,const StringExtractorGDBRemote & response)498435933ddSDimitry Andric OKErrorNotSupportedResponseValidator(void *,
499435933ddSDimitry Andric const StringExtractorGDBRemote &response) {
500435933ddSDimitry Andric switch (response.GetResponseType()) {
5014bb0738eSEd Maste case StringExtractorGDBRemote::eOK:
5024bb0738eSEd Maste case StringExtractorGDBRemote::eError:
5034bb0738eSEd Maste case StringExtractorGDBRemote::eUnsupported:
5044bb0738eSEd Maste return true;
5054bb0738eSEd Maste
5064bb0738eSEd Maste case StringExtractorGDBRemote::eAck:
5074bb0738eSEd Maste case StringExtractorGDBRemote::eNack:
5084bb0738eSEd Maste case StringExtractorGDBRemote::eResponse:
5094bb0738eSEd Maste break;
5104bb0738eSEd Maste }
5114bb0738eSEd Maste return false;
5124bb0738eSEd Maste }
5134bb0738eSEd Maste
JSONResponseValidator(void *,const StringExtractorGDBRemote & response)514435933ddSDimitry Andric static bool JSONResponseValidator(void *,
515435933ddSDimitry Andric const StringExtractorGDBRemote &response) {
516435933ddSDimitry Andric switch (response.GetResponseType()) {
5174bb0738eSEd Maste case StringExtractorGDBRemote::eUnsupported:
5184bb0738eSEd Maste case StringExtractorGDBRemote::eError:
5194bb0738eSEd Maste return true; // Accept unsupported or EXX as valid responses
5204bb0738eSEd Maste
5214bb0738eSEd Maste case StringExtractorGDBRemote::eOK:
5224bb0738eSEd Maste case StringExtractorGDBRemote::eAck:
5234bb0738eSEd Maste case StringExtractorGDBRemote::eNack:
5244bb0738eSEd Maste break;
5254bb0738eSEd Maste
5264bb0738eSEd Maste case StringExtractorGDBRemote::eResponse:
5274bb0738eSEd Maste // JSON that is returned in from JSON query packets is currently always
5284ba319b5SDimitry Andric // either a dictionary which starts with a '{', or an array which starts
5294ba319b5SDimitry Andric // with a '['. This is a quick validator to just make sure the response
5304ba319b5SDimitry Andric // could be valid JSON without having to validate all of the
5314bb0738eSEd Maste // JSON content.
532435933ddSDimitry Andric switch (response.GetStringRef()[0]) {
533435933ddSDimitry Andric case '{':
534435933ddSDimitry Andric return true;
535435933ddSDimitry Andric case '[':
536435933ddSDimitry Andric return true;
5374bb0738eSEd Maste default:
5384bb0738eSEd Maste break;
5394bb0738eSEd Maste }
5404bb0738eSEd Maste break;
5414bb0738eSEd Maste }
5424bb0738eSEd Maste return false;
5434bb0738eSEd Maste }
5444bb0738eSEd Maste
5454bb0738eSEd Maste static bool
ASCIIHexBytesResponseValidator(void *,const StringExtractorGDBRemote & response)546435933ddSDimitry Andric ASCIIHexBytesResponseValidator(void *,
547435933ddSDimitry Andric const StringExtractorGDBRemote &response) {
548435933ddSDimitry Andric switch (response.GetResponseType()) {
5494bb0738eSEd Maste case StringExtractorGDBRemote::eUnsupported:
5504bb0738eSEd Maste case StringExtractorGDBRemote::eError:
5514bb0738eSEd Maste return true; // Accept unsupported or EXX as valid responses
5524bb0738eSEd Maste
5534bb0738eSEd Maste case StringExtractorGDBRemote::eOK:
5544bb0738eSEd Maste case StringExtractorGDBRemote::eAck:
5554bb0738eSEd Maste case StringExtractorGDBRemote::eNack:
5564bb0738eSEd Maste break;
5574bb0738eSEd Maste
558435933ddSDimitry Andric case StringExtractorGDBRemote::eResponse: {
5594bb0738eSEd Maste uint32_t valid_count = 0;
560435933ddSDimitry Andric for (const char ch : response.GetStringRef()) {
561435933ddSDimitry Andric if (!isxdigit(ch)) {
5624bb0738eSEd Maste return false;
5634bb0738eSEd Maste }
5644bb0738eSEd Maste if (++valid_count >= 16)
565435933ddSDimitry Andric break; // Don't validate all the characters in case the packet is very
566435933ddSDimitry Andric // large
5674bb0738eSEd Maste }
5684bb0738eSEd Maste return true;
569435933ddSDimitry Andric } break;
5704bb0738eSEd Maste }
5714bb0738eSEd Maste return false;
5724bb0738eSEd Maste }
5734bb0738eSEd Maste
CopyResponseValidator(const StringExtractorGDBRemote & rhs)574435933ddSDimitry Andric void StringExtractorGDBRemote::CopyResponseValidator(
575435933ddSDimitry Andric const StringExtractorGDBRemote &rhs) {
5764bb0738eSEd Maste m_validator = rhs.m_validator;
5774bb0738eSEd Maste m_validator_baton = rhs.m_validator_baton;
5784bb0738eSEd Maste }
5794bb0738eSEd Maste
SetResponseValidator(ResponseValidatorCallback callback,void * baton)580435933ddSDimitry Andric void StringExtractorGDBRemote::SetResponseValidator(
581435933ddSDimitry Andric ResponseValidatorCallback callback, void *baton) {
5824bb0738eSEd Maste m_validator = callback;
5834bb0738eSEd Maste m_validator_baton = baton;
5844bb0738eSEd Maste }
5854bb0738eSEd Maste
SetResponseValidatorToOKErrorNotSupported()586435933ddSDimitry Andric void StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() {
5874bb0738eSEd Maste m_validator = OKErrorNotSupportedResponseValidator;
5884bb0738eSEd Maste m_validator_baton = nullptr;
5894bb0738eSEd Maste }
5904bb0738eSEd Maste
SetResponseValidatorToASCIIHexBytes()591435933ddSDimitry Andric void StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() {
5924bb0738eSEd Maste m_validator = ASCIIHexBytesResponseValidator;
5934bb0738eSEd Maste m_validator_baton = nullptr;
5944bb0738eSEd Maste }
5954bb0738eSEd Maste
SetResponseValidatorToJSON()596435933ddSDimitry Andric void StringExtractorGDBRemote::SetResponseValidatorToJSON() {
5974bb0738eSEd Maste m_validator = JSONResponseValidator;
5984bb0738eSEd Maste m_validator_baton = nullptr;
5994bb0738eSEd Maste }
6004bb0738eSEd Maste
ValidateResponse() const601435933ddSDimitry Andric bool StringExtractorGDBRemote::ValidateResponse() const {
6024bb0738eSEd Maste // If we have a validator callback, try to validate the callback
6034bb0738eSEd Maste if (m_validator)
6044bb0738eSEd Maste return m_validator(m_validator_baton, *this);
6054bb0738eSEd Maste else
6064bb0738eSEd Maste return true; // No validator, so response is valid
6074bb0738eSEd Maste }
608