]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Utility / StringExtractorGDBRemote.cpp
1 //===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 #include <string.h>
12
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "Utility/StringExtractorGDBRemote.h"
17
18
19
20 StringExtractorGDBRemote::ResponseType
21 StringExtractorGDBRemote::GetResponseType () const
22 {
23     if (m_packet.empty())
24         return eUnsupported;
25
26     switch (m_packet[0])
27     {
28     case 'E':
29         if (m_packet.size() == 3 &&
30             isxdigit(m_packet[1]) &&
31             isxdigit(m_packet[2]))
32             return eError;
33         break;
34
35     case 'O':
36         if (m_packet.size() == 2 && m_packet[1] == 'K')
37             return eOK;
38         break;
39
40     case '+':
41         if (m_packet.size() == 1)
42             return eAck;
43         break;
44
45     case '-':
46         if (m_packet.size() == 1)
47             return eNack;
48         break;
49     }
50     return eResponse;
51 }
52
53 StringExtractorGDBRemote::ServerPacketType
54 StringExtractorGDBRemote::GetServerPacketType () const
55 {
56 #define PACKET_MATCHES(s) ((packet_size == (sizeof(s)-1)) && (strcmp((packet_cstr),(s)) == 0))
57 #define PACKET_STARTS_WITH(s) ((packet_size >= (sizeof(s)-1)) && ::strncmp(packet_cstr, s, (sizeof(s)-1))==0)
58     
59     // Empty is not a supported packet...
60     if (m_packet.empty())
61         return eServerPacketType_invalid;
62
63     const size_t packet_size = m_packet.size();
64     const char *packet_cstr = m_packet.c_str();
65     switch (m_packet[0])
66     {
67     case '\x03':
68         if (packet_size == 1) return eServerPacketType_interrupt;
69         break;
70
71     case '-':
72         if (packet_size == 1) return eServerPacketType_nack;
73         break;
74
75     case '+':
76         if (packet_size == 1) return eServerPacketType_ack;
77         break;
78
79     case 'A':
80         return eServerPacketType_A;
81             
82     case 'Q':
83
84         switch (packet_cstr[1])
85         {
86         case 'E':
87             if (PACKET_STARTS_WITH ("QEnvironment:"))           return eServerPacketType_QEnvironment;
88             if (PACKET_STARTS_WITH ("QEnvironmentHexEncoded:")) return eServerPacketType_QEnvironmentHexEncoded;
89             break;
90
91         case 'S':
92             if (PACKET_MATCHES ("QStartNoAckMode"))               return eServerPacketType_QStartNoAckMode;
93             if (PACKET_STARTS_WITH ("QSaveRegisterState"))        return eServerPacketType_QSaveRegisterState;
94             if (PACKET_STARTS_WITH ("QSetDisableASLR:"))          return eServerPacketType_QSetDisableASLR;
95             if (PACKET_STARTS_WITH ("QSetSTDIN:"))                return eServerPacketType_QSetSTDIN;
96             if (PACKET_STARTS_WITH ("QSetSTDOUT:"))               return eServerPacketType_QSetSTDOUT;
97             if (PACKET_STARTS_WITH ("QSetSTDERR:"))               return eServerPacketType_QSetSTDERR;
98             if (PACKET_STARTS_WITH ("QSetWorkingDir:"))           return eServerPacketType_QSetWorkingDir;
99             if (PACKET_STARTS_WITH ("QSetLogging:"))              return eServerPacketType_QSetLogging;
100             if (PACKET_STARTS_WITH ("QSetMaxPacketSize:"))        return eServerPacketType_QSetMaxPacketSize;
101             if (PACKET_STARTS_WITH ("QSetMaxPayloadSize:"))       return eServerPacketType_QSetMaxPayloadSize;
102             if (PACKET_STARTS_WITH ("QSetEnableAsyncProfiling;")) return eServerPacketType_QSetEnableAsyncProfiling;
103             if (PACKET_STARTS_WITH ("QSyncThreadState:"))         return eServerPacketType_QSyncThreadState;
104             break;
105
106         case 'L':
107             if (PACKET_STARTS_WITH ("QLaunchArch:"))              return eServerPacketType_QLaunchArch;
108             if (PACKET_MATCHES("QListThreadsInStopReply"))        return eServerPacketType_QListThreadsInStopReply;
109             break;
110
111         case 'R':
112             if (PACKET_STARTS_WITH ("QRestoreRegisterState:"))    return eServerPacketType_QRestoreRegisterState;
113             break;
114
115         case 'T':
116             if (PACKET_MATCHES ("QThreadSuffixSupported"))        return eServerPacketType_QThreadSuffixSupported;
117             break;
118         }
119         break;
120             
121     case 'q':
122         switch (packet_cstr[1])
123         {
124         case 's':
125             if (PACKET_MATCHES ("qsProcessInfo"))               return eServerPacketType_qsProcessInfo;
126             if (PACKET_MATCHES ("qsThreadInfo"))                return eServerPacketType_qsThreadInfo;
127             break;
128
129         case 'f':
130             if (PACKET_STARTS_WITH ("qfProcessInfo"))           return eServerPacketType_qfProcessInfo;
131             if (PACKET_STARTS_WITH ("qfThreadInfo"))            return eServerPacketType_qfThreadInfo;
132             break;
133
134         case 'C':
135             if (packet_size == 2)                               return eServerPacketType_qC;
136             break;
137
138         case 'G':
139             if (PACKET_STARTS_WITH ("qGroupName:"))             return eServerPacketType_qGroupName;
140             if (PACKET_MATCHES ("qGetWorkingDir"))              return eServerPacketType_qGetWorkingDir;
141             if (PACKET_MATCHES ("qGetPid"))                     return eServerPacketType_qGetPid;
142             if (PACKET_STARTS_WITH ("qGetProfileData;"))        return eServerPacketType_qGetProfileData;
143             if (PACKET_MATCHES ("qGDBServerVersion"))           return eServerPacketType_qGDBServerVersion;
144             break;
145
146         case 'H':
147             if (PACKET_MATCHES ("qHostInfo"))                   return eServerPacketType_qHostInfo;
148             break;
149
150         case 'K':
151             if (PACKET_STARTS_WITH ("qKillSpawnedProcess"))     return eServerPacketType_qKillSpawnedProcess;
152             break;
153         
154         case 'L':
155             if (PACKET_STARTS_WITH ("qLaunchGDBServer"))        return eServerPacketType_qLaunchGDBServer;
156             if (PACKET_MATCHES ("qLaunchSuccess"))              return eServerPacketType_qLaunchSuccess;
157             break;
158             
159         case 'M':
160             if (PACKET_STARTS_WITH ("qMemoryRegionInfo:"))      return eServerPacketType_qMemoryRegionInfo;
161             if (PACKET_MATCHES ("qMemoryRegionInfo"))           return eServerPacketType_qMemoryRegionInfoSupported;
162             break;
163
164         case 'P':
165             if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
166             if (PACKET_STARTS_WITH ("qPlatform_shell:"))        return eServerPacketType_qPlatform_shell;
167             if (PACKET_STARTS_WITH ("qPlatform_mkdir:"))        return eServerPacketType_qPlatform_mkdir;
168             if (PACKET_STARTS_WITH ("qPlatform_chmod:"))        return eServerPacketType_qPlatform_chmod;
169             if (PACKET_MATCHES ("qProcessInfo"))                return eServerPacketType_qProcessInfo;
170             break;
171                 
172         case 'R':
173             if (PACKET_STARTS_WITH ("qRcmd,"))                  return eServerPacketType_qRcmd;
174             if (PACKET_STARTS_WITH ("qRegisterInfo"))           return eServerPacketType_qRegisterInfo;
175             break;
176
177         case 'S':
178             if (PACKET_STARTS_WITH ("qSpeedTest:"))             return eServerPacketType_qSpeedTest;
179             if (PACKET_MATCHES ("qShlibInfoAddr"))              return eServerPacketType_qShlibInfoAddr;
180             if (PACKET_MATCHES ("qStepPacketSupported"))        return eServerPacketType_qStepPacketSupported;
181             if (PACKET_MATCHES ("qSyncThreadStateSupported"))   return eServerPacketType_qSyncThreadStateSupported;
182             break;
183
184         case 'T':
185             if (PACKET_STARTS_WITH ("qThreadExtraInfo,"))       return eServerPacketType_qThreadExtraInfo;
186             if (PACKET_STARTS_WITH ("qThreadStopInfo"))         return eServerPacketType_qThreadStopInfo;
187             break;
188
189         case 'U':
190             if (PACKET_STARTS_WITH ("qUserName:"))              return eServerPacketType_qUserName;
191             break;
192
193         case 'V':
194             if (PACKET_MATCHES ("qVAttachOrWaitSupported"))     return eServerPacketType_qVAttachOrWaitSupported;
195             break;
196
197         case 'W':
198             if (PACKET_STARTS_WITH ("qWatchpointSupportInfo:")) return eServerPacketType_qWatchpointSupportInfo;
199             if (PACKET_MATCHES ("qWatchpointSupportInfo"))      return eServerPacketType_qWatchpointSupportInfoSupported;
200             break;
201         }
202         break;
203     case 'v':
204             if (PACKET_STARTS_WITH("vFile:"))
205             {
206                 if (PACKET_STARTS_WITH("vFile:open:"))          return eServerPacketType_vFile_open;
207                 else if (PACKET_STARTS_WITH("vFile:close:"))    return eServerPacketType_vFile_close;
208                 else if (PACKET_STARTS_WITH("vFile:pread"))     return eServerPacketType_vFile_pread;
209                 else if (PACKET_STARTS_WITH("vFile:pwrite"))    return eServerPacketType_vFile_pwrite;
210                 else if (PACKET_STARTS_WITH("vFile:size"))      return eServerPacketType_vFile_size;
211                 else if (PACKET_STARTS_WITH("vFile:exists"))    return eServerPacketType_vFile_exists;
212                 else if (PACKET_STARTS_WITH("vFile:stat"))      return eServerPacketType_vFile_stat;
213                 else if (PACKET_STARTS_WITH("vFile:mode"))      return eServerPacketType_vFile_mode;
214                 else if (PACKET_STARTS_WITH("vFile:MD5"))       return eServerPacketType_vFile_md5;
215                 else if (PACKET_STARTS_WITH("vFile:symlink"))   return eServerPacketType_vFile_symlink;
216                 else if (PACKET_STARTS_WITH("vFile:unlink"))    return eServerPacketType_vFile_unlink;
217
218             } else {
219               if (PACKET_STARTS_WITH ("vAttach;"))              return eServerPacketType_vAttach;
220               if (PACKET_STARTS_WITH ("vAttachWait;"))          return eServerPacketType_vAttachWait;
221               if (PACKET_STARTS_WITH ("vAttachOrWait;"))        return eServerPacketType_vAttachOrWait;
222               if (PACKET_STARTS_WITH ("vAttachName;"))          return eServerPacketType_vAttachName;
223               if (PACKET_STARTS_WITH("vCont;"))                 return eServerPacketType_vCont;
224               if (PACKET_MATCHES ("vCont?"))                    return eServerPacketType_vCont_actions;
225             }
226             break;
227       case '_':
228         switch (packet_cstr[1])
229         {
230         case 'M':
231             return eServerPacketType__M;
232
233         case 'm':
234             return eServerPacketType__m;
235         }
236         break;
237
238       case '?':
239         if (packet_size == 1) return eServerPacketType_stop_reason;
240         break;
241
242       case 'c':
243         return eServerPacketType_c;
244
245       case 'C':
246         return eServerPacketType_C;
247
248       case 'D':
249         if (packet_size == 1) return eServerPacketType_D;
250         break;
251
252       case 'g':
253         if (packet_size == 1) return eServerPacketType_g;
254         break;
255
256       case 'G':
257         return eServerPacketType_G;
258
259       case 'H':
260         return eServerPacketType_H;
261
262       case 'k':
263         if (packet_size == 1) return eServerPacketType_k;
264         break;
265
266       case 'm':
267         return eServerPacketType_m;
268
269       case 'M':
270         return eServerPacketType_M;
271
272       case 'p':
273         return eServerPacketType_p;
274
275       case 'P':
276         return eServerPacketType_P;
277
278       case 's':
279         if (packet_size == 1) return eServerPacketType_s;
280         break;
281
282       case 'S':
283         return eServerPacketType_S;
284
285       case 'T':
286         return eServerPacketType_T;
287
288       case 'z':
289         if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
290           return eServerPacketType_z;
291         break;
292
293       case 'Z':
294         if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4')
295           return eServerPacketType_Z;
296         break;
297     }
298     return eServerPacketType_unimplemented;
299 }
300
301 bool
302 StringExtractorGDBRemote::IsOKResponse() const
303 {
304     return GetResponseType () == eOK;
305 }
306
307
308 bool
309 StringExtractorGDBRemote::IsUnsupportedResponse() const
310 {
311     return GetResponseType () == eUnsupported;
312 }
313
314 bool
315 StringExtractorGDBRemote::IsNormalResponse() const
316 {
317     return GetResponseType () == eResponse;
318 }
319
320 bool
321 StringExtractorGDBRemote::IsErrorResponse() const
322 {
323     return GetResponseType () == eError &&
324            m_packet.size() == 3 &&
325            isxdigit(m_packet[1]) &&
326            isxdigit(m_packet[2]);
327 }
328
329 uint8_t
330 StringExtractorGDBRemote::GetError ()
331 {
332     if (GetResponseType() == eError)
333     {
334         SetFilePos(1);
335         return GetHexU8(255);
336     }
337     return 0;
338 }
339
340 size_t
341 StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)
342 {
343     str.clear();
344     char ch;
345     while (GetBytesLeft())
346     {
347         ch = GetChar();
348         if (ch == 0x7d)
349             ch = (GetChar() ^ 0x20);
350         str.append(1,ch);
351     }
352     return str.size();
353 }
354