diff options
Diffstat (limited to 'gdbremote_parser.cpp')
-rw-r--r-- | gdbremote_parser.cpp | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/gdbremote_parser.cpp b/gdbremote_parser.cpp index 6e61802..b9115be 100644 --- a/gdbremote_parser.cpp +++ b/gdbremote_parser.cpp @@ -168,8 +168,8 @@ struct Command { 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 std::string& first = tokens[1].data; + const std::string& second = tokens[3].data; // TODO handle number parsing error (ERANGE) const uint32_t offset = strtol(first.c_str(), nullptr, 16); const uint32_t lenght = strtol(second.c_str(), nullptr, 16); @@ -188,23 +188,23 @@ struct Command { return Packet::None(); if (tokens[3].type != TokenType::kHexNumeric) return Packet::None(); - // XXX Is data parameter always present? + // XXX Is data parameter always present or is it optional? if (tokens[4].type != TokenType::kSeparatorColon) return Packet::None(); if (tokens[5].type != TokenType::kHexNumeric) return Packet::None(); // TODO handle number parsing error (ERANGE) - const std::string first = tokens[1].data; - const std::string second = tokens[3].data; - const std::string data_raw = tokens[5].data; + const std::string& first = tokens[1].data; + const std::string& second = tokens[3].data; + const std::string& data_raw = tokens[5].data; const size_t data_len = data_raw.length()/2; std::vector<uint8_t> data(data_len); assert(data.size() == data_len); - const uint32_t offset = strtol(first.c_str(), nullptr, 16); - const uint32_t lenght = strtol(second.c_str(), nullptr, 16); for (size_t i = 0; i < data_len; i++) { data[i] = Utils::ParseByteFromHexChars(data_raw[i*2], data_raw[i*2+1]); } + const uint32_t offset = strtol(first.c_str(), nullptr, 16); + const uint32_t lenght = strtol(second.c_str(), nullptr, 16); return Packet{ PacketType::kWriteMemory, std::make_unique<const PacketDataWriteMemory>(offset, lenght, std::move(data)), @@ -218,17 +218,37 @@ struct Command { { return Packet{PacketType::kStep}; } - static Packet parseSetBreakpoint(const std::vector<Token>&&) + static Packet parseSetOrDeleteBreakpoint(const std::vector<Token>&& tokens) { + if (tokens.size() < 6) + return Packet::None(); + 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(); + // XXX Is third parameter always present or is it optional? + if (tokens[4].type != TokenType::kSeparatorComma) + return Packet::None(); + if (tokens[5].type != TokenType::kHexNumeric) + return Packet::None(); + const std::string& first = tokens[1].data; + const std::string& second = tokens[3].data; + const std::string& third = tokens[5].data; + const uint32_t type_num = strtol(first.c_str(), nullptr, 16); + const auto type = + (type_num >= static_cast<uint32_t>(BreakpointType::kMin) && + type_num < static_cast<uint32_t>(BreakpointType::kUnsupported)) + ? static_cast<BreakpointType>(type_num) + : BreakpointType::kMin; + const uint32_t offset = strtol(second.c_str(), nullptr, 16); + const uint32_t length = strtol(third.c_str(), nullptr, 16); return Packet{ - PacketType::kSetBreakpoint, + tokens[0].data[0] == 'Z' ? PacketType::kSetBreakpoint : PacketType::kDeleteBreakpoint, + std::make_unique<const PacketDataBreakpoint>(type, offset, length), }; } - static Packet parseDeleteBreakpoint(const std::vector<Token>&&) - { - // TODO arguments - return Packet{PacketType::kDeleteBreakpoint}; - } }; static const Command commands[] = { @@ -252,8 +272,8 @@ static const Command commands[] = { { "M", Command::parseWriteMemory }, { "g", Command::parseReadGeneralRegisters }, { "s", Command::parseStep }, - { "Z", Command::parseSetBreakpoint }, - { "z", Command::parseDeleteBreakpoint }, + { "Z", Command::parseSetOrDeleteBreakpoint }, + { "z", Command::parseSetOrDeleteBreakpoint }, }; Packet Packet::Parse(std::string packet_data) |