Support for hardware breakpoints

This commit is contained in:
Nav
2023-09-20 23:37:54 +01:00
parent df5a141089
commit d7b59cac59
24 changed files with 480 additions and 68 deletions

View File

@@ -159,7 +159,7 @@ namespace DebugServer::Gdb::AvrGdb
*
* We need to figure out why, and determine whether the stop should be reported to GDB.
*/
if (this->activeDebugSession->externalBreakpointAddresses.contains(programAddress)) {
if (this->activeDebugSession->externalBreakpointsByAddress.contains(programAddress)) {
/*
* The target stopped due to an external breakpoint, set by GDB.
*

View File

@@ -56,7 +56,7 @@ namespace DebugServer::Gdb::CommandPackets
try {
Logger::debug("Removing breakpoint at address " + std::to_string(this->address));
debugSession.removeExternalBreakpoint(TargetBreakpoint(this->address), targetControllerService);
debugSession.removeExternalBreakpoint(this->address, targetControllerService);
debugSession.connection.writePacket(OkResponsePacket());
} catch (const Exception& exception) {

View File

@@ -65,7 +65,7 @@ namespace DebugServer::Gdb::CommandPackets
return;
}
debugSession.setExternalBreakpoint(TargetBreakpoint(this->address), targetControllerService);
debugSession.setExternalBreakpoint(this->address, targetControllerService);
debugSession.connection.writePacket(OkResponsePacket());
} catch (const Exception& exception) {

View File

@@ -27,63 +27,83 @@ namespace DebugServer::Gdb
}
void DebugSession::setInternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
) {
if (this->internalBreakpointAddresses.contains(breakpoint.address)) {
if (this->internalBreakpointsByAddress.contains(address)) {
return;
}
if (!this->externalBreakpointAddresses.contains(breakpoint.address)) {
targetControllerService.setBreakpoint(breakpoint);
const auto externalBreakpointIt = this->externalBreakpointsByAddress.find(address);
if (externalBreakpointIt != this->externalBreakpointsByAddress.end()) {
// We already have an external breakpoint at this address
this->internalBreakpointsByAddress.insert(std::pair(address, externalBreakpointIt->second));
return;
}
this->internalBreakpointAddresses.insert(breakpoint.address);
this->internalBreakpointsByAddress.insert(
std::pair(
address,
targetControllerService.setBreakpoint(address, Targets::TargetBreakpoint::Type::HARDWARE)
)
);
}
void DebugSession::removeInternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
) {
if (!this->internalBreakpointAddresses.contains(breakpoint.address)) {
const auto breakpointIt = this->internalBreakpointsByAddress.find(address);
if (breakpointIt == this->internalBreakpointsByAddress.end()) {
return;
}
if (!this->externalBreakpointAddresses.contains(breakpoint.address)) {
targetControllerService.removeBreakpoint(breakpoint);
if (!this->externalBreakpointsByAddress.contains(address)) {
targetControllerService.removeBreakpoint(breakpointIt->second);
}
this->internalBreakpointAddresses.erase(breakpoint.address);
this->internalBreakpointsByAddress.erase(breakpointIt);
}
void DebugSession::setExternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
) {
if (this->externalBreakpointAddresses.contains(breakpoint.address)) {
if (this->externalBreakpointsByAddress.contains(address)) {
return;
}
if (!this->internalBreakpointAddresses.contains(breakpoint.address)) {
targetControllerService.setBreakpoint(breakpoint);
const auto internalBreakpointIt = this->internalBreakpointsByAddress.find(address);
if (internalBreakpointIt != this->internalBreakpointsByAddress.end()) {
// We already have an internal breakpoint at this address
this->externalBreakpointsByAddress.insert(std::pair(address, internalBreakpointIt->second));
return;
}
this->externalBreakpointAddresses.insert(breakpoint.address);
this->externalBreakpointsByAddress.insert(
std::pair(
address,
targetControllerService.setBreakpoint(address, Targets::TargetBreakpoint::Type::HARDWARE)
)
);
}
void DebugSession::removeExternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
) {
if (!this->externalBreakpointAddresses.contains(breakpoint.address)) {
const auto breakpointIt = this->externalBreakpointsByAddress.find(address);
if (breakpointIt == this->externalBreakpointsByAddress.end()) {
return;
}
if (!this->internalBreakpointAddresses.contains(breakpoint.address)) {
targetControllerService.removeBreakpoint(breakpoint);
if (!this->internalBreakpointsByAddress.contains(address)) {
targetControllerService.removeBreakpoint(breakpointIt->second);
}
this->externalBreakpointAddresses.erase(breakpoint.address);
this->externalBreakpointsByAddress.erase(breakpointIt);
}
void DebugSession::startRangeSteppingSession(
@@ -91,7 +111,7 @@ namespace DebugServer::Gdb
Services::TargetControllerService& targetControllerService
) {
for (const auto& interceptAddress : session.interceptedAddresses) {
this->setInternalBreakpoint(Targets::TargetBreakpoint(interceptAddress), targetControllerService);
this->setInternalBreakpoint(interceptAddress, targetControllerService);
}
this->activeRangeSteppingSession = std::move(session);
@@ -104,7 +124,7 @@ namespace DebugServer::Gdb
// Clear all intercepting breakpoints
for (const auto& interceptAddress : this->activeRangeSteppingSession->interceptedAddresses) {
this->removeInternalBreakpoint(Targets::TargetBreakpoint(interceptAddress), targetControllerService);
this->removeInternalBreakpoint(interceptAddress, targetControllerService);
}
this->activeRangeSteppingSession.reset();

View File

@@ -2,7 +2,7 @@
#include <cstdint>
#include <optional>
#include <set>
#include <map>
#include "TargetDescriptor.hpp"
#include "GdbDebugServerConfig.hpp"
@@ -55,8 +55,8 @@ namespace DebugServer::Gdb
*
* We track internal and external breakpoints separately.
*/
std::set<Targets::TargetMemoryAddress> internalBreakpointAddresses;
std::set<Targets::TargetMemoryAddress> externalBreakpointAddresses;
std::map<Targets::TargetMemoryAddress, Targets::TargetBreakpoint> internalBreakpointsByAddress;
std::map<Targets::TargetMemoryAddress, Targets::TargetBreakpoint> externalBreakpointsByAddress;
/**
* When the GDB client is waiting for the target to halt, this is set to true so we know when to notify the
@@ -105,22 +105,22 @@ namespace DebugServer::Gdb
virtual ~DebugSession();
virtual void setInternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
);
virtual void removeInternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
);
virtual void setExternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
);
virtual void removeExternalBreakpoint(
const Targets::TargetBreakpoint& breakpoint,
Targets::TargetMemoryAddress address,
Services::TargetControllerService& targetControllerService
);