diff options
Diffstat (limited to 'gdbremote_parser.cpp')
-rw-r--r-- | gdbremote_parser.cpp | 78 |
1 files changed, 35 insertions, 43 deletions
diff --git a/gdbremote_parser.cpp b/gdbremote_parser.cpp index 641590f..31e6af9 100644 --- a/gdbremote_parser.cpp +++ b/gdbremote_parser.cpp @@ -14,7 +14,6 @@ enum class TokenType: uint8_t { kSeparatorComma, kSeparatorColon, kSeparatorSemicolon, - kNumeric, kHexNumeric, kArbitrary, }; @@ -24,13 +23,6 @@ static inline bool isseparator(uint8_t byte) return ':' == byte || ';' == byte || ',' == byte; } -static inline bool IsTokenTypeSeparator(TokenType token_type) -{ - return token_type == TokenType::kSeparatorColon || - token_type == TokenType::kSeparatorComma || - token_type == TokenType::kSeparatorSemicolon; -} - static inline TokenType separatorTypeFromByte(uint8_t byte) { if (':' == byte) return TokenType::kSeparatorColon; @@ -42,12 +34,17 @@ struct Token { TokenType type{}; std::string data{}; - static std::vector<Token> Tokenize(std::string packet_data) + static std::vector<Token> Tokenize( + const std::string& packet_data, const std::string& command) { if (packet_data.length() == 0) return std::vector<Token>{}; std::vector<Token> tokens{}; + const size_t cmdlen = command.length(); + if (cmdlen > 0) { + tokens.push_back(Token{TokenType::kArbitrary, command}); + } TokenType type{}; - size_t i{}, offset{}; + size_t i{command.length()}, offset{command.length()}; for (; i < packet_data.length(); i++) { assert(type != TokenType::kSeparatorColon); assert(type != TokenType::kSeparatorSemicolon); @@ -65,10 +62,6 @@ struct Token { }); offset++; type = TokenType::kUnknown; - } else if (isdigit(byte)) { - if (type == TokenType::kUnknown) { - type = TokenType::kNumeric; - } } else if (isxdigit(byte)) { if (type != TokenType::kArbitrary) { type = TokenType::kHexNumeric; @@ -152,10 +145,9 @@ struct Command { } static Packet parseContinueVCont(const std::vector<Token>&& tokens) { - const std::string first = tokens[0].data; - constexpr size_t command_len = strlen("vCont"); + const std::string first_arg = tokens[1].data; // Check if it is "vCont?" command - if (first.length() > command_len && first[command_len] == '?') { + if (first_arg == "?") { return Packet{PacketType::kContinueAskSupported}; } // TODO arguments @@ -167,20 +159,17 @@ struct Command { } static Packet parseReadMemory(const std::vector<Token>&& tokens) { - if (tokens.size() < 3 || - tokens[0].type != TokenType::kArbitrary || - !IsTokenTypeSeparator(tokens[1].type) || - tokens[2].type != TokenType::kNumeric) - { + if (tokens.size() < 4) return Packet::None(); - } - constexpr size_t command_len = strlen("m"); - const std::string first = tokens[0].data; - const std::string second = tokens[2].data; - const uint32_t offset = strtol( - first.substr(command_len, first.length()-command_len).c_str(), - nullptr, - 16); + if (tokens[1].type != TokenType::kHexNumeric) + return Packet::None(); + if (tokens[2].type != TokenType::kSeparatorComma) + return Packet::None(); + if (tokens[3].type != TokenType::kHexNumeric) + return Packet::None(); + const std::string first = tokens[1].data; + const std::string second = tokens[3].data; + const uint32_t offset = strtol(first.c_str(), nullptr, 16); const uint32_t lenght = strtol(second.c_str(), nullptr, 16); return Packet{ PacketType::kReadMemory, @@ -195,6 +184,17 @@ struct Command { { return Packet{PacketType::kStep}; } + static Packet parseSetBreakpoint(const std::vector<Token>&&) + { + return Packet{ + PacketType::kSetBreakpoint, + }; + } + static Packet parseDeleteBreakpoint(const std::vector<Token>&&) + { + // TODO arguments + return Packet{PacketType::kDeleteBreakpoint}; + } }; static const Command commands[] = { @@ -217,25 +217,17 @@ static const Command commands[] = { { "m", Command::parseReadMemory }, { "g", Command::parseReadGeneralRegisters }, { "s", Command::parseStep }, + { "Z", Command::parseSetBreakpoint }, + { "z", Command::parseDeleteBreakpoint }, }; Packet Packet::Parse(std::string packet_data) { - const auto tokens = Token::Tokenize(packet_data); - if (tokens.size() == 0) { - printf("Warning: no tokens to parse\n"); - return Packet::None(); - } - const auto first_token = tokens[0]; for (const auto& command: commands) { const auto cmdlen = command.name.length(); - const auto toklen = first_token.data.length(); - // Make sure first token fully includes the command from the beginning - // and not necessary fully equals to it. - // TODO tokenize as if the command is always a separate token - if (cmdlen <= toklen && 0 == memcmp( - &command.name[0], &first_token.data[0], cmdlen)) - { + const auto packetlen = packet_data.length(); + if (cmdlen <= packetlen && 0 == memcmp(&command.name[0], &packet_data[0], cmdlen)) { + const auto tokens = Token::Tokenize(packet_data, command.name); return command.parse(std::move(tokens)); } } |