// SPDX-License-Identifier: MIT /* $info$ tags: glue|gdbserver $end_info$ */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include "LinuxSyscalls/SignalDelegator.h" namespace FEX { class GdbServer { public: GdbServer(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* SignalDelegation, FEX::HLE::SyscallHandler* const SyscallHandler); ~GdbServer(); // Public for threading void GdbServerLoop(); void AlertLibrariesChanged() { LibraryMapChanged = true; } private: void Break(int signal); void OpenListenSocket(); void CloseListenSocket(); enum class WaitForConnectionResult { CONNECTION, ERROR, }; WaitForConnectionResult WaitForConnection(); fextl::unique_ptr OpenSocket(); void StartThread(); fextl::string ReadPacket(std::iostream& stream); void SendPacket(std::ostream& stream, const fextl::string& packet); void SendACK(std::ostream& stream, bool NACK); Event ThreadBreakEvent {}; void WaitForThreadWakeup(); struct HandledPacketType { fextl::string Response {}; enum ResponseType { TYPE_NONE, TYPE_UNKNOWN, TYPE_ACK, TYPE_NACK, TYPE_ONLYACK, TYPE_ONLYNACK, }; ResponseType TypeResponse {}; }; void SendPacketPair(const HandledPacketType& packetPair); HandledPacketType ProcessPacket(const fextl::string& packet); HandledPacketType handleQuery(const fextl::string& packet); HandledPacketType handleXfer(const fextl::string& packet); HandledPacketType handleMemory(const fextl::string& packet); HandledPacketType handleV(const fextl::string& packet); HandledPacketType handleThreadOp(const fextl::string& packet); HandledPacketType handleBreakpoint(const fextl::string& packet); HandledPacketType handleProgramOffsets(); HandledPacketType ThreadAction(char action, uint32_t tid); fextl::string readRegs(); HandledPacketType readReg(const fextl::string& packet); FEXCore::Context::Context* CTX; FEX::HLE::SyscallHandler* const SyscallHandler; fextl::unique_ptr gdbServerThread; fextl::unique_ptr CommsStream; std::mutex sendMutex; bool SettingNoAckMode {false}; bool NoAckMode {false}; bool NonStopMode {false}; fextl::string ThreadString {}; fextl::string OSDataString {}; void buildLibraryMap(); std::atomic LibraryMapChanged = true; std::atomic CoreShuttingDown {}; fextl::string LibraryMapString {}; // Used to keep track of which signals to pass to the guest std::array PassSignals {}; uint32_t CurrentDebuggingThread {}; int ListenSocket {}; fextl::string GdbUnixSocketPath {}; FEX_CONFIG_OPT(Filename, APP_FILENAME); FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE); }; } // namespace FEX