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 68 case '%': 69 return eServerPacketType_notify; 70 71 case '\x03': 72 if (packet_size == 1) return eServerPacketType_interrupt; 73 break; 74 75 case '-': 76 if (packet_size == 1) return eServerPacketType_nack; 77 break; 78 79 case '+': 80 if (packet_size == 1) return eServerPacketType_ack; 81 break; 82 83 case 'A': 84 return eServerPacketType_A; 85 86 case 'Q': 87 88 switch (packet_cstr[1]) 89 { 90 case 'E': 91 if (PACKET_STARTS_WITH ("QEnvironment:")) return eServerPacketType_QEnvironment; 92 if (PACKET_STARTS_WITH ("QEnvironmentHexEncoded:")) return eServerPacketType_QEnvironmentHexEncoded; 93 break; 94 95 case 'S': 96 if (PACKET_MATCHES ("QStartNoAckMode")) return eServerPacketType_QStartNoAckMode; 97 if (PACKET_STARTS_WITH ("QSaveRegisterState")) return eServerPacketType_QSaveRegisterState; 98 if (PACKET_STARTS_WITH ("QSetDisableASLR:")) return eServerPacketType_QSetDisableASLR; 99 if (PACKET_STARTS_WITH ("QSetDetachOnError:")) return eServerPacketType_QSetDetachOnError; 100 if (PACKET_STARTS_WITH ("QSetSTDIN:")) return eServerPacketType_QSetSTDIN; 101 if (PACKET_STARTS_WITH ("QSetSTDOUT:")) return eServerPacketType_QSetSTDOUT; 102 if (PACKET_STARTS_WITH ("QSetSTDERR:")) return eServerPacketType_QSetSTDERR; 103 if (PACKET_STARTS_WITH ("QSetWorkingDir:")) return eServerPacketType_QSetWorkingDir; 104 if (PACKET_STARTS_WITH ("QSetLogging:")) return eServerPacketType_QSetLogging; 105 if (PACKET_STARTS_WITH ("QSetMaxPacketSize:")) return eServerPacketType_QSetMaxPacketSize; 106 if (PACKET_STARTS_WITH ("QSetMaxPayloadSize:")) return eServerPacketType_QSetMaxPayloadSize; 107 if (PACKET_STARTS_WITH ("QSetEnableAsyncProfiling;")) return eServerPacketType_QSetEnableAsyncProfiling; 108 if (PACKET_STARTS_WITH ("QSyncThreadState:")) return eServerPacketType_QSyncThreadState; 109 break; 110 111 case 'L': 112 if (PACKET_STARTS_WITH ("QLaunchArch:")) return eServerPacketType_QLaunchArch; 113 if (PACKET_MATCHES("QListThreadsInStopReply")) return eServerPacketType_QListThreadsInStopReply; 114 break; 115 116 case 'R': 117 if (PACKET_STARTS_WITH ("QRestoreRegisterState:")) return eServerPacketType_QRestoreRegisterState; 118 break; 119 120 case 'T': 121 if (PACKET_MATCHES ("QThreadSuffixSupported")) return eServerPacketType_QThreadSuffixSupported; 122 break; 123 } 124 break; 125 126 case 'q': 127 switch (packet_cstr[1]) 128 { 129 case 's': 130 if (PACKET_MATCHES ("qsProcessInfo")) return eServerPacketType_qsProcessInfo; 131 if (PACKET_MATCHES ("qsThreadInfo")) return eServerPacketType_qsThreadInfo; 132 break; 133 134 case 'f': 135 if (PACKET_STARTS_WITH ("qfProcessInfo")) return eServerPacketType_qfProcessInfo; 136 if (PACKET_STARTS_WITH ("qfThreadInfo")) return eServerPacketType_qfThreadInfo; 137 break; 138 139 case 'C': 140 if (packet_size == 2) return eServerPacketType_qC; 141 break; 142 143 case 'E': 144 if (PACKET_STARTS_WITH ("qEcho:")) return eServerPacketType_qEcho; 145 break; 146 147 case 'F': 148 if (PACKET_STARTS_WITH ("qFileLoadAddress:")) return eServerPacketType_qFileLoadAddress; 149 break; 150 151 case 'G': 152 if (PACKET_STARTS_WITH ("qGroupName:")) return eServerPacketType_qGroupName; 153 if (PACKET_MATCHES ("qGetWorkingDir")) return eServerPacketType_qGetWorkingDir; 154 if (PACKET_MATCHES ("qGetPid")) return eServerPacketType_qGetPid; 155 if (PACKET_STARTS_WITH ("qGetProfileData;")) return eServerPacketType_qGetProfileData; 156 if (PACKET_MATCHES ("qGDBServerVersion")) return eServerPacketType_qGDBServerVersion; 157 break; 158 159 case 'H': 160 if (PACKET_MATCHES ("qHostInfo")) return eServerPacketType_qHostInfo; 161 break; 162 163 case 'K': 164 if (PACKET_STARTS_WITH ("qKillSpawnedProcess")) return eServerPacketType_qKillSpawnedProcess; 165 break; 166 167 case 'L': 168 if (PACKET_STARTS_WITH ("qLaunchGDBServer")) return eServerPacketType_qLaunchGDBServer; 169 if (PACKET_MATCHES ("qLaunchSuccess")) return eServerPacketType_qLaunchSuccess; 170 break; 171 172 case 'M': 173 if (PACKET_STARTS_WITH ("qMemoryRegionInfo:")) return eServerPacketType_qMemoryRegionInfo; 174 if (PACKET_MATCHES ("qMemoryRegionInfo")) return eServerPacketType_qMemoryRegionInfoSupported; 175 if (PACKET_STARTS_WITH ("qModuleInfo:")) return eServerPacketType_qModuleInfo; 176 break; 177 178 case 'P': 179 if (PACKET_STARTS_WITH ("qProcessInfoPID:")) return eServerPacketType_qProcessInfoPID; 180 if (PACKET_STARTS_WITH ("qPlatform_shell:")) return eServerPacketType_qPlatform_shell; 181 if (PACKET_STARTS_WITH ("qPlatform_mkdir:")) return eServerPacketType_qPlatform_mkdir; 182 if (PACKET_STARTS_WITH ("qPlatform_chmod:")) return eServerPacketType_qPlatform_chmod; 183 if (PACKET_MATCHES ("qProcessInfo")) return eServerPacketType_qProcessInfo; 184 break; 185 186 case 'Q': 187 if (PACKET_MATCHES ("qQueryGDBServer")) return eServerPacketType_qQueryGDBServer; 188 break; 189 190 case 'R': 191 if (PACKET_STARTS_WITH ("qRcmd,")) return eServerPacketType_qRcmd; 192 if (PACKET_STARTS_WITH ("qRegisterInfo")) return eServerPacketType_qRegisterInfo; 193 break; 194 195 case 'S': 196 if (PACKET_STARTS_WITH ("qSpeedTest:")) return eServerPacketType_qSpeedTest; 197 if (PACKET_MATCHES ("qShlibInfoAddr")) return eServerPacketType_qShlibInfoAddr; 198 if (PACKET_MATCHES ("qStepPacketSupported")) return eServerPacketType_qStepPacketSupported; 199 if (PACKET_STARTS_WITH ("qSupported")) return eServerPacketType_qSupported; 200 if (PACKET_MATCHES ("qSyncThreadStateSupported")) return eServerPacketType_qSyncThreadStateSupported; 201 break; 202 203 case 'T': 204 if (PACKET_STARTS_WITH ("qThreadExtraInfo,")) return eServerPacketType_qThreadExtraInfo; 205 if (PACKET_STARTS_WITH ("qThreadStopInfo")) return eServerPacketType_qThreadStopInfo; 206 break; 207 208 case 'U': 209 if (PACKET_STARTS_WITH ("qUserName:")) return eServerPacketType_qUserName; 210 break; 211 212 case 'V': 213 if (PACKET_MATCHES ("qVAttachOrWaitSupported")) return eServerPacketType_qVAttachOrWaitSupported; 214 break; 215 216 case 'W': 217 if (PACKET_STARTS_WITH ("qWatchpointSupportInfo:")) return eServerPacketType_qWatchpointSupportInfo; 218 if (PACKET_MATCHES ("qWatchpointSupportInfo")) return eServerPacketType_qWatchpointSupportInfoSupported; 219 break; 220 221 case 'X': 222 if (PACKET_STARTS_WITH ("qXfer:auxv:read::")) return eServerPacketType_qXfer_auxv_read; 223 break; 224 } 225 break; 226 227 case 'j': 228 if (PACKET_MATCHES("jSignalsInfo")) return eServerPacketType_jSignalsInfo; 229 if (PACKET_MATCHES("jThreadsInfo")) return eServerPacketType_jThreadsInfo; 230 break; 231 232 case 'v': 233 if (PACKET_STARTS_WITH("vFile:")) 234 { 235 if (PACKET_STARTS_WITH("vFile:open:")) return eServerPacketType_vFile_open; 236 else if (PACKET_STARTS_WITH("vFile:close:")) return eServerPacketType_vFile_close; 237 else if (PACKET_STARTS_WITH("vFile:pread")) return eServerPacketType_vFile_pread; 238 else if (PACKET_STARTS_WITH("vFile:pwrite")) return eServerPacketType_vFile_pwrite; 239 else if (PACKET_STARTS_WITH("vFile:size")) return eServerPacketType_vFile_size; 240 else if (PACKET_STARTS_WITH("vFile:exists")) return eServerPacketType_vFile_exists; 241 else if (PACKET_STARTS_WITH("vFile:stat")) return eServerPacketType_vFile_stat; 242 else if (PACKET_STARTS_WITH("vFile:mode")) return eServerPacketType_vFile_mode; 243 else if (PACKET_STARTS_WITH("vFile:MD5")) return eServerPacketType_vFile_md5; 244 else if (PACKET_STARTS_WITH("vFile:symlink")) return eServerPacketType_vFile_symlink; 245 else if (PACKET_STARTS_WITH("vFile:unlink")) return eServerPacketType_vFile_unlink; 246 247 } else { 248 if (PACKET_STARTS_WITH ("vAttach;")) return eServerPacketType_vAttach; 249 if (PACKET_STARTS_WITH ("vAttachWait;")) return eServerPacketType_vAttachWait; 250 if (PACKET_STARTS_WITH ("vAttachOrWait;")) return eServerPacketType_vAttachOrWait; 251 if (PACKET_STARTS_WITH ("vAttachName;")) return eServerPacketType_vAttachName; 252 if (PACKET_STARTS_WITH("vCont;")) return eServerPacketType_vCont; 253 if (PACKET_MATCHES ("vCont?")) return eServerPacketType_vCont_actions; 254 } 255 break; 256 case '_': 257 switch (packet_cstr[1]) 258 { 259 case 'M': 260 return eServerPacketType__M; 261 262 case 'm': 263 return eServerPacketType__m; 264 } 265 break; 266 267 case '?': 268 if (packet_size == 1) return eServerPacketType_stop_reason; 269 break; 270 271 case 'c': 272 return eServerPacketType_c; 273 274 case 'C': 275 return eServerPacketType_C; 276 277 case 'D': 278 if (packet_size == 1) return eServerPacketType_D; 279 break; 280 281 case 'g': 282 if (packet_size == 1) return eServerPacketType_g; 283 break; 284 285 case 'G': 286 return eServerPacketType_G; 287 288 case 'H': 289 return eServerPacketType_H; 290 291 case 'I': 292 return eServerPacketType_I; 293 294 case 'k': 295 if (packet_size == 1) return eServerPacketType_k; 296 break; 297 298 case 'm': 299 return eServerPacketType_m; 300 301 case 'M': 302 return eServerPacketType_M; 303 304 case 'p': 305 return eServerPacketType_p; 306 307 case 'P': 308 return eServerPacketType_P; 309 310 case 's': 311 if (packet_size == 1) return eServerPacketType_s; 312 break; 313 314 case 'S': 315 return eServerPacketType_S; 316 317 case 'x': 318 return eServerPacketType_x; 319 320 case 'X': 321 return eServerPacketType_X; 322 323 case 'T': 324 return eServerPacketType_T; 325 326 case 'z': 327 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 328 return eServerPacketType_z; 329 break; 330 331 case 'Z': 332 if (packet_cstr[1] >= '0' && packet_cstr[1] <= '4') 333 return eServerPacketType_Z; 334 break; 335 } 336 return eServerPacketType_unimplemented; 337 } 338 339 bool 340 StringExtractorGDBRemote::IsOKResponse() const 341 { 342 return GetResponseType () == eOK; 343 } 344 345 346 bool 347 StringExtractorGDBRemote::IsUnsupportedResponse() const 348 { 349 return GetResponseType () == eUnsupported; 350 } 351 352 bool 353 StringExtractorGDBRemote::IsNormalResponse() const 354 { 355 return GetResponseType () == eResponse; 356 } 357 358 bool 359 StringExtractorGDBRemote::IsErrorResponse() const 360 { 361 return GetResponseType () == eError && 362 m_packet.size() == 3 && 363 isxdigit(m_packet[1]) && 364 isxdigit(m_packet[2]); 365 } 366 367 uint8_t 368 StringExtractorGDBRemote::GetError () 369 { 370 if (GetResponseType() == eError) 371 { 372 SetFilePos(1); 373 return GetHexU8(255); 374 } 375 return 0; 376 } 377 378 size_t 379 StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str) 380 { 381 // Just get the data bytes in the string as GDBRemoteCommunication::CheckForPacket() 382 // already removes any 0x7d escaped characters. If any 0x7d characters are left in 383 // the packet, then they are supposed to be there... 384 str.clear(); 385 const size_t bytes_left = GetBytesLeft(); 386 if (bytes_left > 0) 387 { 388 str.assign(m_packet, m_index, bytes_left); 389 m_index += bytes_left; 390 } 391 return str.size(); 392 } 393 394