2022-03-24 19:07:28 +00:00
|
|
|
#include "DebugSession.hpp"
|
|
|
|
|
|
2022-08-13 03:06:30 +01:00
|
|
|
#include "src/EventManager/EventManager.hpp"
|
2022-03-24 19:07:28 +00:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace DebugServer::Gdb
|
2022-03-24 19:07:28 +00:00
|
|
|
{
|
2022-05-14 22:38:49 +01:00
|
|
|
DebugSession::DebugSession(
|
|
|
|
|
Connection&& connection,
|
|
|
|
|
const std::set<std::pair<Feature, std::optional<std::string>>>& supportedFeatures,
|
2023-04-01 14:30:33 +01:00
|
|
|
const TargetDescriptor& targetDescriptor,
|
|
|
|
|
const GdbDebugServerConfig& serverConfig
|
2022-05-14 22:38:49 +01:00
|
|
|
)
|
2022-03-28 01:04:14 +01:00
|
|
|
: connection(std::move(connection))
|
2022-05-14 22:38:49 +01:00
|
|
|
, supportedFeatures(supportedFeatures)
|
2022-05-04 19:49:18 +01:00
|
|
|
, gdbTargetDescriptor(targetDescriptor)
|
2023-04-01 14:30:33 +01:00
|
|
|
, serverConfig(serverConfig)
|
2022-05-14 22:38:49 +01:00
|
|
|
{
|
|
|
|
|
this->supportedFeatures.insert({
|
2022-11-16 23:50:28 +00:00
|
|
|
Feature::PACKET_SIZE, std::to_string(Connection::ABSOLUTE_MAXIMUM_PACKET_READ_SIZE)
|
2022-05-14 22:38:49 +01:00
|
|
|
});
|
2022-03-24 19:07:28 +00:00
|
|
|
|
2022-08-13 03:06:30 +01:00
|
|
|
EventManager::triggerEvent(std::make_shared<Events::DebugSessionStarted>());
|
|
|
|
|
}
|
2022-03-29 14:54:49 +01:00
|
|
|
|
2022-08-13 03:06:30 +01:00
|
|
|
DebugSession::~DebugSession() {
|
|
|
|
|
EventManager::triggerEvent(std::make_shared<Events::DebugSessionFinished>());
|
2022-03-24 19:07:28 +00:00
|
|
|
}
|
2023-09-10 22:27:10 +01:00
|
|
|
|
|
|
|
|
void DebugSession::setInternalBreakpoint(
|
2023-09-20 23:37:54 +01:00
|
|
|
Targets::TargetMemoryAddress address,
|
2023-09-10 22:27:10 +01:00
|
|
|
Services::TargetControllerService& targetControllerService
|
|
|
|
|
) {
|
2023-09-20 23:37:54 +01:00
|
|
|
if (this->internalBreakpointsByAddress.contains(address)) {
|
2023-09-10 22:27:10 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
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;
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
this->internalBreakpointsByAddress.insert(
|
|
|
|
|
std::pair(
|
|
|
|
|
address,
|
|
|
|
|
targetControllerService.setBreakpoint(address, Targets::TargetBreakpoint::Type::HARDWARE)
|
|
|
|
|
)
|
|
|
|
|
);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebugSession::removeInternalBreakpoint(
|
2023-09-20 23:37:54 +01:00
|
|
|
Targets::TargetMemoryAddress address,
|
2023-09-10 22:27:10 +01:00
|
|
|
Services::TargetControllerService& targetControllerService
|
|
|
|
|
) {
|
2023-09-20 23:37:54 +01:00
|
|
|
const auto breakpointIt = this->internalBreakpointsByAddress.find(address);
|
|
|
|
|
if (breakpointIt == this->internalBreakpointsByAddress.end()) {
|
2023-09-10 22:27:10 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
if (!this->externalBreakpointsByAddress.contains(address)) {
|
|
|
|
|
targetControllerService.removeBreakpoint(breakpointIt->second);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
this->internalBreakpointsByAddress.erase(breakpointIt);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebugSession::setExternalBreakpoint(
|
2023-09-20 23:37:54 +01:00
|
|
|
Targets::TargetMemoryAddress address,
|
2023-09-10 22:27:10 +01:00
|
|
|
Services::TargetControllerService& targetControllerService
|
|
|
|
|
) {
|
2023-09-20 23:37:54 +01:00
|
|
|
if (this->externalBreakpointsByAddress.contains(address)) {
|
2023-09-10 22:27:10 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
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;
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
this->externalBreakpointsByAddress.insert(
|
|
|
|
|
std::pair(
|
|
|
|
|
address,
|
|
|
|
|
targetControllerService.setBreakpoint(address, Targets::TargetBreakpoint::Type::HARDWARE)
|
|
|
|
|
)
|
|
|
|
|
);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebugSession::removeExternalBreakpoint(
|
2023-09-20 23:37:54 +01:00
|
|
|
Targets::TargetMemoryAddress address,
|
2023-09-10 22:27:10 +01:00
|
|
|
Services::TargetControllerService& targetControllerService
|
|
|
|
|
) {
|
2023-09-20 23:37:54 +01:00
|
|
|
const auto breakpointIt = this->externalBreakpointsByAddress.find(address);
|
|
|
|
|
if (breakpointIt == this->externalBreakpointsByAddress.end()) {
|
2023-09-10 22:27:10 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
if (!this->internalBreakpointsByAddress.contains(address)) {
|
|
|
|
|
targetControllerService.removeBreakpoint(breakpointIt->second);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-20 23:37:54 +01:00
|
|
|
this->externalBreakpointsByAddress.erase(breakpointIt);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebugSession::startRangeSteppingSession(
|
|
|
|
|
RangeSteppingSession&& session,
|
|
|
|
|
Services::TargetControllerService& targetControllerService
|
|
|
|
|
) {
|
|
|
|
|
for (const auto& interceptAddress : session.interceptedAddresses) {
|
2023-09-20 23:37:54 +01:00
|
|
|
this->setInternalBreakpoint(interceptAddress, targetControllerService);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->activeRangeSteppingSession = std::move(session);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebugSession::terminateRangeSteppingSession(Services::TargetControllerService& targetControllerService) {
|
|
|
|
|
if (!this->activeRangeSteppingSession.has_value()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear all intercepting breakpoints
|
|
|
|
|
for (const auto& interceptAddress : this->activeRangeSteppingSession->interceptedAddresses) {
|
2023-09-20 23:37:54 +01:00
|
|
|
this->removeInternalBreakpoint(interceptAddress, targetControllerService);
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->activeRangeSteppingSession.reset();
|
|
|
|
|
}
|
2022-03-24 19:07:28 +00:00
|
|
|
}
|