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 20StringExtractorGDBRemote::ResponseType 21StringExtractorGDBRemote::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 53StringExtractorGDBRemote::ServerPacketType 54StringExtractorGDBRemote::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 301bool 302StringExtractorGDBRemote::IsOKResponse() const 303{ 304 return GetResponseType () == eOK; 305} 306 307 308bool 309StringExtractorGDBRemote::IsUnsupportedResponse() const 310{ 311 return GetResponseType () == eUnsupported; 312} 313 314bool 315StringExtractorGDBRemote::IsNormalResponse() const 316{ 317 return GetResponseType () == eResponse; 318} 319 320bool 321StringExtractorGDBRemote::IsErrorResponse() const 322{ 323 return GetResponseType () == eError && 324 m_packet.size() == 3 && 325 isxdigit(m_packet[1]) && 326 isxdigit(m_packet[2]); 327} 328 329uint8_t 330StringExtractorGDBRemote::GetError () 331{ 332 if (GetResponseType() == eError) 333 { 334 SetFilePos(1); 335 return GetHexU8(255); 336 } 337 return 0; 338} 339 340size_t 341StringExtractorGDBRemote::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 355