diff options
Diffstat (limited to 'gdbremote_parser.cpp')
-rw-r--r-- | gdbremote_parser.cpp | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/gdbremote_parser.cpp b/gdbremote_parser.cpp index 31e6af9..6e61802 100644 --- a/gdbremote_parser.cpp +++ b/gdbremote_parser.cpp @@ -2,6 +2,7 @@ */ #include "gdbremote_parser.hpp" +#include "utils.hpp" #include <cctype> #include <cassert> @@ -169,6 +170,7 @@ struct Command { return Packet::None(); 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); return Packet{ @@ -176,6 +178,38 @@ struct Command { std::make_unique<const PacketDataReadMemory>(offset, lenght), }; } + static Packet parseWriteMemory(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 data parameter always present? + 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 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]); + } + return Packet{ + PacketType::kWriteMemory, + std::make_unique<const PacketDataWriteMemory>(offset, lenght, std::move(data)), + }; + } static Packet parseReadGeneralRegisters(const std::vector<Token>&&) { return Packet{PacketType::kReadGeneralRegisters}; @@ -215,6 +249,7 @@ static const Command commands[] = { { "vCont", Command::parseContinueVCont }, { "c", Command::parseContinue }, { "m", Command::parseReadMemory }, + { "M", Command::parseWriteMemory }, { "g", Command::parseReadGeneralRegisters }, { "s", Command::parseStep }, { "Z", Command::parseSetBreakpoint }, @@ -234,14 +269,6 @@ Packet Packet::Parse(std::string packet_data) return Packet::None(); } -static inline uint8_t parseChecksumFromHexChars(uint8_t first, uint8_t second) -{ - // Assume, that given bytes are valid hex digits in ASCII - first = ((first & 0x40) ? (first + 9) : first) & 0x0f; - second = ((second & 0x40) ? (second + 9) : second) & 0x0f; - return ((first << 4) | second) & 0xff; -} - std::unique_ptr<ExchangeResult> ExchangeContext::Consume(uint8_t byte) { _last_packet += byte; @@ -280,7 +307,7 @@ std::unique_ptr<ExchangeResult> ExchangeContext::Consume(uint8_t byte) transit(ParsingState::kIdle); if (isxdigit(byte)) { const uint8_t given_checksum = - parseChecksumFromHexChars(_given_checksum_first_byte, byte); + Utils::ParseByteFromHexChars(_given_checksum_first_byte, byte); if (given_checksum == checksum) { return ExchangeResult::Ack(packet_data); } else { |