Home | History | Annotate | Download | only in Utility
      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         }
     98         break;
     99 
    100     case 'q':
    101         switch (packet_cstr[1])
    102         {
    103         case 's':
    104             if (PACKET_MATCHES ("qsProcessInfo"))               return eServerPacketType_qsProcessInfo;
    105             break;
    106 
    107         case 'f':
    108             if (PACKET_STARTS_WITH ("qfProcessInfo"))           return eServerPacketType_qfProcessInfo;
    109             break;
    110 
    111         case 'C':
    112             if (packet_size == 2)                               return eServerPacketType_qC;
    113             break;
    114 
    115         case 'G':
    116             if (PACKET_STARTS_WITH ("qGroupName:"))             return eServerPacketType_qGroupName;
    117             break;
    118 
    119         case 'H':
    120             if (PACKET_MATCHES ("qHostInfo"))                   return eServerPacketType_qHostInfo;
    121             break;
    122 
    123         case 'L':
    124             if (PACKET_MATCHES ("qLaunchGDBServer"))            return eServerPacketType_qLaunchGDBServer;
    125             if (PACKET_MATCHES ("qLaunchSuccess"))              return eServerPacketType_qLaunchSuccess;
    126             break;
    127 
    128         case 'P':
    129             if (PACKET_STARTS_WITH ("qProcessInfoPID:"))        return eServerPacketType_qProcessInfoPID;
    130             break;
    131 
    132         case 'S':
    133             if (PACKET_STARTS_WITH ("qSpeedTest:"))             return eServerPacketType_qSpeedTest;
    134             break;
    135 
    136         case 'U':
    137             if (PACKET_STARTS_WITH ("qUserName:"))              return eServerPacketType_qUserName;
    138             break;
    139         }
    140         break;
    141     }
    142     return eServerPacketType_unimplemented;
    143 }
    144 
    145 bool
    146 StringExtractorGDBRemote::IsOKResponse() const
    147 {
    148     return GetResponseType () == eOK;
    149 }
    150 
    151 
    152 bool
    153 StringExtractorGDBRemote::IsUnsupportedResponse() const
    154 {
    155     return GetResponseType () == eUnsupported;
    156 }
    157 
    158 bool
    159 StringExtractorGDBRemote::IsNormalResponse() const
    160 {
    161     return GetResponseType () == eResponse;
    162 }
    163 
    164 bool
    165 StringExtractorGDBRemote::IsErrorResponse() const
    166 {
    167     return GetResponseType () == eError &&
    168            m_packet.size() == 3 &&
    169            isxdigit(m_packet[1]) &&
    170            isxdigit(m_packet[2]);
    171 }
    172 
    173 uint8_t
    174 StringExtractorGDBRemote::GetError ()
    175 {
    176     if (GetResponseType() == eError)
    177     {
    178         SetFilePos(1);
    179         return GetHexU8(255);
    180     }
    181     return 0;
    182 }
    183