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 ("QSetDetachOnError:")) return eServerPacketType_QSetDetachOnError; 96 if (PACKET_STARTS_WITH ("QSetSTDIN:")) return eServerPacketType_QSetSTDIN; 97 if (PACKET_STARTS_WITH ("QSetSTDOUT:")) return eServerPacketType_QSetSTDOUT; 98 if (PACKET_STARTS_WITH ("QSetSTDERR:")) return eServerPacketType_QSetSTDERR; 99 if (PACKET_STARTS_WITH ("QSetWorkingDir:")) return eServerPacketType_QSetWorkingDir; 100 if (PACKET_STARTS_WITH ("QSetLogging:")) return eServerPacketType_QSetLogging; 101 if (PACKET_STARTS_WITH ("QSetMaxPacketSize:")) return eServerPacketType_QSetMaxPacketSize; 102 if (PACKET_STARTS_WITH ("QSetMaxPayloadSize:")) return eServerPacketType_QSetMaxPayloadSize; 103 if (PACKET_STARTS_WITH ("QSetEnableAsyncProfiling;")) return eServerPacketType_QSetEnableAsyncProfiling; 104 if (PACKET_STARTS_WITH ("QSyncThreadState:")) return eServerPacketType_QSyncThreadState; 105 break; 106 107 case 'L': 108 if (PACKET_STARTS_WITH ("QLaunchArch:")) return eServerPacketType_QLaunchArch; 109 if (PACKET_MATCHES("QListThreadsInStopReply")) return eServerPacketType_QListThreadsInStopReply; 110 break; 111 112 case 'R': 113 if (PACKET_STARTS_WITH ("QRestoreRegisterState:")) return eServerPacketType_QRestoreRegisterState; 114 break; 115 116 case 'T': 117 if (PACKET_MATCHES ("QThreadSuffixSupported")) return eServerPacketType_QThreadSuffixSupported; 118 break; 119 } 120 break; 121 122 case 'q': 123 switch (packet_cstr[1]) 124 { 125 case 's': 126 if (PACKET_MATCHES ("qsProcessInfo")) return eServerPacketType_qsProcessInfo; 127 if (PACKET_MATCHES ("qsThreadInfo")) return eServerPacketType_qsThreadInfo; 128 break; 129 130 case 'f': 131 if (PACKET_STARTS_WITH ("qfProcessInfo")) return eServerPacketType_qfProcessInfo; 132 if (PACKET_STARTS_WITH ("qfThreadInfo")) return eServerPacketType_qfThreadInfo; 133 break; 134 135 case 'C': 136 if (packet_size == 2) return eServerPacketType_qC; 137 break; 138 139 case 'G': 140 if (PACKET_STARTS_WITH ("qGroupName:")) return eServerPacketType_qGroupName; 141 if (PACKET_MATCHES ("qGetWorkingDir")) return eServerPacketType_qGetWorkingDir; 142 if (PACKET_MATCHES ("qGetPid")) return eServerPacketType_qGetPid; 143 if (PACKET_STARTS_WITH ("qGetProfileData;")) return eServerPacketType_qGetProfileData; 144 if (PACKET_MATCHES ("qGDBServerVersion")) return eServerPacketType_qGDBServerVersion; 145 break; 146 147 case 'H': 148 if (PACKET_MATCHES ("qHostInfo")) return eServerPacketType_qHostInfo; 149 break; 150 151 case 'K': 152 if (PACKET_STARTS_WITH ("qKillSpawnedProcess")) return eServerPacketType_qKillSpawnedProcess; 153 break; 154 155 case 'L': 156 if (PACKET_STARTS_WITH ("qLaunchGDBServer")) return eServerPacketType_qLaunchGDBServer; 157 if (PACKET_MATCHES ("qLaunchSuccess")) return eServerPacketType_qLaunchSuccess; 158 break; 159 160 case 'M': 161 if (PACKET_STARTS_WITH ("qMemoryRegionInfo:")) return eServerPacketType_qMemoryRegionInfo; 162 if (PACKET_MATCHES ("qMemoryRegionInfo")) return eServerPacketType_qMemoryRegionInfoSupported; 163 break; 164 165 case 'P': 166 if (PACKET_STARTS_WITH ("qProcessInfoPID:")) return eServerPacketType_qProcessInfoPID; 167 if (PACKET_STARTS_WITH ("qPlatform_shell:")) return eServerPacketType_qPlatform_shell; 168 if (PACKET_STARTS_WITH ("qPlatform_mkdir:")) return eServerPacketType_qPlatform_mkdir; 169 if (PACKET_STARTS_WITH ("qPlatform_chmod:")) return eServerPacketType_qPlatform_chmod; 170 if (PACKET_MATCHES ("qProcessInfo")) return eServerPacketType_qProcessInfo; 171 break; 172 173 case 'R': 174 if (PACKET_STARTS_WITH ("qRcmd,")) return eServerPacketType_qRcmd; 175 if (PACKET_STARTS_WITH ("qRegisterInfo")) return eServerPacketType_qRegisterInfo; 176 break; 177 178 case 'S': 179 if (PACKET_STARTS_WITH ("qSpeedTest:")) return eServerPacketType_qSpeedTest; 180 if (PACKET_MATCHES ("qShlibInfoAddr")) return eServerPacketType_qShlibInfoAddr; 181 if (PACKET_MATCHES ("qStepPacketSupported")) return eServerPacketType_qStepPacketSupported; 182 if (PACKET_MATCHES ("qSyncThreadStateSupported")) return eServerPacketType_qSyncThreadStateSupported; 183 break; 184 185 case 'T': 186 if (PACKET_STARTS_WITH ("qThreadExtraInfo,")) return eServerPacketType_qThreadExtraInfo; 187 if (PACKET_STARTS_WITH ("qThreadStopInfo")) return eServerPacketType_qThreadStopInfo; 188 break; 189 190 case 'U': 191 if (PACKET_STARTS_WITH ("qUserName:")) return eServerPacketType_qUserName; 192 break; 193 194 case 'V': 195 if (PACKET_MATCHES ("qVAttachOrWaitSupported")) return eServerPacketType_qVAttachOrWaitSupported; 196 break; 197 198 case 'W': 199 if (PACKET_STARTS_WITH ("qWatchpointSupportInfo:")) return eServerPacketType_qWatchpointSupportInfo; 200 if (PACKET_MATCHES ("qWatchpointSupportInfo")) return eServerPacketType_qWatchpointSupportInfoSupported; 201 break; 202 } 203 break; 204 case 'v': 205 if (PACKET_STARTS_WITH("vFile:")) 206 { 207 if (PACKET_STARTS_WITH("vFile:open:")) return eServerPacketType_vFile_open; 208 else if (PACKET_STARTS_WITH("vFile:close:")) return eServerPacketType_vFile_close; 209 else if (PACKET_STARTS_WITH("vFile:pread")) return eServerPacketType_vFile_pread; 210 else if (PACKET_STARTS_WITH("vFile:pwrite")) return eServerPacketType_vFile_pwrite; 211 else if (PACKET_STARTS_WITH("vFile:size")) return eServerPacketType_vFile_size; 212 else if (PACKET_STARTS_WITH("vFile:exists")) return eServerPacketType_vFile_exists; 213 else if (PACKET_STARTS_WITH("vFile:stat")) return eServerPacketType_vFile_stat; 214 else if (PACKET_STARTS_WITH("vFile:mode")) return eServerPacketType_vFile_mode; 215 else if (PACKET_STARTS_WITH("vFile:MD5")) return eServerPacketType_vFile_md5; 216 else if (PACKET_STARTS_WITH("vFile:symlink")) return eServerPacketType_vFile_symlink; 217 else if (PACKET_STARTS_WITH("vFile:unlink")) return eServerPacketType_vFile_unlink; 218 219 } else { 220 if (PACKET_STARTS_WITH ("vAttach;")) return eServerPacketType_vAttach; 221 if (PACKET_STARTS_WITH ("vAttachWait;")) return eServerPacketType_vAttachWait; 222 if (PACKET_STARTS_WITH ("vAttachOrWait;")) return eServerPacketType_vAttachOrWait; 223 if (PACKET_STARTS_WITH ("vAttachName;")) return eServerPacketType_vAttachName; 224 if (PACKET_STARTS_WITH("vCont;")) return eServerPacketType_vCont; 225 if (PACKET_MATCHES ("vCont?")) return eServerPacketType_vCont_actions; 226 } 227 break; 228 case '_': 229 switch (packet_cstr[1]) 230 { 231 case 'M': 232 return eServerPacketType__M; 233 234 case 'm': 235 return eServerPacketType__m; 236 } 237 break; 238 239 case '?': 240 if (packet_size == 1) return eServerPacketType_stop_reason; 241 break; 242 243 case 'c': 244 return eServerPacketType_c; 245 246 case 'C': 247 return eServerPacketType_C; 248 249 case 'D': 250 if (packet_size == 1) return eServerPacketType_D; 251 break; 252 253 case 'g': 254 if (packet_size == 1) return eServerPacketType_g; 255 break; 256 257 case 'G': 258 return eServerPacketType_G; 259 260 case 'H': 261 return eServerPacketType_H; 262 263 case 'k': 264 if (packet_size == 1) return eServerPacketType_k; 265 break; 266 267 case 'm': 268 return eServerPacketType_m; 269 270 case 'M': 271 return eServerPacketType_M; 272 273 case 'p': 274 return eServerPacketType_p; 275 276 case 'P': 277 return eServerPacketType_P; 278 279 case 's': 280 if (packet_size == 1) return eServerPacketType_s; 281 break; 282 283 case 'S': 284 return eServerPacketType_S; 285 286 case 'T': 287 return eServerPacketType_T; 288 289 case 'z': 290 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 291 return eServerPacketType_z; 292 break; 293 294 case 'Z': 295 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 296 return eServerPacketType_Z; 297 break; 298 } 299 return eServerPacketType_unimplemented; 300 } 301 302 bool 303 StringExtractorGDBRemote::IsOKResponse() const 304 { 305 return GetResponseType () == eOK; 306 } 307 308 309 bool 310 StringExtractorGDBRemote::IsUnsupportedResponse() const 311 { 312 return GetResponseType () == eUnsupported; 313 } 314 315 bool 316 StringExtractorGDBRemote::IsNormalResponse() const 317 { 318 return GetResponseType () == eResponse; 319 } 320 321 bool 322 StringExtractorGDBRemote::IsErrorResponse() const 323 { 324 return GetResponseType () == eError && 325 m_packet.size() == 3 && 326 isxdigit(m_packet[1]) && 327 isxdigit(m_packet[2]); 328 } 329 330 uint8_t 331 StringExtractorGDBRemote::GetError () 332 { 333 if (GetResponseType() == eError) 334 { 335 SetFilePos(1); 336 return GetHexU8(255); 337 } 338 return 0; 339 } 340 341 size_t 342 StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str) 343 { 344 str.clear(); 345 char ch; 346 while (GetBytesLeft()) 347 { 348 ch = GetChar(); 349 if (ch == 0x7d) 350 ch = (GetChar() ^ 0x20); 351 str.append(1,ch); 352 } 353 return str.size(); 354 } 355 356