Replaced WriteMemoryToTarget event with TC command

This commit is contained in:
Nav
2022-04-30 01:30:57 +01:00
parent 63dc84aba0
commit ffc27a567b
8 changed files with 102 additions and 115 deletions

View File

@@ -28,7 +28,6 @@ namespace Bloom::Events
REGISTERS_WRITTEN_TO_TARGET,
TARGET_EXECUTION_RESUMED,
TARGET_EXECUTION_STOPPED,
WRITE_MEMORY_TO_TARGET,
MEMORY_WRITTEN_TO_TARGET,
SET_BREAKPOINT_ON_TARGET,
REMOVE_BREAKPOINT_ON_TARGET,

View File

@@ -15,7 +15,6 @@
#include "RegistersWrittenToTarget.hpp"
#include "TargetExecutionResumed.hpp"
#include "TargetExecutionStopped.hpp"
#include "WriteMemoryToTarget.hpp"
#include "MemoryWrittenToTarget.hpp"
#include "SetBreakpointOnTarget.hpp"
#include "RemoveBreakpointOnTarget.hpp"

View File

@@ -1,39 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
#include <utility>
#include "Event.hpp"
#include "MemoryWrittenToTarget.hpp"
#include "src/Targets/TargetMemory.hpp"
namespace Bloom::Events
{
class WriteMemoryToTarget: public Event
{
public:
using TargetControllerResponseType = MemoryWrittenToTarget;
static constexpr EventType type = EventType::WRITE_MEMORY_TO_TARGET;
static inline const std::string name = "WriteMemoryToTarget";
Targets::TargetMemoryType memoryType = Targets::TargetMemoryType::RAM;
std::uint32_t startAddress = 0;
Targets::TargetMemoryBuffer buffer;
WriteMemoryToTarget() = default;
WriteMemoryToTarget(
Targets::TargetMemoryType memoryType,
std::uint32_t startAddress,
Targets::TargetMemoryBuffer buffer
): memoryType(memoryType), startAddress(startAddress), buffer(std::move(buffer)) {};
[[nodiscard]] EventType getType() const override {
return WriteMemoryToTarget::type;
}
[[nodiscard]] std::string getName() const override {
return WriteMemoryToTarget::name;
}
};
}

View File

@@ -16,5 +16,6 @@ namespace Bloom::TargetController::Commands
READ_TARGET_MEMORY,
GET_TARGET_STATE,
STEP_TARGET_EXECUTION,
WRITE_TARGET_MEMORY,
};
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include "Command.hpp"
#include "src/TargetController/Responses/TargetMemoryRead.hpp"
#include "src/Targets/TargetMemory.hpp"
namespace Bloom::TargetController::Commands
{
class WriteTargetMemory: public Command
{
public:
static constexpr CommandType type = CommandType::WRITE_TARGET_MEMORY;
static inline const std::string name = "WriteTargetMemory";
Targets::TargetMemoryType memoryType;
std::uint32_t startAddress;
Targets::TargetMemoryBuffer buffer;
explicit WriteTargetMemory(
Targets::TargetMemoryType memoryType,
std::uint32_t startAddress,
const Targets::TargetMemoryBuffer& buffer
)
: memoryType(memoryType)
, startAddress(startAddress)
, buffer(buffer)
{};
[[nodiscard]] CommandType getType() const override {
return WriteTargetMemory::type;
}
[[nodiscard]] bool requiresStoppedTargetState() const override {
return true;
}
};
}

View File

@@ -29,6 +29,7 @@ namespace Bloom::TargetController
using Commands::ReadTargetRegisters;
using Commands::WriteTargetRegisters;
using Commands::ReadTargetMemory;
using Commands::WriteTargetMemory;
using Commands::StepTargetExecution;
using Responses::Response;
@@ -389,11 +390,11 @@ namespace Bloom::TargetController
this->deregisterCommandHandler(ReadTargetRegisters::type);
this->deregisterCommandHandler(WriteTargetRegisters::type);
this->deregisterCommandHandler(ReadTargetMemory::type);
this->deregisterCommandHandler(WriteTargetMemory::type);
this->deregisterCommandHandler(StepTargetExecution::type);
this->eventListener->deregisterCallbacksForEventType<Events::DebugSessionFinished>();
this->eventListener->deregisterCallbacksForEventType<Events::ExtractTargetDescriptor>();
this->eventListener->deregisterCallbacksForEventType<Events::WriteMemoryToTarget>();
this->eventListener->deregisterCallbacksForEventType<Events::SetBreakpointOnTarget>();
this->eventListener->deregisterCallbacksForEventType<Events::RemoveBreakpointOnTarget>();
this->eventListener->deregisterCallbacksForEventType<Events::SetProgramCounterOnTarget>();
@@ -445,6 +446,10 @@ namespace Bloom::TargetController
std::bind(&TargetControllerComponent::handleReadTargetMemory, this, std::placeholders::_1)
);
this->registerCommandHandler<WriteTargetMemory>(
std::bind(&TargetControllerComponent::handleWriteTargetMemory, this, std::placeholders::_1)
);
this->registerCommandHandler<StepTargetExecution>(
std::bind(&TargetControllerComponent::handleStepTargetExecution, this, std::placeholders::_1)
);
@@ -457,10 +462,6 @@ namespace Bloom::TargetController
std::bind(&TargetControllerComponent::onExtractTargetDescriptor, this, std::placeholders::_1)
);
this->eventListener->registerCallbackForEventType<Events::WriteMemoryToTarget>(
std::bind(&TargetControllerComponent::onWriteMemoryEvent, this, std::placeholders::_1)
);
this->eventListener->registerCallbackForEventType<Events::SetBreakpointOnTarget>(
std::bind(&TargetControllerComponent::onSetBreakpointEvent, this, std::placeholders::_1)
);
@@ -799,6 +800,55 @@ namespace Bloom::TargetController
));
}
std::unique_ptr<Response> TargetControllerComponent::handleWriteTargetMemory(WriteTargetMemory& command) {
const auto& buffer = command.buffer;
const auto bufferSize = command.buffer.size();
const auto bufferStartAddress = command.startAddress;
this->target->writeMemory(command.memoryType, bufferStartAddress, buffer);
EventManager::triggerEvent(std::make_shared<Events::MemoryWrittenToTarget>());
if (
EventManager::isEventTypeListenedFor(Events::RegistersWrittenToTarget::type)
&& this->registerDescriptorsByMemoryType.contains(command.memoryType)
) {
/*
* The memory type we just wrote to contains some number of registers - if we've written to any address
* that is known to store the value of a register, trigger a RegistersWrittenToTarget event
*/
const auto bufferEndAddress = static_cast<std::uint32_t>(bufferStartAddress + (bufferSize - 1));
auto registerDescriptors = this->getRegisterDescriptorsWithinAddressRange(
bufferStartAddress,
bufferEndAddress,
command.memoryType
);
if (!registerDescriptors.empty()) {
auto registersWrittenEvent = std::make_shared<Events::RegistersWrittenToTarget>();
for (const auto& registerDescriptor : registerDescriptors) {
const auto registerSize = registerDescriptor.size;
const auto registerStartAddress = registerDescriptor.startAddress.value();
const auto registerEndAddress = registerStartAddress + (registerSize - 1);
if (registerStartAddress < bufferStartAddress || registerEndAddress > bufferEndAddress) {
continue;
}
const auto bufferBeginIt = buffer.begin() + (registerStartAddress - bufferStartAddress);
registersWrittenEvent->registers.emplace_back(TargetRegister(
registerDescriptor,
TargetMemoryBuffer(bufferBeginIt, bufferBeginIt + registerSize)
));
}
EventManager::triggerEvent(registersWrittenEvent);
}
}
return std::make_unique<Response>();
}
std::unique_ptr<Response> TargetControllerComponent::handleStepTargetExecution(StepTargetExecution& command) {
if (command.fromProgramCounter.has_value()) {
this->target->setProgramCounter(command.fromProgramCounter.value());
@@ -811,62 +861,6 @@ namespace Bloom::TargetController
return std::make_unique<Response>();
}
void TargetControllerComponent::onWriteMemoryEvent(const Events::WriteMemoryToTarget& event) {
try {
const auto& buffer = event.buffer;
const auto bufferSize = event.buffer.size();
const auto bufferStartAddress = event.startAddress;
this->target->writeMemory(event.memoryType, event.startAddress, event.buffer);
auto memoryWrittenEvent = std::make_shared<Events::MemoryWrittenToTarget>();
memoryWrittenEvent->correlationId = event.id;
EventManager::triggerEvent(memoryWrittenEvent);
if (EventManager::isEventTypeListenedFor(Events::RegistersWrittenToTarget::type)
&& this->registerDescriptorsByMemoryType.contains(event.memoryType)
) {
/*
* The memory type we just wrote to contains some number of registers - if we've written to any address
* that is known to store the value of a register, trigger a RegistersWrittenToTarget event
*/
const auto bufferEndAddress = static_cast<std::uint32_t>(bufferStartAddress + (bufferSize - 1));
auto registerDescriptors = this->getRegisterDescriptorsWithinAddressRange(
bufferStartAddress,
bufferEndAddress,
event.memoryType
);
if (!registerDescriptors.empty()) {
auto registersWrittenEvent = std::make_shared<Events::RegistersWrittenToTarget>();
registersWrittenEvent->correlationId = event.id;
for (const auto& registerDescriptor : registerDescriptors) {
const auto registerSize = registerDescriptor.size;
const auto registerStartAddress = registerDescriptor.startAddress.value();
const auto registerEndAddress = registerStartAddress + (registerSize - 1);
if (registerStartAddress < bufferStartAddress || registerEndAddress > bufferEndAddress) {
continue;
}
const auto bufferBeginIt = buffer.begin() + (registerStartAddress - bufferStartAddress);
registersWrittenEvent->registers.emplace_back(TargetRegister(
registerDescriptor,
TargetMemoryBuffer(bufferBeginIt, bufferBeginIt + registerSize)
));
}
EventManager::triggerEvent(registersWrittenEvent);
}
}
} catch (const TargetOperationFailure& exception) {
Logger::error("Failed to write memory to target - " + exception.getMessage());
this->emitErrorEvent(event.id, exception.getMessage());
}
}
void TargetControllerComponent::onSetBreakpointEvent(const Events::SetBreakpointOnTarget& event) {
try {
this->target->setBreakpoint(event.breakpoint.address);

View File

@@ -25,6 +25,7 @@
#include "Commands/ReadTargetRegisters.hpp"
#include "Commands/WriteTargetRegisters.hpp"
#include "Commands/ReadTargetMemory.hpp"
#include "Commands/WriteTargetMemory.hpp"
#include "Commands/StepTargetExecution.hpp"
// Responses
@@ -303,15 +304,9 @@ namespace Bloom::TargetController
);
std::unique_ptr<Responses::Response> handleWriteTargetRegisters(Commands::WriteTargetRegisters& command);
std::unique_ptr<Responses::TargetMemoryRead> handleReadTargetMemory(Commands::ReadTargetMemory& command);
std::unique_ptr<Responses::Response> handleWriteTargetMemory(Commands::WriteTargetMemory& command);
std::unique_ptr<Responses::Response> handleStepTargetExecution(Commands::StepTargetExecution& command);
/**
* Will attempt to write memory to the target. On success, a MemoryWrittenToTarget event is emitted.
*
* @param event
*/
void onWriteMemoryEvent(const Events::WriteMemoryToTarget& event);
/**
* Will attempt to set the specific breakpoint on the target. On success, the BreakpointSetOnTarget event will
* be emitted.

View File

@@ -12,6 +12,7 @@
#include "Commands/ReadTargetRegisters.hpp"
#include "Commands/WriteTargetRegisters.hpp"
#include "Commands/ReadTargetMemory.hpp"
#include "Commands/WriteTargetMemory.hpp"
#include "Commands/StepTargetExecution.hpp"
#include "src/Logger/Logger.hpp"
@@ -29,6 +30,7 @@ namespace Bloom::TargetController
using Commands::ReadTargetRegisters;
using Commands::WriteTargetRegisters;
using Commands::ReadTargetMemory;
using Commands::WriteTargetMemory;
using Commands::StepTargetExecution;
TargetControllerConsole::TargetControllerConsole(EventListener& eventListener)
@@ -130,12 +132,10 @@ namespace Bloom::TargetController
std::uint32_t startAddress,
const TargetMemoryBuffer& buffer
) {
auto writeMemoryEvent = std::make_shared<WriteMemoryToTarget>();
writeMemoryEvent->memoryType = memoryType;
writeMemoryEvent->startAddress = startAddress;
writeMemoryEvent->buffer = buffer;
this->triggerTargetControllerEventAndWaitForResponse(writeMemoryEvent);
this->commandManager.sendCommandAndWaitForResponse(
std::make_unique<WriteTargetMemory>(memoryType, startAddress, buffer),
this->defaultTimeout
);
}
void TargetControllerConsole::setBreakpoint(TargetBreakpoint breakpoint) {