130fdc8d8SChris Lattner //===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner // C Includes
11ad65c051SStephen Wilson #include <string.h>
12ad65c051SStephen Wilson 
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
16ad65c051SStephen Wilson #include "Utility/StringExtractorGDBRemote.h"
1730fdc8d8SChris Lattner 
1830fdc8d8SChris Lattner 
1930fdc8d8SChris Lattner 
20576d8834SGreg Clayton StringExtractorGDBRemote::ResponseType
21576d8834SGreg Clayton StringExtractorGDBRemote::GetResponseType () const
2230fdc8d8SChris Lattner {
2330fdc8d8SChris Lattner     if (m_packet.empty())
2430fdc8d8SChris Lattner         return eUnsupported;
2530fdc8d8SChris Lattner 
2630fdc8d8SChris Lattner     switch (m_packet[0])
2730fdc8d8SChris Lattner     {
2830fdc8d8SChris Lattner     case 'E':
2930fdc8d8SChris Lattner         if (m_packet.size() == 3 &&
3030fdc8d8SChris Lattner             isxdigit(m_packet[1]) &&
3130fdc8d8SChris Lattner             isxdigit(m_packet[2]))
3230fdc8d8SChris Lattner             return eError;
3330fdc8d8SChris Lattner         break;
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner     case 'O':
3630fdc8d8SChris Lattner         if (m_packet.size() == 2 && m_packet[1] == 'K')
3730fdc8d8SChris Lattner             return eOK;
3830fdc8d8SChris Lattner         break;
3930fdc8d8SChris Lattner 
4030fdc8d8SChris Lattner     case '+':
4130fdc8d8SChris Lattner         if (m_packet.size() == 1)
4230fdc8d8SChris Lattner             return eAck;
4330fdc8d8SChris Lattner         break;
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner     case '-':
4630fdc8d8SChris Lattner         if (m_packet.size() == 1)
4730fdc8d8SChris Lattner             return eNack;
4830fdc8d8SChris Lattner         break;
4930fdc8d8SChris Lattner     }
5030fdc8d8SChris Lattner     return eResponse;
5130fdc8d8SChris Lattner }
5230fdc8d8SChris Lattner 
53576d8834SGreg Clayton StringExtractorGDBRemote::ServerPacketType
54576d8834SGreg Clayton StringExtractorGDBRemote::GetServerPacketType () const
5530fdc8d8SChris Lattner {
568b82f087SGreg Clayton #define PACKET_MATCHES(s) ((packet_size == (sizeof(s)-1)) && (strcmp((packet_cstr),(s)) == 0))
578b82f087SGreg Clayton #define PACKET_STARTS_WITH(s) ((packet_size >= (sizeof(s)-1)) && ::strncmp(packet_cstr, s, (sizeof(s)-1))==0)
588b82f087SGreg Clayton 
59576d8834SGreg Clayton     // Empty is not a supported packet...
60576d8834SGreg Clayton     if (m_packet.empty())
61576d8834SGreg Clayton         return eServerPacketType_invalid;
62576d8834SGreg Clayton 
638b82f087SGreg Clayton     const size_t packet_size = m_packet.size();
64576d8834SGreg Clayton     const char *packet_cstr = m_packet.c_str();
65576d8834SGreg Clayton     switch (m_packet[0])
66576d8834SGreg Clayton     {
67d314e810SGreg Clayton     case '\x03':
688b82f087SGreg Clayton         if (packet_size == 1) return eServerPacketType_interrupt;
69d314e810SGreg Clayton         break;
70d314e810SGreg Clayton 
71576d8834SGreg Clayton     case '-':
728b82f087SGreg Clayton         if (packet_size == 1) return eServerPacketType_nack;
73576d8834SGreg Clayton         break;
74576d8834SGreg Clayton 
75576d8834SGreg Clayton     case '+':
768b82f087SGreg Clayton         if (packet_size == 1) return eServerPacketType_ack;
77576d8834SGreg Clayton         break;
78576d8834SGreg Clayton 
798b82f087SGreg Clayton     case 'A':
808b82f087SGreg Clayton         return eServerPacketType_A;
818b82f087SGreg Clayton 
821cb6496eSGreg Clayton     case 'Q':
838b82f087SGreg Clayton         switch (packet_cstr[1])
848b82f087SGreg Clayton         {
858b82f087SGreg Clayton         case 'E':
868b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("QEnvironment:"))           return eServerPacketType_QEnvironment;
878b82f087SGreg Clayton             break;
888b82f087SGreg Clayton 
898b82f087SGreg Clayton         case 'S':
908b82f087SGreg Clayton             if (PACKET_MATCHES ("QStartNoAckMode"))             return eServerPacketType_QStartNoAckMode;
918b82f087SGreg Clayton             else if (PACKET_STARTS_WITH ("QSetDisableASLR:"))   return eServerPacketType_QSetDisableASLR;
928b82f087SGreg Clayton             else if (PACKET_STARTS_WITH ("QSetSTDIN:"))         return eServerPacketType_QSetSTDIN;
938b82f087SGreg Clayton             else if (PACKET_STARTS_WITH ("QSetSTDOUT:"))        return eServerPacketType_QSetSTDOUT;
948b82f087SGreg Clayton             else if (PACKET_STARTS_WITH ("QSetSTDERR:"))        return eServerPacketType_QSetSTDERR;
958b82f087SGreg Clayton             else if (PACKET_STARTS_WITH ("QSetWorkingDir:"))    return eServerPacketType_QSetWorkingDir;
968b82f087SGreg Clayton             break;
97e0f8f574SDaniel Malea         case 'L':
98e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH ("QLaunchArch:"))            return eServerPacketType_QLaunchArch;
99e0f8f574SDaniel Malea             break;
1008b82f087SGreg Clayton         }
1011cb6496eSGreg Clayton         break;
1021cb6496eSGreg Clayton 
103576d8834SGreg Clayton     case 'q':
1048b82f087SGreg Clayton         switch (packet_cstr[1])
1058b82f087SGreg Clayton         {
1068b82f087SGreg Clayton         case 's':
1078b82f087SGreg Clayton             if (PACKET_MATCHES ("qsProcessInfo"))               return eServerPacketType_qsProcessInfo;
1088b82f087SGreg Clayton             break;
1098b82f087SGreg Clayton 
1108b82f087SGreg Clayton         case 'f':
1118b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qfProcessInfo"))           return eServerPacketType_qfProcessInfo;
1128b82f087SGreg Clayton             break;
1138b82f087SGreg Clayton 
1148b82f087SGreg Clayton         case 'C':
1158b82f087SGreg Clayton             if (packet_size == 2)                               return eServerPacketType_qC;
1168b82f087SGreg Clayton             break;
1178b82f087SGreg Clayton 
1188b82f087SGreg Clayton         case 'G':
1198b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qGroupName:"))             return eServerPacketType_qGroupName;
120*fbb76349SGreg Clayton             if (PACKET_MATCHES ("qGetWorkingDir"))              return eServerPacketType_qGetWorkingDir;
1218b82f087SGreg Clayton             break;
1228b82f087SGreg Clayton 
1238b82f087SGreg Clayton         case 'H':
1248b82f087SGreg Clayton             if (PACKET_MATCHES ("qHostInfo"))                   return eServerPacketType_qHostInfo;
1258b82f087SGreg Clayton             break;
1268b82f087SGreg Clayton 
127e0f8f574SDaniel Malea         case 'K':
128e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH ("qKillSpawnedProcess"))     return eServerPacketType_qKillSpawnedProcess;
129e0f8f574SDaniel Malea             break;
130e0f8f574SDaniel Malea 
1318b82f087SGreg Clayton         case 'L':
132e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH ("qLaunchGDBServer"))        return eServerPacketType_qLaunchGDBServer;
1338b82f087SGreg Clayton             if (PACKET_MATCHES ("qLaunchSuccess"))              return eServerPacketType_qLaunchSuccess;
1348b82f087SGreg Clayton             break;
1358b82f087SGreg Clayton 
1368b82f087SGreg Clayton         case 'P':
1378b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
138*fbb76349SGreg Clayton             if (PACKET_STARTS_WITH ("qPlatform_shell:"))   return eServerPacketType_qPlatform_shell;
139*fbb76349SGreg Clayton             if (PACKET_STARTS_WITH ("qPlatform_mkdir:"))        return eServerPacketType_qPlatform_mkdir;
140*fbb76349SGreg Clayton             if (PACKET_STARTS_WITH ("qPlatform_chmod:"))        return eServerPacketType_qPlatform_chmod;
1418b82f087SGreg Clayton             break;
1428b82f087SGreg Clayton 
143e0f8f574SDaniel Malea 
1448b82f087SGreg Clayton         case 'S':
1458b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qSpeedTest:"))             return eServerPacketType_qSpeedTest;
1468b82f087SGreg Clayton             break;
1478b82f087SGreg Clayton 
1488b82f087SGreg Clayton         case 'U':
1498b82f087SGreg Clayton             if (PACKET_STARTS_WITH ("qUserName:"))              return eServerPacketType_qUserName;
1508b82f087SGreg Clayton             break;
1518b82f087SGreg Clayton         }
152576d8834SGreg Clayton         break;
153e0f8f574SDaniel Malea     case 'v':
154e0f8f574SDaniel Malea             if (PACKET_STARTS_WITH("vFile:"))
155e0f8f574SDaniel Malea             {
156*fbb76349SGreg Clayton                 if (PACKET_STARTS_WITH("vFile:open:"))          return eServerPacketType_vFile_open;
157*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:close:"))    return eServerPacketType_vFile_close;
158*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:pread"))     return eServerPacketType_vFile_pread;
159*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:pwrite"))    return eServerPacketType_vFile_pwrite;
160*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:size"))      return eServerPacketType_vFile_size;
161*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:exists"))    return eServerPacketType_vFile_exists;
162*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:stat"))      return eServerPacketType_vFile_stat;
163*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:mode"))      return eServerPacketType_vFile_mode;
164*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:MD5"))       return eServerPacketType_vFile_md5;
165*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:symlink"))   return eServerPacketType_vFile_symlink;
166*fbb76349SGreg Clayton                 else if (PACKET_STARTS_WITH("vFile:unlink"))    return eServerPacketType_vFile_unlink;
167e0f8f574SDaniel Malea 
168e0f8f574SDaniel Malea             }
169e0f8f574SDaniel Malea             break;
170576d8834SGreg Clayton     }
171576d8834SGreg Clayton     return eServerPacketType_unimplemented;
172576d8834SGreg Clayton }
173576d8834SGreg Clayton 
174576d8834SGreg Clayton bool
175576d8834SGreg Clayton StringExtractorGDBRemote::IsOKResponse() const
176576d8834SGreg Clayton {
177576d8834SGreg Clayton     return GetResponseType () == eOK;
17830fdc8d8SChris Lattner }
17930fdc8d8SChris Lattner 
18030fdc8d8SChris Lattner 
18130fdc8d8SChris Lattner bool
182576d8834SGreg Clayton StringExtractorGDBRemote::IsUnsupportedResponse() const
18330fdc8d8SChris Lattner {
184576d8834SGreg Clayton     return GetResponseType () == eUnsupported;
18530fdc8d8SChris Lattner }
18630fdc8d8SChris Lattner 
18730fdc8d8SChris Lattner bool
188576d8834SGreg Clayton StringExtractorGDBRemote::IsNormalResponse() const
18930fdc8d8SChris Lattner {
190576d8834SGreg Clayton     return GetResponseType () == eResponse;
19130fdc8d8SChris Lattner }
19230fdc8d8SChris Lattner 
19330fdc8d8SChris Lattner bool
194576d8834SGreg Clayton StringExtractorGDBRemote::IsErrorResponse() const
19530fdc8d8SChris Lattner {
196576d8834SGreg Clayton     return GetResponseType () == eError &&
19730fdc8d8SChris Lattner            m_packet.size() == 3 &&
19830fdc8d8SChris Lattner            isxdigit(m_packet[1]) &&
19930fdc8d8SChris Lattner            isxdigit(m_packet[2]);
20030fdc8d8SChris Lattner }
20130fdc8d8SChris Lattner 
20230fdc8d8SChris Lattner uint8_t
20330fdc8d8SChris Lattner StringExtractorGDBRemote::GetError ()
20430fdc8d8SChris Lattner {
205576d8834SGreg Clayton     if (GetResponseType() == eError)
20630fdc8d8SChris Lattner     {
20730fdc8d8SChris Lattner         SetFilePos(1);
20830fdc8d8SChris Lattner         return GetHexU8(255);
20930fdc8d8SChris Lattner     }
21030fdc8d8SChris Lattner     return 0;
21130fdc8d8SChris Lattner }
212e0f8f574SDaniel Malea 
213e0f8f574SDaniel Malea size_t
214e0f8f574SDaniel Malea StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)
215e0f8f574SDaniel Malea {
216e0f8f574SDaniel Malea     str.clear();
217e0f8f574SDaniel Malea     char ch;
218e0f8f574SDaniel Malea     while (GetBytesLeft())
219e0f8f574SDaniel Malea     {
220e0f8f574SDaniel Malea         ch = GetChar();
221e0f8f574SDaniel Malea         if (ch == 0x7d)
222e0f8f574SDaniel Malea             ch = (GetChar() ^ 0x20);
223e0f8f574SDaniel Malea         str.append(1,ch);
224e0f8f574SDaniel Malea     }
225e0f8f574SDaniel Malea     return str.size();
226e0f8f574SDaniel Malea }
227e0f8f574SDaniel Malea 
228