Removed using namespace directive for class member function definitions in source files

This commit is contained in:
Nav
2022-02-05 15:32:08 +00:00
parent 9bbc534973
commit 53a3c815d7
116 changed files with 13113 additions and 12664 deletions

View File

@@ -2,8 +2,9 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void CommandPacket::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void CommandPacket::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}

View File

@@ -4,126 +4,138 @@
#include <memory>
#include <map>
using namespace Bloom::DebugServers::Gdb;
using namespace Bloom::DebugServers::Gdb::CommandPackets;
namespace Bloom::DebugServers::Gdb
{
using CommandPackets::CommandPacket;
std::vector<std::vector<unsigned char>> CommandPacketFactory::extractRawPackets(std::vector<unsigned char> buffer) {
std::vector<std::vector<unsigned char>> output;
std::vector<std::vector<unsigned char>> CommandPacketFactory::extractRawPackets(
std::vector<unsigned char> buffer
) {
std::vector<std::vector<unsigned char>> output;
std::size_t bufferIndex;
std::size_t bufferSize = buffer.size();
unsigned char byte;
for (bufferIndex = 0; bufferIndex < bufferSize; bufferIndex++) {
byte = buffer[bufferIndex];
std::size_t bufferIndex;
std::size_t bufferSize = buffer.size();
unsigned char byte;
for (bufferIndex = 0; bufferIndex < bufferSize; bufferIndex++) {
byte = buffer[bufferIndex];
if (byte == 0x03) {
/*
* This is an interrupt packet - it doesn't carry any of the usual packet frame bytes, so we'll just
* add them here, in order to keep things consistent.
*
* Because we're effectively faking the packet frame, we can use any value for the checksum.
*/
output.push_back({'$', byte, '#', 'F', 'F'});
if (byte == 0x03) {
/*
* This is an interrupt packet - it doesn't carry any of the usual packet frame bytes, so we'll just
* add them here, in order to keep things consistent.
*
* Because we're effectively faking the packet frame, we can use any value for the checksum.
*/
output.push_back({'$', byte, '#', 'F', 'F'});
} else if (byte == '$') {
// Beginning of packet
std::vector<unsigned char> rawPacket;
rawPacket.push_back('$');
} else if (byte == '$') {
// Beginning of packet
std::vector<unsigned char> rawPacket;
rawPacket.push_back('$');
auto packetIndex = bufferIndex;
bool validPacket = false;
bool isByteEscaped = false;
auto packetIndex = bufferIndex;
bool validPacket = false;
bool isByteEscaped = false;
for (packetIndex++; packetIndex < bufferSize; packetIndex++) {
byte = buffer[packetIndex];
for (packetIndex++; packetIndex < bufferSize; packetIndex++) {
byte = buffer[packetIndex];
if (byte == '}' && !isByteEscaped) {
isByteEscaped = true;
continue;
}
if (byte == '}' && !isByteEscaped) {
isByteEscaped = true;
continue;
}
if (byte == '$' && !isByteEscaped) {
// Unexpected end of packet
validPacket = false;
break;
}
if (byte == '#' && !isByteEscaped) {
// End of packet data
if ((bufferSize - 1) < (packetIndex + 2)) {
// There should be at least two more bytes in the buffer, for the checksum.
if (byte == '$' && !isByteEscaped) {
// Unexpected end of packet
validPacket = false;
break;
}
if (byte == '#' && !isByteEscaped) {
// End of packet data
if ((bufferSize - 1) < (packetIndex + 2)) {
// There should be at least two more bytes in the buffer, for the checksum.
break;
}
rawPacket.push_back(byte);
// Add the checksum bytes and break the loop
rawPacket.push_back(buffer[++packetIndex]);
rawPacket.push_back(buffer[++packetIndex]);
validPacket = true;
break;
}
if (isByteEscaped) {
// Escaped bytes are XOR'd with a 0x20 mask.
byte ^= 0x20;
isByteEscaped = false;
}
rawPacket.push_back(byte);
// Add the checksum bytes and break the loop
rawPacket.push_back(buffer[++packetIndex]);
rawPacket.push_back(buffer[++packetIndex]);
validPacket = true;
break;
}
if (isByteEscaped) {
// Escaped bytes are XOR'd with a 0x20 mask.
byte ^= 0x20;
isByteEscaped = false;
if (validPacket) {
output.push_back(rawPacket);
bufferIndex = packetIndex;
}
rawPacket.push_back(byte);
}
if (validPacket) {
output.push_back(rawPacket);
bufferIndex = packetIndex;
}
}
return output;
}
return output;
}
std::unique_ptr<CommandPacket> CommandPacketFactory::create(std::vector<unsigned char> rawPacket) {
if (rawPacket.size() == 5 && rawPacket[1] == 0x03) {
// This is an interrupt request - create a fake packet for it
return std::make_unique<CommandPackets::InterruptExecution>(rawPacket);
}
auto rawPacketString = std::string(rawPacket.begin(), rawPacket.end());
if (rawPacketString.size() >= 2) {
/*
* First byte of the raw packet will be 0x24 ('$'), so find() should return 1, not 0, when
* looking for a command identifier string.
*/
if (rawPacketString.find("qSupported") == 1) {
return std::make_unique<CommandPackets::SupportedFeaturesQuery>(rawPacket);
} else if (rawPacketString[1] == 'g' || rawPacketString[1] == 'p') {
return std::make_unique<CommandPackets::ReadRegisters>(rawPacket);
} else if (rawPacketString[1] == 'P') {
return std::make_unique<CommandPackets::WriteRegister>(rawPacket);
} else if (rawPacketString[1] == 'c') {
return std::make_unique<CommandPackets::ContinueExecution>(rawPacket);
} else if (rawPacketString[1] == 's') {
return std::make_unique<CommandPackets::StepExecution>(rawPacket);
} else if (rawPacketString[1] == 'm') {
return std::make_unique<CommandPackets::ReadMemory>(rawPacket);
} else if (rawPacketString[1] == 'M') {
return std::make_unique<CommandPackets::WriteMemory>(rawPacket);
} else if (rawPacketString[1] == 'Z') {
return std::make_unique<CommandPackets::SetBreakpoint>(rawPacket);
} else if (rawPacketString[1] == 'z') {
return std::make_unique<CommandPackets::RemoveBreakpoint>(rawPacket);
std::unique_ptr<CommandPacket> CommandPacketFactory::create(std::vector<unsigned char> rawPacket) {
if (rawPacket.size() == 5 && rawPacket[1] == 0x03) {
// This is an interrupt request - create a fake packet for it
return std::make_unique<CommandPackets::InterruptExecution>(rawPacket);
}
}
return std::make_unique<CommandPacket>(rawPacket);
auto rawPacketString = std::string(rawPacket.begin(), rawPacket.end());
if (rawPacketString.size() >= 2) {
/*
* First byte of the raw packet will be 0x24 ('$'), so find() should return 1, not 0, when
* looking for a command identifier string.
*/
if (rawPacketString.find("qSupported") == 1) {
return std::make_unique<CommandPackets::SupportedFeaturesQuery>(rawPacket);
}
if (rawPacketString[1] == 'g' || rawPacketString[1] == 'p') {
return std::make_unique<CommandPackets::ReadRegisters>(rawPacket);
}
if (rawPacketString[1] == 'P') {
return std::make_unique<CommandPackets::WriteRegister>(rawPacket);
}
if (rawPacketString[1] == 'c') {
return std::make_unique<CommandPackets::ContinueExecution>(rawPacket);
}
if (rawPacketString[1] == 's') {
return std::make_unique<CommandPackets::StepExecution>(rawPacket);
}
if (rawPacketString[1] == 'm') {
return std::make_unique<CommandPackets::ReadMemory>(rawPacket);
}
if (rawPacketString[1] == 'M') {
return std::make_unique<CommandPackets::WriteMemory>(rawPacket);
}
if (rawPacketString[1] == 'Z') {
return std::make_unique<CommandPackets::SetBreakpoint>(rawPacket);
}
if (rawPacketString[1] == 'z') {
return std::make_unique<CommandPackets::RemoveBreakpoint>(rawPacket);
}
}
return std::make_unique<CommandPacket>(rawPacket);
}
}

View File

@@ -4,16 +4,17 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void ContinueExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void ContinueExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void ContinueExecution::init() {
if (this->data.size() > 1) {
this->fromProgramCounter = static_cast<std::uint32_t>(
std::stoi(std::string(this->data.begin(), this->data.end()), nullptr, 16)
);
void ContinueExecution::init() {
if (this->data.size() > 1) {
this->fromProgramCounter = static_cast<std::uint32_t>(
std::stoi(std::string(this->data.begin(), this->data.end()), nullptr, 16)
);
}
}
}

View File

@@ -2,8 +2,9 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
void InterruptExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void InterruptExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
}

View File

@@ -2,43 +2,47 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void ReadMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void ReadMemory::init() {
if (this->data.size() < 4) {
throw Exception("Invalid packet length");
void ReadMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
auto packetString = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 1),
static_cast<int>(this->data.size() - 1)
);
void ReadMemory::init() {
if (this->data.size() < 4) {
throw Exception("Invalid packet length");
}
/*
* The read memory ('m') packet consists of two segments, an address and a number of bytes to read.
* These are separated by a comma character.
*/
auto packetSegments = packetString.split(",");
auto packetString = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 1),
static_cast<int>(this->data.size() - 1)
);
if (packetSegments.size() != 2) {
throw Exception("Unexpected number of segments in packet data: " + std::to_string(packetSegments.size()));
}
/*
* The read memory ('m') packet consists of two segments, an address and a number of bytes to read.
* These are separated by a comma character.
*/
auto packetSegments = packetString.split(",");
bool conversionStatus = false;
this->startAddress = packetSegments.at(0).toUInt(&conversionStatus, 16);
if (packetSegments.size() != 2) {
throw Exception(
"Unexpected number of segments in packet data: " + std::to_string(packetSegments.size())
);
}
if (!conversionStatus) {
throw Exception("Failed to parse start address from read memory packet data");
}
bool conversionStatus = false;
this->startAddress = packetSegments.at(0).toUInt(&conversionStatus, 16);
this->bytes = packetSegments.at(1).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse start address from read memory packet data");
}
if (!conversionStatus) {
throw Exception("Failed to parse read length from read memory packet data");
this->bytes = packetSegments.at(1).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse read length from read memory packet data");
}
}
}

View File

@@ -2,15 +2,18 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void ReadRegisters::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void ReadRegisters::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void ReadRegisters::init() {
if (this->data.size() >= 2 && this->data.front() == 'p') {
// This command packet is requesting a specific register
this->registerNumber = static_cast<size_t>(std::stoi(std::string(this->data.begin() + 1, this->data.end())));
void ReadRegisters::init() {
if (this->data.size() >= 2 && this->data.front() == 'p') {
// This command packet is requesting a specific register
this->registerNumber = static_cast<size_t>(
std::stoi(std::string(this->data.begin() + 1, this->data.end()))
);
}
}
}

View File

@@ -4,36 +4,38 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void RemoveBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void RemoveBreakpoint::init() {
if (data.size() < 6) {
throw Exception("Unexpected RemoveBreakpoint packet size");
void RemoveBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
// z0 = SW breakpoint, z1 = HW breakpoint
this->type = (data[1] == 0) ? BreakpointType::SOFTWARE_BREAKPOINT : (data[1] == 1) ?
BreakpointType::HARDWARE_BREAKPOINT : BreakpointType::UNKNOWN;
void RemoveBreakpoint::init() {
if (data.size() < 6) {
throw Exception("Unexpected RemoveBreakpoint packet size");
}
auto packetData = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 2),
static_cast<int>(this->data.size() - 2)
);
// z0 = SW breakpoint, z1 = HW breakpoint
this->type = (data[1] == 0) ? BreakpointType::SOFTWARE_BREAKPOINT : (data[1] == 1) ?
BreakpointType::HARDWARE_BREAKPOINT : BreakpointType::UNKNOWN;
auto packetSegments = packetData.split(",");
if (packetSegments.size() < 3) {
throw Exception("Unexpected number of packet segments in RemoveBreakpoint packet");
}
auto packetData = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 2),
static_cast<int>(this->data.size() - 2)
);
bool conversionStatus = true;
this->address = packetSegments.at(1).toUInt(&conversionStatus, 16);
auto packetSegments = packetData.split(",");
if (packetSegments.size() < 3) {
throw Exception("Unexpected number of packet segments in RemoveBreakpoint packet");
}
if (!conversionStatus) {
throw Exception("Failed to convert address hex value from RemoveBreakpoint packet.");
bool conversionStatus = true;
this->address = packetSegments.at(1).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to convert address hex value from RemoveBreakpoint packet.");
}
}
}

View File

@@ -1,40 +1,41 @@
#include "SetBreakpoint.hpp"
#include <QtCore/QString>
#include <QtCore/QStringList>
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void SetBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void SetBreakpoint::init() {
if (data.size() < 6) {
throw Exception("Unexpected SetBreakpoint packet size");
void SetBreakpoint::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
// Z0 = SW breakpoint, Z1 = HW breakpoint
this->type = (data[1] == 0) ? BreakpointType::SOFTWARE_BREAKPOINT : (data[1] == 1) ?
BreakpointType::HARDWARE_BREAKPOINT : BreakpointType::UNKNOWN;
void SetBreakpoint::init() {
if (data.size() < 6) {
throw Exception("Unexpected SetBreakpoint packet size");
}
auto packetData = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 2),
static_cast<int>(this->data.size() - 2)
);
// Z0 = SW breakpoint, Z1 = HW breakpoint
this->type = (data[1] == 0) ? BreakpointType::SOFTWARE_BREAKPOINT : (data[1] == 1) ?
BreakpointType::HARDWARE_BREAKPOINT : BreakpointType::UNKNOWN;
auto packetSegments = packetData.split(",");
if (packetSegments.size() < 3) {
throw Exception("Unexpected number of packet segments in SetBreakpoint packet");
}
auto packetData = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 2),
static_cast<int>(this->data.size() - 2)
);
bool conversionStatus = true;
this->address = packetSegments.at(1).toUInt(&conversionStatus, 16);
auto packetSegments = packetData.split(",");
if (packetSegments.size() < 3) {
throw Exception("Unexpected number of packet segments in SetBreakpoint packet");
}
if (!conversionStatus) {
throw Exception("Failed to convert address hex value from SetBreakpoint packet.");
bool conversionStatus = true;
this->address = packetSegments.at(1).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to convert address hex value from SetBreakpoint packet.");
}
}
}

View File

@@ -1,18 +1,20 @@
#include "StepExecution.hpp"
#include <cstdint>
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
#include "StepExecution.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void StepExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void StepExecution::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void StepExecution::init() {
if (this->data.size() > 1) {
this->fromProgramCounter = static_cast<std::uint32_t>(
std::stoi(std::string(this->data.begin(), this->data.end()), nullptr, 16)
);
void StepExecution::init() {
if (this->data.size() > 1) {
this->fromProgramCounter = static_cast<std::uint32_t>(
std::stoi(std::string(this->data.begin(), this->data.end()), nullptr, 16)
);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace Bloom::DebugServers::Gdb::CommandPackets
/**
* The address from which to begin the step.
*/
std::optional<size_t> fromProgramCounter;
std::optional<std::size_t> fromProgramCounter;
explicit StepExecution(const std::vector<unsigned char>& rawPacket): CommandPacket(rawPacket) {
init();

View File

@@ -4,38 +4,39 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
void SupportedFeaturesQuery::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void SupportedFeaturesQuery::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void SupportedFeaturesQuery::init() {
/*
* For qSupported packets, supported and unsupported GDB features are reported in the packet
* data, where each GDB feature is separated by a semicolon.
*/
void SupportedFeaturesQuery::init() {
/*
* For qSupported packets, supported and unsupported GDB features are reported in the packet
* data, where each GDB feature is separated by a semicolon.
*/
// The "qSupported:" prefix occupies 11 bytes
if (data.size() > 11) {
auto packetData = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 11),
static_cast<int>(this->data.size() - 11)
);
// The "qSupported:" prefix occupies 11 bytes
if (data.size() > 11) {
auto packetData = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 11),
static_cast<int>(this->data.size() - 11)
);
auto featureList = packetData.split(";");
auto gdbFeatureMapping = getGdbFeatureToNameMapping();
auto featureList = packetData.split(";");
auto gdbFeatureMapping = getGdbFeatureToNameMapping();
for (int i = 0; i < featureList.size(); i++) {
auto featureString = featureList.at(i);
for (int i = 0; i < featureList.size(); i++) {
auto featureString = featureList.at(i);
// We only care about supported features. Supported features will precede a '+' character.
if (featureString[featureString.size() - 1] == '+') {
featureString.remove('+');
// We only care about supported features. Supported features will precede a '+' character.
if (featureString[featureString.size() - 1] == '+') {
featureString.remove('+');
auto feature = gdbFeatureMapping.valueAt(featureString.toStdString());
if (feature.has_value()) {
this->supportedFeatures.insert(static_cast<decltype(feature)::value_type>(feature.value()));
auto feature = gdbFeatureMapping.valueAt(featureString.toStdString());
if (feature.has_value()) {
this->supportedFeatures.insert(static_cast<decltype(feature)::value_type>(feature.value()));
}
}
}
}

View File

@@ -2,52 +2,59 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void WriteMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void WriteMemory::init() {
if (this->data.size() < 4) {
throw Exception("Invalid packet length");
void WriteMemory::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
auto packetString = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 1),
static_cast<int>(this->data.size() - 1)
);
void WriteMemory::init() {
if (this->data.size() < 4) {
throw Exception("Invalid packet length");
}
/*
* The write memory ('M') packet consists of three segments, an address, a length and a buffer.
* The address and length are separated by a comma character, and the buffer proceeds a colon character.
*/
auto packetSegments = packetString.split(",");
if (packetSegments.size() != 2) {
throw Exception("Unexpected number of segments in packet data: " + std::to_string(packetSegments.size()));
}
auto packetString = QString::fromLocal8Bit(
reinterpret_cast<const char*>(this->data.data() + 1),
static_cast<int>(this->data.size() - 1)
);
bool conversionStatus = false;
this->startAddress = packetSegments.at(0).toUInt(&conversionStatus, 16);
/*
* The write memory ('M') packet consists of three segments, an address, a length and a buffer.
* The address and length are separated by a comma character, and the buffer proceeds a colon character.
*/
auto packetSegments = packetString.split(",");
if (packetSegments.size() != 2) {
throw Exception(
"Unexpected number of segments in packet data: " + std::to_string(packetSegments.size())
);
}
if (!conversionStatus) {
throw Exception("Failed to parse start address from write memory packet data");
}
bool conversionStatus = false;
this->startAddress = packetSegments.at(0).toUInt(&conversionStatus, 16);
auto lengthAndBufferSegments = packetSegments.at(1).split(":");
if (lengthAndBufferSegments.size() != 2) {
throw Exception("Unexpected number of segments in packet data: " + std::to_string(lengthAndBufferSegments.size()));
}
if (!conversionStatus) {
throw Exception("Failed to parse start address from write memory packet data");
}
auto bufferSize = lengthAndBufferSegments.at(0).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse write length from write memory packet data");
}
auto lengthAndBufferSegments = packetSegments.at(1).split(":");
if (lengthAndBufferSegments.size() != 2) {
throw Exception(
"Unexpected number of segments in packet data: "
+ std::to_string(lengthAndBufferSegments.size())
);
}
this->buffer = Packet::hexToData(lengthAndBufferSegments.at(1).toStdString());
auto bufferSize = lengthAndBufferSegments.at(0).toUInt(&conversionStatus, 16);
if (!conversionStatus) {
throw Exception("Failed to parse write length from write memory packet data");
}
if (this->buffer.size() != bufferSize) {
throw Exception("Buffer size does not match length value given in write memory packet");
this->buffer = Packet::hexToData(lengthAndBufferSegments.at(1).toStdString());
if (this->buffer.size() != bufferSize) {
throw Exception("Buffer size does not match length value given in write memory packet");
}
}
}

View File

@@ -3,27 +3,29 @@
#include "src/DebugServers/GdbRsp/GdbRspDebugServer.hpp"
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugServers::Gdb::CommandPackets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugServers::Gdb::CommandPackets
{
using namespace Bloom::Exceptions;
void WriteRegister::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
void WriteRegister::init() {
// The P packet updates a single register
auto packet = std::string(this->data.begin(), this->data.end());
if (packet.size() < 4) {
throw Exception("Invalid P command packet - insufficient data in packet.");
void WriteRegister::dispatchToHandler(Gdb::GdbRspDebugServer& gdbRspDebugServer) {
gdbRspDebugServer.handleGdbPacket(*this);
}
if (packet.find('=') == std::string::npos) {
throw Exception("Invalid P command packet - unexpected format");
}
void WriteRegister::init() {
// The P packet updates a single register
auto packet = std::string(this->data.begin(), this->data.end());
auto packetSegments = QString::fromStdString(packet).split("=");
this->registerNumber = static_cast<int>(packetSegments.front().mid(1).toUInt(nullptr, 16));
this->registerValue = Packet::hexToData(packetSegments.back().toStdString());
std::reverse(this->registerValue.begin(), this->registerValue.end());
if (packet.size() < 4) {
throw Exception("Invalid P command packet - insufficient data in packet.");
}
if (packet.find('=') == std::string::npos) {
throw Exception("Invalid P command packet - unexpected format");
}
auto packetSegments = QString::fromStdString(packet).split("=");
this->registerNumber = static_cast<int>(packetSegments.front().mid(1).toUInt(nullptr, 16));
this->registerValue = Packet::hexToData(packetSegments.back().toStdString());
std::reverse(this->registerValue.begin(), this->registerValue.end());
}
}