2021-08-07 17:07:04 +01:00
|
|
|
#include "WriteRegister.hpp"
|
2021-10-02 17:39:27 +01:00
|
|
|
|
2022-03-31 21:52:46 +01:00
|
|
|
#include "src/DebugServer/Gdb/ResponsePackets/TargetStopped.hpp"
|
|
|
|
|
#include "src/DebugServer/Gdb/ResponsePackets/OkResponsePacket.hpp"
|
|
|
|
|
#include "src/DebugServer/Gdb/ResponsePackets/ErrorResponsePacket.hpp"
|
2022-03-24 19:17:41 +00:00
|
|
|
|
|
|
|
|
#include "src/Targets/TargetRegister.hpp"
|
|
|
|
|
|
|
|
|
|
#include "src/Logger/Logger.hpp"
|
2021-05-24 20:58:49 +01:00
|
|
|
#include "src/Exceptions/Exception.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-03-31 16:05:39 +01:00
|
|
|
namespace Bloom::DebugServer::Gdb::CommandPackets
|
2022-02-05 15:32:08 +00:00
|
|
|
{
|
2022-03-24 19:17:41 +00:00
|
|
|
using Targets::TargetRegister;
|
|
|
|
|
using Targets::TargetRegisterDescriptors;
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-03-24 19:17:41 +00:00
|
|
|
using ResponsePackets::ResponsePacket;
|
|
|
|
|
using ResponsePackets::OkResponsePacket;
|
|
|
|
|
using ResponsePackets::ErrorResponsePacket;
|
|
|
|
|
|
|
|
|
|
using Exceptions::Exception;
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
void WriteRegister::init() {
|
|
|
|
|
// The P packet updates a single register
|
|
|
|
|
auto packet = std::string(this->data.begin(), this->data.end());
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
if (packet.size() < 4) {
|
|
|
|
|
throw Exception("Invalid P command packet - insufficient data in packet.");
|
|
|
|
|
}
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
if (packet.find('=') == std::string::npos) {
|
|
|
|
|
throw Exception("Invalid P command packet - unexpected format");
|
|
|
|
|
}
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
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());
|
|
|
|
|
}
|
2022-03-24 19:17:41 +00:00
|
|
|
|
|
|
|
|
void WriteRegister::handle(DebugSession& debugSession, TargetControllerConsole& targetControllerConsole) {
|
|
|
|
|
Logger::debug("Handling WriteRegister packet");
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
auto targetRegisterDescriptor = debugSession.targetDescriptor.getTargetRegisterDescriptorFromNumber(this->registerNumber);
|
|
|
|
|
|
|
|
|
|
const auto valueSize = this->registerValue.size();
|
|
|
|
|
if (valueSize > 0 && valueSize > targetRegisterDescriptor.size) {
|
|
|
|
|
// Attempt to trim the higher zero-value bytes from the register value, until we reach the correct size.
|
|
|
|
|
for (auto i = this->registerValue.size() - 1; i >= targetRegisterDescriptor.size; i--) {
|
|
|
|
|
if (this->registerValue.at(i) != 0x00) {
|
|
|
|
|
// If we reach a non-zero byte, we cannot trim anymore without changing the data
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->registerValue.erase(this->registerValue.begin() + i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this->registerValue.size() > targetRegisterDescriptor.size) {
|
|
|
|
|
const auto& gdbRegisterDescriptor = debugSession.targetDescriptor.getRegisterDescriptorFromNumber(this->registerNumber);
|
|
|
|
|
throw Exception("Cannot set value for " + gdbRegisterDescriptor.name
|
|
|
|
|
+ " - value size exceeds register size."
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
targetControllerConsole.writeRegisters({
|
|
|
|
|
TargetRegister(targetRegisterDescriptor, this->registerValue)
|
|
|
|
|
});
|
|
|
|
|
debugSession.connection.writePacket(OkResponsePacket());
|
|
|
|
|
|
|
|
|
|
} catch (const Exception& exception) {
|
|
|
|
|
Logger::error("Failed to write registers - " + exception.getMessage());
|
|
|
|
|
debugSession.connection.writePacket(ErrorResponsePacket());
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-04 21:04:12 +01:00
|
|
|
}
|