Introduced the TargetControllerConsole class to provide access to common functionality within the TargetController.
This commit is contained in:
@@ -57,177 +57,4 @@ void DebugServer::shutdown() {
|
||||
|
||||
void DebugServer::onShutdownDebugServerEvent(EventPointer<Events::ShutdownDebugServer> event) {
|
||||
this->shutdown();
|
||||
}
|
||||
|
||||
void DebugServer::stopTargetExecution() {
|
||||
auto stopTargetEvent = std::make_shared<Events::StopTargetExecution>();
|
||||
this->eventManager.triggerEvent(stopTargetEvent);
|
||||
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::TargetExecutionStopped,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), stopTargetEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetExecutionStopped>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void DebugServer::continueTargetExecution(std::optional<std::uint32_t> fromAddress) {
|
||||
auto resumeExecutionEvent = std::make_shared<Events::ResumeTargetExecution>();
|
||||
|
||||
if (fromAddress.has_value()) {
|
||||
resumeExecutionEvent->fromProgramCounter = fromAddress.value();
|
||||
}
|
||||
|
||||
this->eventManager.triggerEvent(resumeExecutionEvent);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::TargetExecutionResumed,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), resumeExecutionEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetExecutionResumed>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void DebugServer::stepTargetExecution(std::optional<std::uint32_t> fromAddress) {
|
||||
auto stepExecutionEvent = std::make_shared<Events::StepTargetExecution>();
|
||||
|
||||
if (fromAddress.has_value()) {
|
||||
stepExecutionEvent->fromProgramCounter = fromAddress.value();
|
||||
}
|
||||
|
||||
this->eventManager.triggerEvent(stepExecutionEvent);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::TargetExecutionResumed,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), stepExecutionEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::TargetExecutionResumed>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
TargetRegisters DebugServer::readGeneralRegistersFromTarget(TargetRegisterDescriptors descriptors) {
|
||||
auto readRegistersEvent = std::make_shared<Events::RetrieveRegistersFromTarget>();
|
||||
readRegistersEvent->descriptors = descriptors;
|
||||
|
||||
this->eventManager.triggerEvent(readRegistersEvent);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::RegistersRetrievedFromTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), readRegistersEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::RegistersRetrievedFromTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
|
||||
auto retrievedRegistersEvent = std::get<EventPointer<Events::RegistersRetrievedFromTarget>>(responseEvent.value());
|
||||
return retrievedRegistersEvent->registers;
|
||||
}
|
||||
|
||||
void DebugServer::writeGeneralRegistersToTarget(TargetRegisters registers) {
|
||||
auto event = std::make_shared<Events::WriteRegistersToTarget>();
|
||||
event->registers = registers;
|
||||
|
||||
this->eventManager.triggerEvent(event);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::RegistersWrittenToTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), event->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::RegistersWrittenToTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
TargetMemoryBuffer DebugServer::readMemoryFromTarget(TargetMemoryType memoryType, std::uint32_t startAddress, std::uint32_t bytes) {
|
||||
auto readMemoryEvent = std::make_shared<Events::RetrieveMemoryFromTarget>();
|
||||
readMemoryEvent->memoryType = memoryType;
|
||||
readMemoryEvent->startAddress = startAddress;
|
||||
readMemoryEvent->bytes = bytes;
|
||||
|
||||
this->eventManager.triggerEvent(readMemoryEvent);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::MemoryRetrievedFromTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), readMemoryEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::MemoryRetrievedFromTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
|
||||
auto retrievedRegistersEvent = std::get<EventPointer<Events::MemoryRetrievedFromTarget>>(responseEvent.value());
|
||||
return retrievedRegistersEvent->data;
|
||||
}
|
||||
|
||||
void DebugServer::writeMemoryToTarget(
|
||||
TargetMemoryType memoryType,
|
||||
std::uint32_t startAddress,
|
||||
const TargetMemoryBuffer& buffer
|
||||
) {
|
||||
auto writeMemoryEvent = std::make_shared<Events::WriteMemoryToTarget>();
|
||||
writeMemoryEvent->memoryType = memoryType;
|
||||
writeMemoryEvent->startAddress = startAddress;
|
||||
writeMemoryEvent->buffer = buffer;
|
||||
|
||||
this->eventManager.triggerEvent(writeMemoryEvent);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::MemoryWrittenToTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), writeMemoryEvent->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::MemoryWrittenToTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void DebugServer::setBreakpointOnTarget(TargetBreakpoint breakpoint) {
|
||||
auto event = std::make_shared<Events::SetBreakpointOnTarget>();
|
||||
event->breakpoint = breakpoint;
|
||||
|
||||
this->eventManager.triggerEvent(event);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::BreakpointSetOnTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), event->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::BreakpointSetOnTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
void DebugServer::removeBreakpointOnTarget(TargetBreakpoint breakpoint) {
|
||||
auto event = std::make_shared<Events::RemoveBreakpointOnTarget>();
|
||||
event->breakpoint = breakpoint;
|
||||
|
||||
this->eventManager.triggerEvent(event);
|
||||
auto responseEvent = this->eventListener->waitForEvent<
|
||||
Events::BreakpointRemovedOnTarget,
|
||||
Events::TargetControllerErrorOccurred
|
||||
>(std::chrono::milliseconds(5000), event->id);
|
||||
|
||||
if (!responseEvent.has_value()
|
||||
|| !std::holds_alternative<EventPointer<Events::BreakpointRemovedOnTarget>>(responseEvent.value())
|
||||
) {
|
||||
throw Exception("Unexpected response from TargetController");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
|
||||
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||
#include "src/EventManager/Events/Events.hpp"
|
||||
#include "src/EventManager/EventManager.hpp"
|
||||
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
||||
@@ -75,6 +76,11 @@ namespace Bloom::DebugServers
|
||||
EventManager& eventManager;
|
||||
EventListenerPointer eventListener = std::make_shared<EventListener>("DebugServerEventListener");
|
||||
|
||||
TargetControllerConsole targetControllerConsole = TargetControllerConsole(
|
||||
this->eventManager,
|
||||
*(this->eventListener)
|
||||
);
|
||||
|
||||
/**
|
||||
* Enables the interruption of any blocking file IO.
|
||||
*/
|
||||
@@ -99,75 +105,6 @@ namespace Bloom::DebugServers
|
||||
*/
|
||||
virtual void close() = 0;
|
||||
|
||||
/**
|
||||
* Requests the TargetController to halt execution on the target.
|
||||
*/
|
||||
void stopTargetExecution();
|
||||
|
||||
/**
|
||||
* Requests the TargetController to continue execution on the target.
|
||||
*
|
||||
* @param fromAddress
|
||||
*/
|
||||
void continueTargetExecution(std::optional<std::uint32_t> fromAddress);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to step execution on the target.
|
||||
*
|
||||
* @param fromAddress
|
||||
*/
|
||||
void stepTargetExecution(std::optional<std::uint32_t> fromAddress);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to read register values from the target.
|
||||
*
|
||||
* @param descriptors
|
||||
* Descriptors of the registers to read.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TargetRegisters readGeneralRegistersFromTarget(TargetRegisterDescriptors descriptors);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to write register values to the target.
|
||||
*
|
||||
* @param registers
|
||||
*/
|
||||
void writeGeneralRegistersToTarget(TargetRegisters registers);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to read memory from the target.
|
||||
*
|
||||
* @param memoryType
|
||||
* @param startAddress
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
TargetMemoryBuffer readMemoryFromTarget(TargetMemoryType memoryType, std::uint32_t startAddress, std::uint32_t bytes);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to write memory to the target.
|
||||
*
|
||||
* @param memoryType
|
||||
* @param startAddress
|
||||
* @param buffer
|
||||
*/
|
||||
void writeMemoryToTarget(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to set a breakpoint on the target.
|
||||
*
|
||||
* @param breakpoint
|
||||
*/
|
||||
void setBreakpointOnTarget(TargetBreakpoint breakpoint);
|
||||
|
||||
/**
|
||||
* Requests the TargetController to remove a breakpoint from the target.
|
||||
*
|
||||
* @param breakpoint
|
||||
*/
|
||||
void removeBreakpointOnTarget(TargetBreakpoint breakpoint);
|
||||
|
||||
public:
|
||||
DebugServer(EventManager& eventManager): eventManager(eventManager) {};
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadGeneralRegisters& pa
|
||||
}
|
||||
}
|
||||
|
||||
auto registerSet = this->readGeneralRegistersFromTarget(descriptors);
|
||||
auto registerSet = this->targetControllerConsole.readGeneralRegisters(descriptors);
|
||||
auto registerNumberToDescriptorMapping = this->getRegisterNumberToDescriptorMapping();
|
||||
|
||||
/*
|
||||
@@ -297,7 +297,9 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteGeneralRegisters& p
|
||||
|
||||
try {
|
||||
auto registerDescriptor = this->getRegisterDescriptorFromNumber(packet.registerNumber);
|
||||
this->writeGeneralRegistersToTarget({TargetRegister(registerDescriptor, packet.registerValue)});
|
||||
this->targetControllerConsole.writeGeneralRegisters({
|
||||
TargetRegister(registerDescriptor, packet.registerValue)
|
||||
});
|
||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||
|
||||
} catch (const Exception& exception) {
|
||||
@@ -310,7 +312,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ContinueExecution& packe
|
||||
Logger::debug("Handling ContinueExecution packet");
|
||||
|
||||
try {
|
||||
this->continueTargetExecution(packet.fromProgramCounter);
|
||||
this->targetControllerConsole.continueTargetExecution(packet.fromProgramCounter);
|
||||
this->clientConnection->waitingForBreak = true;
|
||||
|
||||
} catch (const Exception& exception) {
|
||||
@@ -323,7 +325,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::StepExecution& packet) {
|
||||
Logger::debug("Handling StepExecution packet");
|
||||
|
||||
try {
|
||||
this->stepTargetExecution(packet.fromProgramCounter);
|
||||
this->targetControllerConsole.stepTargetExecution(packet.fromProgramCounter);
|
||||
this->clientConnection->waitingForBreak = true;
|
||||
|
||||
} catch (const Exception& exception) {
|
||||
@@ -338,7 +340,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::ReadMemory& packet) {
|
||||
try {
|
||||
auto memoryType = this->getMemoryTypeFromGdbAddress(packet.startAddress);
|
||||
auto startAddress = this->removeMemoryTypeIndicatorFromGdbAddress(packet.startAddress);
|
||||
auto memoryBuffer = this->readMemoryFromTarget(memoryType, startAddress, packet.bytes);
|
||||
auto memoryBuffer = this->targetControllerConsole.readMemory(memoryType, startAddress, packet.bytes);
|
||||
|
||||
auto hexMemoryBuffer = Packet::dataToHex(memoryBuffer);
|
||||
this->clientConnection->writePacket(
|
||||
@@ -357,7 +359,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::WriteMemory& packet) {
|
||||
try {
|
||||
auto memoryType = this->getMemoryTypeFromGdbAddress(packet.startAddress);
|
||||
auto startAddress = this->removeMemoryTypeIndicatorFromGdbAddress(packet.startAddress);
|
||||
this->writeMemoryToTarget(memoryType, startAddress, packet.buffer);
|
||||
this->targetControllerConsole.writeMemory(memoryType, startAddress, packet.buffer);
|
||||
|
||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||
|
||||
@@ -373,7 +375,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::SetBreakpoint& packet) {
|
||||
try {
|
||||
auto breakpoint = TargetBreakpoint();
|
||||
breakpoint.address = packet.address;
|
||||
this->setBreakpointOnTarget(breakpoint);
|
||||
this->targetControllerConsole.setBreakpoint(breakpoint);
|
||||
|
||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||
|
||||
@@ -389,7 +391,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::RemoveBreakpoint& packet
|
||||
try {
|
||||
auto breakpoint = TargetBreakpoint();
|
||||
breakpoint.address = packet.address;
|
||||
this->removeBreakpointOnTarget(breakpoint);
|
||||
this->targetControllerConsole.removeBreakpoint(breakpoint);
|
||||
|
||||
this->clientConnection->writePacket(ResponsePacket({'O', 'K'}));
|
||||
|
||||
@@ -403,7 +405,7 @@ void GdbRspDebugServer::handleGdbPacket(CommandPackets::InterruptExecution& pack
|
||||
Logger::debug("Handling InterruptExecution packet");
|
||||
|
||||
try {
|
||||
this->stopTargetExecution();
|
||||
this->targetControllerConsole.stopTargetExecution();
|
||||
this->clientConnection->writePacket(TargetStopped(Signal::INTERRUPTED));
|
||||
|
||||
} catch (const Exception& exception) {
|
||||
|
||||
Reference in New Issue
Block a user