2021-04-04 21:04:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
#include <cstdint>
|
2021-04-04 21:04:12 +01:00
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <queue>
|
2022-03-27 18:32:13 +01:00
|
|
|
#include <optional>
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
#include "src/DebugServers/ServerInterface.hpp"
|
2022-03-19 15:16:59 +00:00
|
|
|
|
|
|
|
|
#include "GdbDebugServerConfig.hpp"
|
2022-03-27 18:32:13 +01:00
|
|
|
#include "src/EventManager/EventListener.hpp"
|
|
|
|
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
2022-03-19 15:16:59 +00:00
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
#include "Connection.hpp"
|
2022-03-24 19:17:41 +00:00
|
|
|
#include "TargetDescriptor.hpp"
|
|
|
|
|
#include "DebugSession.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
#include "Signal.hpp"
|
2021-12-28 00:00:45 +00:00
|
|
|
#include "RegisterDescriptor.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
#include "Feature.hpp"
|
2022-03-19 15:17:07 +00:00
|
|
|
#include "CommandPackets/CommandPacketFactory.hpp"
|
|
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
#include "src/EventManager/Events/TargetControllerStateReported.hpp"
|
|
|
|
|
#include "src/EventManager/Events/TargetExecutionStopped.hpp"
|
2022-03-19 15:17:07 +00:00
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
#include "src/Helpers/BiMap.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
|
|
|
|
|
namespace Bloom::DebugServers::Gdb
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* The GdbRspDebugServer is an implementation of a GDB server using the GDB Remote Serial Protocol.
|
|
|
|
|
*
|
|
|
|
|
* This DebugServer employs TCP/IP sockets to interface with GDB clients. The listening address can be configured
|
|
|
|
|
* in the user's project config file.
|
|
|
|
|
*
|
|
|
|
|
* See https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html for more info on the GDB Remote
|
|
|
|
|
* Serial Protocol.
|
|
|
|
|
*
|
|
|
|
|
* @TODO: This could do with some cleaning.
|
|
|
|
|
*/
|
2022-03-27 18:32:13 +01:00
|
|
|
class GdbRspDebugServer: public ServerInterface
|
2021-04-04 21:04:12 +01:00
|
|
|
{
|
2021-10-06 21:12:31 +01:00
|
|
|
public:
|
2021-12-31 19:45:15 +00:00
|
|
|
explicit GdbRspDebugServer(
|
2022-03-27 18:32:13 +01:00
|
|
|
const DebugServerConfig& debugServerConfig,
|
|
|
|
|
EventListener& eventListener
|
|
|
|
|
);
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
[[nodiscard]] std::string getName() const override {
|
2021-10-06 21:12:31 +01:00
|
|
|
return "GDB Remote Serial Protocol DebugServer";
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
/**
|
|
|
|
|
* Prepares the GDB server for listing on the selected address and port.
|
|
|
|
|
*/
|
|
|
|
|
void init() override;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Terminates any active debug session and closes the listening socket.
|
|
|
|
|
*/
|
|
|
|
|
void close() override;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Waits for a connection from a GDB client or services an active one.
|
|
|
|
|
*
|
|
|
|
|
* This function will return when any blocking operation is interrupted via this->interruptEventNotifier.
|
|
|
|
|
*/
|
|
|
|
|
void run() override;
|
|
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
protected:
|
2022-03-19 15:16:59 +00:00
|
|
|
std::optional<GdbDebugServerConfig> debugServerConfig;
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
EventListener& eventListener;
|
|
|
|
|
|
|
|
|
|
EventNotifier* interruptEventNotifier = nullptr;
|
|
|
|
|
|
|
|
|
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(this->eventListener);
|
|
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
/**
|
|
|
|
|
* Listening socket address
|
|
|
|
|
*/
|
|
|
|
|
struct sockaddr_in socketAddress = {};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Listening socket file descriptor
|
|
|
|
|
*/
|
|
|
|
|
int serverSocketFileDescriptor = -1;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* We don't listen on the this->serverSocketFileDescriptor directly. Instead, we add it to an epoll set, along
|
|
|
|
|
* with the this->interruptEventNotifier FD. This allows us to interrupt any blocking socket IO calls when
|
|
|
|
|
* we have other things to do.
|
|
|
|
|
*
|
|
|
|
|
* See GdbRspDebugServer::init()
|
|
|
|
|
* See DebugServer::interruptEventNotifier
|
|
|
|
|
* See EventNotifier
|
|
|
|
|
*/
|
|
|
|
|
int eventFileDescriptor = -1;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* SO_REUSEADDR option value for listening socket.
|
|
|
|
|
*/
|
|
|
|
|
int enableReuseAddressSocketOption = 1;
|
|
|
|
|
|
2022-03-24 19:17:41 +00:00
|
|
|
std::optional<DebugSession> activeDebugSession;
|
2021-04-04 21:04:12 +01:00
|
|
|
|
|
|
|
|
/**
|
2022-03-24 19:17:41 +00:00
|
|
|
* Waits for a GDB client to connect on the listening socket.
|
2021-04-04 21:04:12 +01:00
|
|
|
*
|
2022-03-24 19:17:41 +00:00
|
|
|
* This function may return an std::nullopt, if the waiting was interrupted by some other event.
|
2021-04-04 21:04:12 +01:00
|
|
|
*/
|
2022-03-24 19:17:41 +00:00
|
|
|
std::optional<Connection> waitForConnection();
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-03-24 19:17:41 +00:00
|
|
|
void terminateActiveDebugSession();
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2022-03-24 19:17:41 +00:00
|
|
|
virtual const TargetDescriptor& getGdbTargetDescriptor() = 0;
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2021-06-22 14:44:00 +01:00
|
|
|
void onTargetControllerStateReported(const Events::TargetControllerStateReported& event);
|
2021-05-30 16:53:49 +01:00
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
/**
|
|
|
|
|
* If the GDB client is currently waiting for the target execution to stop, this event handler will issue
|
|
|
|
|
* a "stop reply" packet to the client once the target execution stops.
|
|
|
|
|
*/
|
2021-06-22 14:44:00 +01:00
|
|
|
void onTargetExecutionStopped(const Events::TargetExecutionStopped&);
|
2021-04-04 21:04:12 +01:00
|
|
|
};
|
|
|
|
|
}
|