Files
FEX-Emu--FEX/Source/Tools/FEXLoader/LinuxSyscalls/SignalDelegator.h
T
Ryan Houdek 7e4334c98a FEXLoader: Move to Tools folder
This has confused people for quite a long time thinking these are unit
tests.

First step, move it without any changes. Only Renamed.
2023-04-11 16:37:21 -07:00

114 lines
3.6 KiB
C++

/*
$info$
tags: LinuxSyscalls|common
$end_info$
*/
#pragma once
#include <array>
#include <atomic>
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <mutex>
#include <FEXCore/Core/SignalDelegator.h>
namespace FEXCore {
namespace Core {
struct InternalThreadState;
}
}
namespace FEX::HLE {
class SignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::Allocator::FEXAllocOperators {
public:
// Returns true if the host handled the signal
// Arguments are the same as sigaction handler
SignalDelegator();
~SignalDelegator() override;
/**
* @brief Registers a signal handler for the host to handle a signal specifically for guest handling
*
* It's a process level signal handler so one must be careful
*/
void RegisterHostSignalHandlerForGuest(int Signal, FEXCore::HostSignalDelegatorFunctionForGuest Func) override;
/**
* @name These functions are all for Linux signal emulation
* @{ */
/**
* @brief Allows the guest to register a signal handler that is run after the host attempts to resolve the handler first
*/
uint64_t RegisterGuestSignalHandler(int Signal, const FEXCore::GuestSigAction *Action, struct FEXCore::GuestSigAction *OldAction);
uint64_t RegisterGuestSigAltStack(const stack_t *ss, stack_t *old_ss);
uint64_t GuestSigProcMask(int how, const uint64_t *set, uint64_t *oldset);
uint64_t GuestSigPending(uint64_t *set, size_t sigsetsize);
uint64_t GuestSigSuspend(uint64_t *set, size_t sigsetsize);
uint64_t GuestSigTimedWait(uint64_t *set, siginfo_t *info, const struct timespec *timeout, size_t sigsetsize);
uint64_t GuestSignalFD(int fd, const uint64_t *set, size_t sigsetsize , int flags);
/** @} */
void CheckXIDHandler() override;
void UninstallHostHandler(int Signal);
protected:
// Called from the thunk handler to handle the signal
void HandleGuestSignal(FEXCore::Core::InternalThreadState *Thread, int Signal, void *Info, void *UContext) override;
void RegisterFrontendTLSState(FEXCore::Core::InternalThreadState *Thread) override;
void UninstallFrontendTLSState(FEXCore::Core::InternalThreadState *Thread) override;
/**
* @brief Registers a signal handler for the host to handle a signal
*
* It's a process level signal handler so one must be careful
*/
void FrontendRegisterHostSignalHandler(int Signal, FEXCore::HostSignalDelegatorFunction Func, bool Required) override;
void FrontendRegisterFrontendHostSignalHandler(int Signal, FEXCore::HostSignalDelegatorFunction Func, bool Required) override;
private:
enum DefaultBehaviour {
DEFAULT_TERM,
// Core dump based signals are supposed to have a coredump appear
// For FEX's behaviour we don't really care right now
DEFAULT_COREDUMP = DEFAULT_TERM,
DEFAULT_IGNORE,
};
struct kernel_sigaction {
union {
void (*handler)(int);
void (*sigaction)(int, siginfo_t*, void*);
};
uint64_t sa_flags;
void (*restorer)();
uint64_t sa_mask;
};
struct SignalHandler {
std::atomic<bool> Installed{};
std::atomic<bool> Required{};
kernel_sigaction HostAction{};
kernel_sigaction OldAction{};
FEXCore::HostSignalDelegatorFunctionForGuest GuestHandler{};
FEXCore::GuestSigAction GuestAction{};
DefaultBehaviour DefaultBehaviour {DEFAULT_TERM};
};
std::array<SignalHandler, MAX_SIGNALS + 1> HostHandlers{};
bool InstallHostThunk(int Signal);
bool UpdateHostThunk(int Signal);
std::mutex HostDelegatorMutex;
std::mutex GuestDelegatorMutex;
};
}