summaryrefslogtreecommitdiff
path: root/gdbremote_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gdbremote_parser.cpp')
-rw-r--r--gdbremote_parser.cpp45
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 {