Support for hardware breakpoints
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user