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 switch (packet_cstr[1]) 84 { 85 case 'E': 86 if (PACKET_STARTS_WITH ("QEnvironment:")) return eServerPacketType_QEnvironment; 87 break; 88 89 case 'S': 90 if (PACKET_MATCHES ("QStartNoAckMode")) return eServerPacketType_QStartNoAckMode; 91 else if (PACKET_STARTS_WITH ("QSetDisableASLR:")) return eServerPacketType_QSetDisableASLR; 92 else if (PACKET_STARTS_WITH ("QSetSTDIN:")) return eServerPacketType_QSetSTDIN; 93 else if (PACKET_STARTS_WITH ("QSetSTDOUT:")) return eServerPacketType_QSetSTDOUT; 94 else if (PACKET_STARTS_WITH ("QSetSTDERR:")) return eServerPacketType_QSetSTDERR; 95 else if (PACKET_STARTS_WITH ("QSetWorkingDir:")) return eServerPacketType_QSetWorkingDir; 96 break; 97 case 'L': 98 if (PACKET_STARTS_WITH ("QLaunchArch:")) return eServerPacketType_QLaunchArch; 99 break; 100 } 101 break; 102 103 case 'q': 104 switch (packet_cstr[1]) 105 { 106 case 's': 107 if (PACKET_MATCHES ("qsProcessInfo")) return eServerPacketType_qsProcessInfo; 108 break; 109 110 case 'f': 111 if (PACKET_STARTS_WITH ("qfProcessInfo")) return eServerPacketType_qfProcessInfo; 112 break; 113 114 case 'C': 115 if (packet_size == 2) return eServerPacketType_qC; 116 break; 117 118 case 'G': 119 if (PACKET_STARTS_WITH ("qGroupName:")) return eServerPacketType_qGroupName; 120 if (PACKET_MATCHES ("qGetWorkingDir")) return eServerPacketType_qGetWorkingDir; 121 break; 122 123 case 'H': 124 if (PACKET_MATCHES ("qHostInfo")) return eServerPacketType_qHostInfo; 125 break; 126 127 case 'K': 128 if (PACKET_STARTS_WITH ("qKillSpawnedProcess")) return eServerPacketType_qKillSpawnedProcess; 129 break; 130 131 case 'L': 132 if (PACKET_STARTS_WITH ("qLaunchGDBServer")) return eServerPacketType_qLaunchGDBServer; 133 if (PACKET_MATCHES ("qLaunchSuccess")) return eServerPacketType_qLaunchSuccess; 134 break; 135 136 case 'P': 137 if (PACKET_STARTS_WITH ("qProcessInfoPID:")) return eServerPacketType_qProcessInfoPID; 138 if (PACKET_STARTS_WITH ("qPlatform_shell:")) return eServerPacketType_qPlatform_shell; 139 if (PACKET_STARTS_WITH ("qPlatform_mkdir:")) return eServerPacketType_qPlatform_mkdir; 140 if (PACKET_STARTS_WITH ("qPlatform_chmod:")) return eServerPacketType_qPlatform_chmod; 141 break; 142 143 144 case 'S': 145 if (PACKET_STARTS_WITH ("qSpeedTest:")) return eServerPacketType_qSpeedTest; 146 break; 147 148 case 'U': 149 if (PACKET_STARTS_WITH ("qUserName:")) return eServerPacketType_qUserName; 150 break; 151 } 152 break; 153 case 'v': 154 if (PACKET_STARTS_WITH("vFile:")) 155 { 156 if (PACKET_STARTS_WITH("vFile:open:")) return eServerPacketType_vFile_open; 157 else if (PACKET_STARTS_WITH("vFile:close:")) return eServerPacketType_vFile_close; 158 else if (PACKET_STARTS_WITH("vFile:pread")) return eServerPacketType_vFile_pread; 159 else if (PACKET_STARTS_WITH("vFile:pwrite")) return eServerPacketType_vFile_pwrite; 160 else if (PACKET_STARTS_WITH("vFile:size")) return eServerPacketType_vFile_size; 161 else if (PACKET_STARTS_WITH("vFile:exists")) return eServerPacketType_vFile_exists; 162 else if (PACKET_STARTS_WITH("vFile:stat")) return eServerPacketType_vFile_stat; 163 else if (PACKET_STARTS_WITH("vFile:mode")) return eServerPacketType_vFile_mode; 164 else if (PACKET_STARTS_WITH("vFile:MD5")) return eServerPacketType_vFile_md5; 165 else if (PACKET_STARTS_WITH("vFile:symlink")) return eServerPacketType_vFile_symlink; 166 else if (PACKET_STARTS_WITH("vFile:unlink")) return eServerPacketType_vFile_unlink; 167 168 } 169 break; 170 } 171 return eServerPacketType_unimplemented; 172 } 173 174 bool 175 StringExtractorGDBRemote::IsOKResponse() const 176 { 177 return GetResponseType () == eOK; 178 } 179 180 181 bool 182 StringExtractorGDBRemote::IsUnsupportedResponse() const 183 { 184 return GetResponseType () == eUnsupported; 185 } 186 187 bool 188 StringExtractorGDBRemote::IsNormalResponse() const 189 { 190 return GetResponseType () == eResponse; 191 } 192 193 bool 194 StringExtractorGDBRemote::IsErrorResponse() const 195 { 196 return GetResponseType () == eError && 197 m_packet.size() == 3 && 198 isxdigit(m_packet[1]) && 199 isxdigit(m_packet[2]); 200 } 201 202 uint8_t 203 StringExtractorGDBRemote::GetError () 204 { 205 if (GetResponseType() == eError) 206 { 207 SetFilePos(1); 208 return GetHexU8(255); 209 } 210 return 0; 211 } 212 213 size_t 214 StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str) 215 { 216 str.clear(); 217 char ch; 218 while (GetBytesLeft()) 219 { 220 ch = GetChar(); 221 if (ch == 0x7d) 222 ch = (GetChar() ^ 0x20); 223 str.append(1,ch); 224 } 225 return str.size(); 226 } 227 228