Merge pull request #582 from Sonicadvance1/move_syscalls

Moves FEXCore's SignalDelegator and SyscallHandler to the frontend
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis authored and GitHub committed 2020-12-16 12:52:39 +02:00
commit ef75b8e4ec
93 files changed
+863 -895

No files matched your search

-46
View File
@@ -127,7 +127,6 @@ set (SRCS
Interface/Core/GdbServer.cpp
Interface/Core/HostFeatures.cpp
Interface/Core/OpcodeDispatcher.cpp
Interface/Core/SignalDelegator.cpp
Interface/Core/X86Tables.cpp
Interface/Core/X86DebugInfo.cpp
Interface/Core/X86HelperGen.cpp
@@ -144,51 +143,6 @@ set (SRCS
Interface/Core/X86Tables/VEXTables.cpp
Interface/Core/X86Tables/X87Tables.cpp
Interface/Core/X86Tables/XOPTables.cpp
Interface/HLE/FileManagement.cpp
Interface/HLE/EmulatedFiles/EmulatedFiles.cpp
Interface/HLE/Syscalls.cpp
Interface/HLE/x32/Syscalls.cpp
Interface/HLE/x32/FD.cpp
Interface/HLE/x32/FS.cpp
Interface/HLE/x32/Info.cpp
Interface/HLE/x32/Memory.cpp
Interface/HLE/x32/NotImplemented.cpp
Interface/HLE/x32/Semaphore.cpp
Interface/HLE/x32/Sched.cpp
Interface/HLE/x32/Socket.cpp
Interface/HLE/x32/Thread.cpp
Interface/HLE/x32/Time.cpp
Interface/HLE/x64/FD.cpp
Interface/HLE/x64/IO.cpp
Interface/HLE/x64/Ioctl.cpp
Interface/HLE/x64/Info.cpp
Interface/HLE/x64/Memory.cpp
Interface/HLE/x64/Msg.cpp
Interface/HLE/x64/NotImplemented.cpp
Interface/HLE/x64/Semaphore.cpp
Interface/HLE/x64/Sched.cpp
Interface/HLE/x64/Socket.cpp
Interface/HLE/x64/Thread.cpp
Interface/HLE/x64/Syscalls.cpp
Interface/HLE/x64/Time.cpp
Interface/HLE/Syscalls/EPoll.cpp
Interface/HLE/Syscalls/FD.cpp
Interface/HLE/Syscalls/FS.cpp
Interface/HLE/Syscalls/Info.cpp
Interface/HLE/Syscalls/IO.cpp
Interface/HLE/Syscalls/Key.cpp
Interface/HLE/Syscalls/Memory.cpp
Interface/HLE/Syscalls/Msg.cpp
Interface/HLE/Syscalls/Sched.cpp
Interface/HLE/Syscalls/Semaphore.cpp
Interface/HLE/Syscalls/SHM.cpp
Interface/HLE/Syscalls/Signals.cpp
Interface/HLE/Syscalls/Socket.cpp
Interface/HLE/Syscalls/Thread.cpp
Interface/HLE/Syscalls/Time.cpp
Interface/HLE/Syscalls/Timer.cpp
Interface/HLE/Syscalls/NotImplemented.cpp
Interface/HLE/Syscalls/Stubs.cpp
Interface/HLE/Thunks/Thunks.cpp
Interface/IR/IR.cpp
Interface/IR/IREmitter.cpp
-6
View File
@@ -29,9 +29,6 @@ namespace FEXCore::Config {
case FEXCore::Config::CONFIG_IS64BIT_MODE:
CTX->Config.Is64BitMode = Config != 0;
break;
case FEXCore::Config::CONFIG_EMULATED_CPU_CORES:
CTX->Config.EmulatedCPUCores = std::max(1UL, Config);
break;
case FEXCore::Config::CONFIG_TSO_ENABLED:
CTX->Config.TSOEnabled = Config != 0;
break;
@@ -85,9 +82,6 @@ namespace FEXCore::Config {
case FEXCore::Config::CONFIG_IS64BIT_MODE:
return CTX->Config.Is64BitMode;
break;
case FEXCore::Config::CONFIG_EMULATED_CPU_CORES:
return CTX->Config.EmulatedCPUCores;
break;
case FEXCore::Config::CONFIG_TSO_ENABLED:
return CTX->Config.TSOEnabled;
break;
+41 -12
View File
@@ -26,12 +26,6 @@ namespace FEXCore::Context {
delete CTX;
}
void SetApplicationFile(FEXCore::Context::Context *CTX, std::string const &File) {
CTX->SyscallHandler->SetFilename(File);
// XXX: This isn't good for debugging
// CTX->LoadEntryList();
}
bool InitCore(FEXCore::Context::Context *CTX, FEXCore::CodeLoader *Loader) {
return CTX->InitCore(Loader);
}
@@ -94,10 +88,6 @@ namespace FEXCore::Context {
CTX->FallbackCPUFactory = std::move(Factory);
}
uint64_t HandleSyscall(FEXCore::Context::Context *CTX, FEXCore::Core::ThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) {
return FEXCore::HandleSyscall(CTX->SyscallHandler.get(), reinterpret_cast<FEXCore::Core::InternalThreadState*>(Thread), Args);
}
bool AddVirtualMemoryMapping([[maybe_unused]] FEXCore::Context::Context *CTX, [[maybe_unused]] uint64_t VirtualAddress, [[maybe_unused]] uint64_t PhysicalAddress, [[maybe_unused]] uint64_t Size) {
return false;
}
@@ -113,6 +103,47 @@ namespace FEXCore::Context {
CTX->RegisterFrontendHostSignalHandler(Signal, Func);
}
FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) {
return CTX->CreateThread(NewThreadState, ParentTID);
}
void InitializeThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) {
return CTX->InitializeThread(Thread);
}
void RunThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) {
CTX->RunThread(Thread);
}
void StopThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) {
CTX->StopThread(Thread);
}
void DeleteForkedThreads(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) {
// This function is called after fork
// We need to cleanup some of the thread data that is dead
for (auto &DeadThread : CTX->Threads) {
if (DeadThread == Thread) {
continue;
}
// Setting running to false ensures that when they are shutdown we won't send signals to kill them
DeadThread->State.RunningEvents.Running = false;
}
}
void SetSignalDelegator(FEXCore::Context::Context *CTX, FEXCore::SignalDelegator *SignalDelegation) {
CTX->SignalDelegation = SignalDelegation;
}
void SetSyscallHandler(FEXCore::Context::Context *CTX, FEXCore::HLE::SyscallHandler *Handler) {
CTX->SyscallHandler = Handler;
}
FEXCore::CPUID::FunctionResults RunCPUIDFunction(FEXCore::Context::Context *CTX, uint32_t Function, [[maybe_unused]] uint32_t Leaf) {
return CTX->CPUID.RunFunction(Function);
}
namespace Debug {
void CompileRIP(FEXCore::Context::Context *CTX, uint64_t RIP) {
CTX->CompileRIP(CTX->ParentThread, RIP);
@@ -149,8 +180,6 @@ namespace Debug {
FEXCore::Core::ThreadState *GetThreadState(FEXCore::Context::Context *CTX) {
return CTX->GetThreadState();
}
}
}
+11 -10
View File
@@ -4,9 +4,7 @@
#include "Interface/Core/Frontend.h"
#include "Interface/Core/HostFeatures.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/Core/SignalDelegator.h"
#include "Interface/Core/X86HelperGen.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/IR/PassManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CPUBackend.h>
@@ -17,14 +15,17 @@
#include <mutex>
namespace FEXCore {
class SyscallHandler;
class ThunkHandler;
class BlockSamplingData;
class GdbServer;
class SiganlDelegator;
namespace CPU {
class JITCore;
}
namespace HLE {
class SyscallHandler;
}
}
namespace FEXCore::IR {
@@ -41,7 +42,7 @@ namespace FEXCore::Context {
};
struct Context {
friend class FEXCore::SyscallHandler;
friend class FEXCore::HLE::SyscallHandler;
friend class FEXCore::CPU::JITCore;
friend class FEXCore::IR::Validation::IRValidation;
@@ -57,14 +58,13 @@ namespace FEXCore::Context {
std::string ThunkLibsPath;
bool Is64BitMode {true};
uint64_t EmulatedCPUCores{1};
bool TSOEnabled {true};
bool SMCChecks {false};
bool ABILocalFlags {false};
bool ABINoPF {false};
std::string DumpIR;
} Config;
FEXCore::HostFeatures HostFeatures;
@@ -83,7 +83,7 @@ namespace FEXCore::Context {
bool Running{};
FEXCore::CPUIDEmu CPUID;
std::unique_ptr<FEXCore::SyscallHandler> SyscallHandler;
FEXCore::HLE::SyscallHandler *SyscallHandler{};
std::unique_ptr<FEXCore::ThunkHandler> ThunkHandler;
CustomCPUFactoryType CustomCPUFactory;
@@ -94,7 +94,7 @@ namespace FEXCore::Context {
std::unique_ptr<FEXCore::BlockSamplingData> BlockData;
#endif
SignalDelegator SignalDelegation;
SignalDelegator *SignalDelegation{};
X86GeneratedCode X86CodeGen;
Context();
@@ -139,8 +139,6 @@ namespace FEXCore::Context {
uintptr_t CompileBlock(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP);
uintptr_t CompileFallbackBlock(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP);
FEXCore::CodeLoader *GetCodeLoader() const { return LocalLoader; }
// Used for thread creation from syscalls
void InitializeCompiler(FEXCore::Core::InternalThreadState* State, bool CompileThread);
FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID);
@@ -178,5 +176,8 @@ namespace FEXCore::Context {
#if ENABLE_JITSYMBOLS
FEXCore::JITSymbols Symbols;
#endif
FEXCore::Config::Value<std::string> AppFilename{FEXCore::Config::CONFIG_APP_FILENAME, ""};
};
uint64_t HandleSyscall(FEXCore::HLE::SyscallHandler *Handler, FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args);
}
+25 -25
View File
@@ -7,8 +7,8 @@
namespace FEXCore {
//#define CPUID_AMD
CPUIDEmu::FunctionResults CPUIDEmu::Function_0h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_0h() {
FEXCore::CPUID::FunctionResults Res{};
// EBX, EDX, ECX become the manufacturer id string
#ifdef CPUID_AMD
@@ -26,8 +26,8 @@ CPUIDEmu::FunctionResults CPUIDEmu::Function_0h() {
}
// Processor Info and Features bits
CPUIDEmu::FunctionResults CPUIDEmu::Function_01h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_01h() {
FEXCore::CPUID::FunctionResults Res{};
Res.eax = 0 | // Stepping
(0 << 4) | // Model
@@ -109,15 +109,15 @@ CPUIDEmu::FunctionResults CPUIDEmu::Function_01h() {
return Res;
}
CPUIDEmu::FunctionResults CPUIDEmu::Function_06h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_06h() {
FEXCore::CPUID::FunctionResults Res{};
Res.eax = (1 << 2); // Always running APIC
Res.ecx = (0 << 3); // Intel performance energy bias preference (EPB)
return Res;
}
CPUIDEmu::FunctionResults CPUIDEmu::Function_07h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_07h() {
FEXCore::CPUID::FunctionResults Res{};
// Number of subfunctions
Res.eax = 0x0;
@@ -227,8 +227,8 @@ CPUIDEmu::FunctionResults CPUIDEmu::Function_07h() {
}
// Highest extended function implemented
CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0000h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0000h() {
FEXCore::CPUID::FunctionResults Res{};
Res.eax = 0x8000001F;
// EBX, EDX, ECX become the manufacturer id string
@@ -246,8 +246,8 @@ CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0000h() {
}
// Extended processor and feature bits
CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0001h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0001h() {
FEXCore::CPUID::FunctionResults Res{};
Res.eax = 0 | // Stepping
(0 << 4) | // Model
@@ -333,33 +333,33 @@ constexpr char ProcessorBrand[48] = {
};
//Processor brand string
CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0002h() {
CPUIDEmu::FunctionResults Res{};
memcpy(&Res, &ProcessorBrand[0], sizeof(CPUIDEmu::FunctionResults));
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0002h() {
FEXCore::CPUID::FunctionResults Res{};
memcpy(&Res, &ProcessorBrand[0], sizeof(FEXCore::CPUID::FunctionResults));
return Res;
}
CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0003h() {
CPUIDEmu::FunctionResults Res{};
memcpy(&Res, &ProcessorBrand[16], sizeof(CPUIDEmu::FunctionResults));
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0003h() {
FEXCore::CPUID::FunctionResults Res{};
memcpy(&Res, &ProcessorBrand[16], sizeof(FEXCore::CPUID::FunctionResults));
return Res;
}
CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0004h() {
CPUIDEmu::FunctionResults Res{};
memcpy(&Res, &ProcessorBrand[32], sizeof(CPUIDEmu::FunctionResults));
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0004h() {
FEXCore::CPUID::FunctionResults Res{};
memcpy(&Res, &ProcessorBrand[32], sizeof(FEXCore::CPUID::FunctionResults));
return Res;
}
// Advanced power management
CPUIDEmu::FunctionResults CPUIDEmu::Function_8000_0007h() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0007h() {
FEXCore::CPUID::FunctionResults Res{};
Res.eax = (1 << 2); // APIC timer not affected by p-state
return Res;
}
CPUIDEmu::FunctionResults CPUIDEmu::Function_Reserved() {
CPUIDEmu::FunctionResults Res{};
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_Reserved() {
FEXCore::CPUID::FunctionResults Res{};
return Res;
}
+15 -17
View File
@@ -2,6 +2,8 @@
#include <functional>
#include <unordered_map>
#include <FEXCore/Core/CPUID.h>
namespace FEXCore {
namespace Context {
struct Context;
@@ -20,11 +22,7 @@ private:
public:
void Init(FEXCore::Context::Context *ctx);
struct FunctionResults {
uint32_t eax, ebx, ecx, edx;
};
FunctionResults RunFunction(uint32_t Function) {
FEXCore::CPUID::FunctionResults RunFunction(uint32_t Function) {
auto Handler = FunctionHandlers.find(Function);
if (Handler == FunctionHandlers.end())
@@ -35,7 +33,7 @@ public:
private:
FEXCore::Context::Context *CTX;
using FunctionHandler = std::function<FunctionResults()>;
using FunctionHandler = std::function<FEXCore::CPUID::FunctionResults()>;
void RegisterFunction(uint32_t Function, FunctionHandler Handler) {
FunctionHandlers[Function] = Handler;
}
@@ -43,17 +41,17 @@ private:
std::unordered_map<uint32_t, FunctionHandler> FunctionHandlers;
// Functions
FunctionResults Function_0h();
FunctionResults Function_01h();
FunctionResults Function_06h();
FunctionResults Function_07h();
FunctionResults Function_8000_0000h();
FunctionResults Function_8000_0001h();
FunctionResults Function_8000_0002h();
FunctionResults Function_8000_0003h();
FunctionResults Function_8000_0004h();
FunctionResults Function_8000_0007h();
FEXCore::CPUID::FunctionResults Function_0h();
FEXCore::CPUID::FunctionResults Function_01h();
FEXCore::CPUID::FunctionResults Function_06h();
FEXCore::CPUID::FunctionResults Function_07h();
FEXCore::CPUID::FunctionResults Function_8000_0000h();
FEXCore::CPUID::FunctionResults Function_8000_0001h();
FEXCore::CPUID::FunctionResults Function_8000_0002h();
FEXCore::CPUID::FunctionResults Function_8000_0003h();
FEXCore::CPUID::FunctionResults Function_8000_0004h();
FEXCore::CPUID::FunctionResults Function_8000_0007h();
FunctionResults Function_Reserved();
FEXCore::CPUID::FunctionResults Function_Reserved();
};
}
+1 -2
View File
@@ -3,7 +3,6 @@
#include "Interface/Core/CompileService.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/Core/OpcodeDispatcher.h"
#include "Interface/Core/SignalDelegator.h"
namespace FEXCore {
CompileService::CompileService(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread)
@@ -102,7 +101,7 @@ namespace FEXCore {
void CompileService::ExecutionThread() {
// Ignore signals coming from the guest
CTX->SignalDelegation.MaskThreadSignals();
CTX->SignalDelegation->MaskThreadSignals();
// Set our thread name so we can see its relation
char ThreadName[16]{};
+14 -8
View File
@@ -18,6 +18,7 @@
#include <FEXCore/Core/CoreState.h>
#include <FEXCore/Core/CPUBackend.h>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include "Interface/HLE/Thunks/Thunks.h"
@@ -160,7 +161,7 @@ namespace FEXCore::Context {
}
void Context::SaveEntryList() {
std::string const &Filename = SyscallHandler->GetFilename();
std::string const &Filename = AppFilename();
std::string hash_string;
if (GetFilenameHash(Filename, hash_string)) {
@@ -178,7 +179,7 @@ namespace FEXCore::Context {
}
void Context::LoadEntryList() {
std::string const &Filename = SyscallHandler->GetFilename();
std::string const &Filename = AppFilename();
std::string hash_string;
if (GetFilenameHash(Filename, hash_string)) {
@@ -230,8 +231,6 @@ namespace FEXCore::Context {
}
bool Context::InitCore(FEXCore::CodeLoader *Loader) {
bool Is64Bit = Config.Is64BitMode;
SyscallHandler.reset(FEXCore::CreateHandler(Is64Bit ? OperatingMode::MODE_64BIT : OperatingMode::MODE_32BIT, this));
ThunkHandler.reset(FEXCore::ThunkHandler::Create());
LocalLoader = Loader;
@@ -288,7 +287,7 @@ namespace FEXCore::Context {
}
void Context::RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func) {
SignalDelegation.RegisterFrontendHostSignalHandler(Signal, Func);
SignalDelegation->RegisterFrontendHostSignalHandler(Signal, Func);
}
void Context::WaitForIdle() {
@@ -500,7 +499,8 @@ namespace FEXCore::Context {
State->PassManager->AddDefaultPasses(Config.Core == FEXCore::Config::CONFIG_IRJIT);
State->PassManager->AddDefaultValidationPasses();
State->PassManager->RegisterSyscallHandler(SyscallHandler.get());
State->PassManager->RegisterSyscallHandler(SyscallHandler);
State->CTX = this;
@@ -850,7 +850,7 @@ namespace FEXCore::Context {
// Let's do some initial bookkeeping here
Thread->State.ThreadManager.TID = ::gettid();
Thread->State.ThreadManager.PID = ::getpid();
SignalDelegation.RegisterTLSState(Thread);
SignalDelegation->RegisterTLSState(Thread);
ThunkHandler->RegisterTLSState(Thread);
++IdleWaitRefCount;
@@ -890,7 +890,7 @@ namespace FEXCore::Context {
--IdleWaitRefCount;
IdleWaitCV.notify_all();
SignalDelegation.UninstallTLSState(Thread);
SignalDelegation->UninstallTLSState(Thread);
}
void Context::RemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) {
@@ -970,4 +970,10 @@ namespace FEXCore::Context {
return &ParentThread->State;
}
uint64_t HandleSyscall(FEXCore::HLE::SyscallHandler *Handler, FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) {
uint64_t Result{};
Result = Handler->HandleSyscall(Thread, Args);
return Result;
}
}
+5 -4
View File
@@ -44,7 +44,7 @@ GdbServer::GdbServer(FEXCore::Context::Context *ctx) : CTX(ctx) {
// This is a total hack as there is currently no way to resume once hitting a segfault
// But it's semi-useful for debugging.
ctx->SignalDelegation.RegisterHostSignalHandler(SIGSEGV, [this] (FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) {
ctx->SignalDelegation->RegisterHostSignalHandler(SIGSEGV, [this] (FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) {
this->Break(SIGSEGV);
this->CTX->Config.RunningMode = FEXCore::Context::CoreRunningMode::MODE_SINGLESTEP;
@@ -501,8 +501,9 @@ GdbServer::HandledPacketType GdbServer::handleXfer(std::string &packet) {
};
if (object == "exec-file") {
if (annex_pid == getpid())
return {encode(CTX->SyscallHandler->GetFilename()), HandledPacketType::TYPE_ACK};
if (annex_pid == getpid()) {
return {encode(Filename()), HandledPacketType::TYPE_ACK};
}
return {"E00", HandledPacketType::TYPE_ACK};
}
@@ -568,7 +569,7 @@ GdbServer::HandledPacketType GdbServer::handleProgramOffsets() {
std::fstream fs;
fs.open("/proc/self/maps", std::fstream::in | std::fstream::binary);
std::string Line;
std::string const &RuntimeExecutable = CTX->SyscallHandler->GetFilename();
std::string const &RuntimeExecutable = Filename();
while (std::getline(fs, Line)) {
uint64_t Begin, End;
char Filename[255];
+1
View File
@@ -57,6 +57,7 @@ private:
bool NoAckMode{false};
std::string ThreadString{};
uint32_t CurrentDebuggingThread{};
FEXCore::Config::Value<std::string> Filename{FEXCore::Config::CONFIG_APP_FILENAME, ""};
};
}
@@ -31,7 +31,7 @@ static constexpr size_t MAX_DISPATCHER_CODE_SIZE = 4096;
class DispatchGenerator : public vixl::aarch64::Assembler {
public:
DispatchGenerator(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleSignalPause(int Signal, void *info, void *ucontext);
CPUBackend::AsmDispatch DispatchPtr;
@@ -436,10 +436,10 @@ void DispatchGenerator::RestoreThreadState(void *ucontext) {
// Restore the previous signal state
// This allows recursive signals to properly handle signal masking as we are walking back up the list of signals
CTX->SignalDelegation.SetCurrentSignal(Context->Signal);
CTX->SignalDelegation->SetCurrentSignal(Context->Signal);
}
bool DispatchGenerator::HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) {
bool DispatchGenerator::HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) {
ucontext_t* _context = (ucontext_t*)ucontext;
mcontext_t* _mcontext = &_context->uc_mcontext;
@@ -542,7 +542,7 @@ void InterpreterCore::CreateAsmDispatch(FEXCore::Context::Context *ctx, FEXCore:
CallbackPtr = Generator->CallbackPtr;
}
bool InterpreterCore::HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) {
bool InterpreterCore::HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) {
DispatchGenerator *Gen = Generator;
return Gen->HandleGuestSignal(Signal, info, ucontext, GuestAction, GuestStack);
}
@@ -42,7 +42,7 @@ private:
uint32_t AllocateTmpSpace(size_t Size);
bool HandleSignalPause(int Signal, void *info, void *ucontext);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack);
template<typename Res>
Res GetDest(void* SSAData, IR::OrderedNodeWrapper Op);
@@ -5,10 +5,10 @@
#include "Interface/Core/DebugData.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/Core/Interpreter/InterpreterClass.h"
#include "Interface/HLE/Syscalls.h"
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Core/CPUBackend.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/IR/IR.h>
#include <FEXCore/IR/IntrusiveIRList.h>
@@ -337,18 +337,18 @@ InterpreterCore::InterpreterCore(FEXCore::Context::Context *ctx, FEXCore::Core::
if (!CompileThread) {
CreateAsmDispatch(ctx, Thread);
CTX->SignalDelegation.RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
CTX->SignalDelegation->RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
InterpreterCore *Core = reinterpret_cast<InterpreterCore*>(Thread->IntBackend.get());
return Core->HandleSignalPause(Signal, info, ucontext);
});
auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) -> bool {
auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) -> bool {
InterpreterCore *Core = reinterpret_cast<InterpreterCore*>(Thread->CPUBackend.get());
return Core->HandleGuestSignal(Signal, info, ucontext, GuestAction, GuestStack);
};
for (uint32_t Signal = 0; Signal < SignalDelegator::MAX_SIGNALS; ++Signal) {
CTX->SignalDelegation.RegisterHostSignalHandlerForGuest(Signal, GuestSignalHandler);
CTX->SignalDelegation->RegisterHostSignalHandlerForGuest(Signal, GuestSignalHandler);
}
}
}
@@ -485,7 +485,6 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
for (auto [CodeNode, IROp] : CurrentIR->GetCode(BlockNode)) {
OrderedNodeWrapper WrapperOp = CodeNode->Wrapped(ListBegin);
uint8_t OpSize = IROp->Size;
uint32_t Node = CurrentIR->GetID(CodeNode);
switch (IROp->Op) {
case IR::OP_VALIDATECODE: {
@@ -586,7 +585,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
Args.Argument[j] = *GetSrc<uint64_t*>(SSAData, Op->Header.Args[j]);
}
uint64_t Res = FEXCore::HandleSyscall(CTX->SyscallHandler.get(), Thread, &Args);
uint64_t Res = FEXCore::Context::HandleSyscall(CTX->SyscallHandler, Thread, &Args);
GD = Res;
break;
}
@@ -12,7 +12,7 @@ static constexpr size_t MAX_DISPATCHER_CODE_SIZE = 4096;
class DispatchGenerator : public Xbyak::CodeGenerator {
public:
DispatchGenerator(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleSignalPause(int Signal, void *info, void *ucontext);
CPUBackend::AsmDispatch DispatchPtr;
@@ -342,10 +342,10 @@ void DispatchGenerator::RestoreThreadState(void *ucontext) {
// Restore the previous signal state
// This allows recursive signals to properly handle signal masking as we are walking back up the list of signals
CTX->SignalDelegation.SetCurrentSignal(Context->Signal);
CTX->SignalDelegation->SetCurrentSignal(Context->Signal);
}
bool DispatchGenerator::HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) {
bool DispatchGenerator::HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) {
ucontext_t* _context = (ucontext_t*)ucontext;
mcontext_t* _mcontext = &_context->uc_mcontext;
@@ -450,7 +450,7 @@ void InterpreterCore::CreateAsmDispatch(FEXCore::Context::Context *ctx, FEXCore:
ReturnPtr = Generator->ReturnPtr;
}
bool InterpreterCore::HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) {
bool InterpreterCore::HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) {
DispatchGenerator *Gen = Generator;
return Gen->HandleGuestSignal(Signal, info, ucontext, GuestAction, GuestStack);
}
@@ -2,6 +2,7 @@
#include "Interface/Core/InternalThreadState.h"
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/HLE/SyscallHandler.h>
namespace FEXCore::CPU {
using namespace vixl;
@@ -176,11 +177,11 @@ DEF_OP(Syscall) {
}
str(lr, MemOperand(sp, 7 * 8 + RA64.size() * 8 + 0 * 8));
LoadConstant(x0, reinterpret_cast<uint64_t>(CTX->SyscallHandler.get()));
LoadConstant(x0, reinterpret_cast<uint64_t>(CTX->SyscallHandler));
mov(x1, STATE);
mov(x2, sp);
LoadConstant(x3, reinterpret_cast<uint64_t>(FEXCore::HandleSyscall));
LoadConstant(x3, reinterpret_cast<uint64_t>(FEXCore::Context::HandleSyscall));
blr(x3);
// Result is now in x0
@@ -331,7 +332,7 @@ DEF_OP(CPUID) {
LoadConstant(x0, reinterpret_cast<uint64_t>(&CTX->CPUID));
mov(x1, GetReg<RA_64>(Op->Header.Args[0].ID()));
using ClassPtrType = FEXCore::CPUIDEmu::FunctionResults (FEXCore::CPUIDEmu::*)(uint32_t);
using ClassPtrType = FEXCore::CPUID::FunctionResults (FEXCore::CPUIDEmu::*)(uint32_t);
union PtrCast {
ClassPtrType ClassPtr;
uintptr_t Data;
+7 -7
View File
@@ -170,7 +170,7 @@ void JITCore::RestoreThreadState(void *ucontext) {
// Restore the previous signal state
// This allows recursive signals to properly handle signal masking as we are walking back up the list of signals
CTX->SignalDelegation.SetCurrentSignal(Context->Signal);
CTX->SignalDelegation->SetCurrentSignal(Context->Signal);
}
bool JITCore::HandleSIGILL(int Signal, void *info, void *ucontext) {
@@ -198,7 +198,7 @@ bool JITCore::HandleSIGILL(int Signal, void *info, void *ucontext) {
return false;
}
bool JITCore::HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) {
bool JITCore::HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) {
ucontext_t* _context = (ucontext_t*)ucontext;
mcontext_t* _mcontext = &_context->uc_mcontext;
@@ -522,28 +522,28 @@ JITCore::JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadSt
CreateCustomDispatch(Thread);
// This will register the host signal handler per thread, which is fine
CTX->SignalDelegation.RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleSIGILL(Signal, info, ucontext);
});
CTX->SignalDelegation.RegisterHostSignalHandler(SIGBUS, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
CTX->SignalDelegation->RegisterHostSignalHandler(SIGBUS, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleSIGBUS(Signal, info, ucontext);
});
CTX->SignalDelegation.RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
CTX->SignalDelegation->RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleSignalPause(Signal, info, ucontext);
});
auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) -> bool {
auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleGuestSignal(Signal, info, ucontext, GuestAction, GuestStack);
};
for (uint32_t Signal = 0; Signal < SignalDelegator::MAX_SIGNALS; ++Signal) {
CTX->SignalDelegation.RegisterHostSignalHandlerForGuest(Signal, GuestSignalHandler);
CTX->SignalDelegation->RegisterHostSignalHandlerForGuest(Signal, GuestSignalHandler);
}
}
}
@@ -95,7 +95,7 @@ public:
bool HandleSIGILL(int Signal, void *info, void *ucontext);
bool HandleSIGBUS(int Signal, void *info, void *ucontext);
bool HandleSignalPause(int Signal, void *info, void *ucontext);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack);
static constexpr size_t INITIAL_CODE_SIZE = 1024 * 1024 * 16;
static CodeBuffer AllocateNewCodeBuffer(size_t Size);
@@ -2,6 +2,7 @@
#include "Interface/IR/Passes/RegisterAllocationPass.h"
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/HLE/SyscallHandler.h>
namespace FEXCore::CPU {
#define DEF_OP(x) void JITCore::Op_##x(FEXCore::IR::IROp_Header *IROp, uint32_t Node)
@@ -159,10 +160,10 @@ DEF_OP(Syscall) {
}
mov(rsi, STATE); // Move thread in to rsi
mov(rdi, reinterpret_cast<uint64_t>(CTX->SyscallHandler.get()));
mov(rdi, reinterpret_cast<uint64_t>(CTX->SyscallHandler));
mov(rdx, rsp);
mov(rax, reinterpret_cast<uint64_t>(FEXCore::HandleSyscall));
mov(rax, reinterpret_cast<uint64_t>(FEXCore::Context::HandleSyscall));
if (NumPush & 1)
sub(rsp, 8); // Align
@@ -209,7 +210,6 @@ DEF_OP(Thunk) {
DEF_OP(ValidateCode) {
auto Op = IROp->C<IR::IROp_ValidateCode>();
uint8_t* NewCode = (uint8_t*)Op->CodePtr;
uint8_t* OldCode = (uint8_t*)&Op->CodeOriginal;
int len = Op->CodeLength;
int idx = 0;
@@ -267,7 +267,7 @@ DEF_OP(RemoveCodeEntry) {
DEF_OP(CPUID) {
auto Op = IROp->C<IR::IROp_CPUID>();
using ClassPtrType = FEXCore::CPUIDEmu::FunctionResults (FEXCore::CPUIDEmu::*)(uint32_t Function);
using ClassPtrType = FEXCore::CPUID::FunctionResults (FEXCore::CPUIDEmu::*)(uint32_t Function);
union {
ClassPtrType ClassPtr;
uint64_t Raw;
+7 -6
View File
@@ -9,6 +9,7 @@
#include <FEXCore/Core/UContext.h>
#include <cmath>
#include <signal.h>
// #define DEBUG_RA 1
// #define DEBUG_CYCLES
@@ -115,10 +116,10 @@ void JITCore::RestoreThreadState(void *ucontext) {
// Restore the previous signal state
// This allows recursive signals to properly handle signal masking as we are walking back up the list of signals
CTX->SignalDelegation.SetCurrentSignal(Context->Signal);
CTX->SignalDelegation->SetCurrentSignal(Context->Signal);
}
bool JITCore::HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) {
bool JITCore::HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) {
ucontext_t* _context = (ucontext_t*)ucontext;
mcontext_t* _mcontext = &_context->uc_mcontext;
@@ -388,23 +389,23 @@ JITCore::JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadSt
CreateCustomDispatch(Thread);
// This will register the host signal handler per thread, which is fine
CTX->SignalDelegation.RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleSIGILL(Signal, info, ucontext);
});
CTX->SignalDelegation.RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
CTX->SignalDelegation->RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleSignalPause(Signal, info, ucontext);
});
auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack) -> bool {
auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) -> bool {
JITCore *Core = reinterpret_cast<JITCore*>(Thread->CPUBackend.get());
return Core->HandleGuestSignal(Signal, info, ucontext, GuestAction, GuestStack);
};
for (uint32_t Signal = 0; Signal < SignalDelegator::MAX_SIGNALS; ++Signal) {
CTX->SignalDelegation.RegisterHostSignalHandlerForGuest(Signal, GuestSignalHandler);
CTX->SignalDelegation->RegisterHostSignalHandlerForGuest(Signal, GuestSignalHandler);
}
}
}
@@ -71,7 +71,7 @@ public:
bool HandleSIGILL(int Signal, void *info, void *ucontext);
bool HandleSignalPause(int Signal, void *info, void *ucontext);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, SignalDelegator::GuestSigAction *GuestAction, stack_t *GuestStack);
bool HandleGuestSignal(int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack);
void CopyNecessaryDataForCompileThread(CPUBackend *Original) override;
private:
+26 -20
View File
@@ -8,6 +8,7 @@
#include <cstdint>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/HLE/SyscallHandler.h>
namespace FEXCore::IR {
@@ -46,31 +47,36 @@ void OpDispatchBuilder::SyscallOp(OpcodeArgs) {
constexpr size_t SyscallArgs = 7;
std::array<uint64_t, SyscallArgs> *GPRIndexes {};
static std::array<uint64_t, SyscallArgs> GPRIndexes_64 = {
FEXCore::X86State::REG_RAX,
FEXCore::X86State::REG_RDI,
FEXCore::X86State::REG_RSI,
FEXCore::X86State::REG_RDX,
FEXCore::X86State::REG_R10,
FEXCore::X86State::REG_R8,
FEXCore::X86State::REG_R9,
};
if (CTX->Config.Is64BitMode) {
static std::array<uint64_t, SyscallArgs> GPRIndexes_64 = {
FEXCore::X86State::REG_RAX,
FEXCore::X86State::REG_RDI,
FEXCore::X86State::REG_RSI,
FEXCore::X86State::REG_RDX,
FEXCore::X86State::REG_R10,
FEXCore::X86State::REG_R8,
FEXCore::X86State::REG_R9,
};
static std::array<uint64_t, SyscallArgs> GPRIndexes_32 = {
FEXCore::X86State::REG_RAX,
FEXCore::X86State::REG_RBX,
FEXCore::X86State::REG_RCX,
FEXCore::X86State::REG_RDX,
FEXCore::X86State::REG_RSI,
FEXCore::X86State::REG_RDI,
FEXCore::X86State::REG_RBP,
};
auto OSABI = CTX->SyscallHandler->GetOSABI();
if (OSABI == FEXCore::HLE::SyscallOSABI::OS_LINUX64) {
GPRIndexes = &GPRIndexes_64;
}
else {
static std::array<uint64_t, SyscallArgs> GPRIndexes_32 = {
FEXCore::X86State::REG_RAX,
FEXCore::X86State::REG_RBX,
FEXCore::X86State::REG_RCX,
FEXCore::X86State::REG_RDX,
FEXCore::X86State::REG_RSI,
FEXCore::X86State::REG_RDI,
FEXCore::X86State::REG_RBP,
};
else if (OSABI == FEXCore::HLE::SyscallOSABI::OS_LINUX32) {
GPRIndexes = &GPRIndexes_32;
}
else {
LogMan::Msg::D("Unhandled OSABI syscall");
}
auto NewRIP = _Constant(GPRSize * 8, Op->PC);
_StoreContext(GPRClass, GPRSize, offsetof(FEXCore::Core::CPUState, rip), NewRIP);
+3 -3
View File
@@ -7,7 +7,7 @@
#include <memory>
#include <vector>
namespace FEXCore {
namespace FEXCore::HLE {
class SyscallHandler;
}
@@ -56,13 +56,13 @@ public:
return reinterpret_cast<IR::RegisterAllocationPass*>(RAPass);
}
void RegisterSyscallHandler(SyscallHandler *Handler) {
void RegisterSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) {
SyscallHandler = Handler;
}
protected:
ShouldExitHandler ExitHandler;
SyscallHandler *SyscallHandler;
FEXCore::HLE::SyscallHandler *SyscallHandler;
private:
Pass *RAPass{};
@@ -4,6 +4,7 @@
#include "Interface/Core/OpcodeDispatcher.h"
#include <iterator>
#include <unordered_set>
namespace {
constexpr uint32_t INVALID_REG = ~0U;
@@ -2,6 +2,7 @@
#include "Interface/IR/PassManager.h"
#include "Interface/Core/OpcodeDispatcher.h"
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::IR {
@@ -22,12 +23,12 @@ bool SyscallOptimization::Run(IREmitter *IREmit) {
// Is the first argument a constant?
uint64_t Constant;
if (IREmit->IsValueConstant(IROp->Args[0], &Constant)) {
auto SyscallDef = Manager->SyscallHandler->GetDefinition(Constant);
auto SyscallDef = Manager->SyscallHandler->GetSyscallABI(Constant);
// XXX: Once we have the ability to do real function calls then we can call directly in to the syscall handler
if (SyscallDef->NumArgs < FEXCore::HLE::SyscallArguments::MAX_ARGS) {
if (SyscallDef.NumArgs < FEXCore::HLE::SyscallArguments::MAX_ARGS) {
// If the number of args are less than what the IR op supports then we can remove arg usage
// We need +1 since we are still passing in syscall number here
for (uint8_t Arg = (SyscallDef->NumArgs + 1); Arg < FEXCore::HLE::SyscallArguments::MAX_ARGS; ++Arg) {
for (uint8_t Arg = (SyscallDef.NumArgs + 1); Arg < FEXCore::HLE::SyscallArguments::MAX_ARGS; ++Arg) {
IREmit->ReplaceNodeArgument(CodeNode, Arg, IREmit->Invalid());
}
Changed = true;
+1
View File
@@ -29,6 +29,7 @@ namespace FEXCore::Config {
CONFIG_DUMP_GPRS,
CONFIG_IS_INTERPRETER,
CONFIG_INTERPRETER_INSTALLED,
CONFIG_APP_FILENAME,
};
enum ConfigCore {
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <cstdint>
namespace FEXCore::CPUID {
struct FunctionResults {
uint32_t eax, ebx, ecx, edx;
};
}
+10 -13
View File
@@ -4,6 +4,7 @@
#include <string>
#include <FEXCore/Core/SignalDelegator.h>
#include <FEXCore/Core/CPUID.h>
namespace FEXCore {
class CodeLoader;
@@ -21,6 +22,7 @@ namespace FEXCore::CPU {
namespace FEXCore::HLE {
struct SyscallArguments;
class SyscallVisitor;
class SyscallHandler;
}
namespace FEXCore::Context {
@@ -81,8 +83,6 @@ namespace FEXCore::Context {
*/
bool InitCore(FEXCore::Context::Context *CTX, FEXCore::CodeLoader *Loader);
void SetApplicationFile(FEXCore::Context::Context *CTX, std::string const &File);
void SetExitHandler(FEXCore::Context::Context *CTX, std::function<void(uint64_t ThreadId, FEXCore::Context::ExitReason)> handler);
std::function<void(uint64_t ThreadId, FEXCore::Context::ExitReason)> GetExitHandler(FEXCore::Context::Context *CTX);
@@ -195,17 +195,6 @@ namespace FEXCore::Context {
*/
void SetFallbackCPUBackendFactory(FEXCore::Context::Context *CTX, CustomCPUFactoryType Factory);
/**
* @brief This allows a frontend core to call Syscall routines directly. Useful for debugging
*
* @param CTX The context that we created
* @param Thread The thread to run the syscall on
* @param Args The arguments to the syscall
*
* @return The value that a syscall returns
*/
uint64_t HandleSyscall(FEXCore::Context::Context *CTX, FEXCore::Core::ThreadState *Thread, FEXCore::HLE::SyscallArguments *Args);
/**
* @brief Sets up memory regions on the guest for mirroring within the guest's VM space
*
@@ -231,4 +220,12 @@ namespace FEXCore::Context {
void RegisterFrontendHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func);
FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID);
void InitializeThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread);
void RunThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread);
void StopThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread);
void DeleteForkedThreads(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread);
void SetSignalDelegator(FEXCore::Context::Context *CTX, FEXCore::SignalDelegator *SignalDelegation);
void SetSyscallHandler(FEXCore::Context::Context *CTX, FEXCore::HLE::SyscallHandler *Handler);
FEXCore::CPUID::FunctionResults RunCPUIDFunction(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf);
}
+58
View File
@@ -1,10 +1,68 @@
#pragma once
#include <cstdint>
#include <functional>
#include <signal.h>
namespace FEXCore {
namespace Core {
struct InternalThreadState;
}
struct __attribute__((packed)) GuestSAMask {
uint64_t Val;
};
struct __attribute__((packed)) GuestSigAction {
union {
void (*handler)(int);
void (*sigaction)(int, siginfo_t *, void*);
} sigaction_handler;
uint64_t sa_flags;
void (*restorer)(void);
GuestSAMask sa_mask;
};
using HostSignalDelegatorFunction = std::function<bool(FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext)>;
using HostSignalDelegatorFunctionForGuest = std::function<bool(FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack)>;
class SignalDelegator {
public:
/**
* @brief Registers an emulated thread's object to a TLS object
*
* Required to know which thread has received the signal when it occurs
*/
virtual void RegisterTLSState(FEXCore::Core::InternalThreadState *Thread) = 0;
virtual void UninstallTLSState(FEXCore::Core::InternalThreadState *Thread) = 0;
/**
* @brief Masks a thread from receiving any signals that aren't synchronous
*
* Any helper thread that is generated needs to call this routine to ensure it doesn't receive errant signals to handle
*/
virtual void MaskThreadSignals() = 0;
virtual void SetCurrentSignal(uint32_t Signal) = 0;
/**
* @brief Registers a signal handler for the host to handle a signal
*
* It's a process level signal handler so one must be careful
*/
virtual void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func) = 0;
virtual void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func) = 0;
/**
* @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
*/
virtual void RegisterHostSignalHandlerForGuest(int Signal, HostSignalDelegatorFunctionForGuest Func) = 0;
constexpr static size_t MAX_SIGNALS {64};
// Use the last signal just so we are less likely to ever conflict with something that the guest application is using
// 64 is used internally by Valgrind
constexpr static size_t SIGNAL_FOR_PAUSE {63};
};
}
+38
View File
@@ -1,9 +1,47 @@
#pragma once
#include <cstdint>
#include <string>
namespace FEXCore::Context {
struct Context;
}
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
struct SyscallArguments {
static constexpr std::size_t MAX_ARGS = 7;
uint64_t Argument[MAX_ARGS];
};
struct SyscallABI {
// Expectation is that the backend will be aware of how to modify the arguments based on numbering
// Only GPRs expected
uint8_t NumArgs;
// If the syscall has a return then it should be stored in the ABI specific syscall register
// Linux = RAX
bool HasReturn;
};
enum class SyscallOSABI {
OS_LINUX64,
OS_LINUX32,
OS_WIN64,
OS_WIN32,
};
class SyscallHandler {
public:
virtual ~SyscallHandler() = default;
virtual uint64_t HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) = 0;
virtual SyscallABI GetSyscallABI(uint64_t Syscall) = 0;
SyscallOSABI GetOSABI() const { return OSABI; }
protected:
SyscallOSABI OSABI;
};
}
+53 -4
View File
@@ -6,10 +6,57 @@ if(NOT CMAKE_ASM_NASM_COMPILER_LOADED)
error("Failed to find NASM compatible assembler!")
endif()
set(SYSCALL_SRCS
LinuxSyscalls/FileManagement.cpp
LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp
LinuxSyscalls/SignalDelegator.cpp
LinuxSyscalls/Syscalls.cpp
LinuxSyscalls/x32/Syscalls.cpp
LinuxSyscalls/x32/FD.cpp
LinuxSyscalls/x32/FS.cpp
LinuxSyscalls/x32/Info.cpp
LinuxSyscalls/x32/Memory.cpp
LinuxSyscalls/x32/NotImplemented.cpp
LinuxSyscalls/x32/Semaphore.cpp
LinuxSyscalls/x32/Sched.cpp
LinuxSyscalls/x32/Socket.cpp
LinuxSyscalls/x32/Thread.cpp
LinuxSyscalls/x32/Time.cpp
LinuxSyscalls/x64/FD.cpp
LinuxSyscalls/x64/IO.cpp
LinuxSyscalls/x64/Ioctl.cpp
LinuxSyscalls/x64/Info.cpp
LinuxSyscalls/x64/Memory.cpp
LinuxSyscalls/x64/Msg.cpp
LinuxSyscalls/x64/NotImplemented.cpp
LinuxSyscalls/x64/Semaphore.cpp
LinuxSyscalls/x64/Sched.cpp
LinuxSyscalls/x64/Socket.cpp
LinuxSyscalls/x64/Thread.cpp
LinuxSyscalls/x64/Syscalls.cpp
LinuxSyscalls/x64/Time.cpp
LinuxSyscalls/Syscalls/EPoll.cpp
LinuxSyscalls/Syscalls/FD.cpp
LinuxSyscalls/Syscalls/FS.cpp
LinuxSyscalls/Syscalls/Info.cpp
LinuxSyscalls/Syscalls/IO.cpp
LinuxSyscalls/Syscalls/Key.cpp
LinuxSyscalls/Syscalls/Memory.cpp
LinuxSyscalls/Syscalls/Msg.cpp
LinuxSyscalls/Syscalls/Sched.cpp
LinuxSyscalls/Syscalls/Semaphore.cpp
LinuxSyscalls/Syscalls/SHM.cpp
LinuxSyscalls/Syscalls/Signals.cpp
LinuxSyscalls/Syscalls/Socket.cpp
LinuxSyscalls/Syscalls/Thread.cpp
LinuxSyscalls/Syscalls/Time.cpp
LinuxSyscalls/Syscalls/Timer.cpp
LinuxSyscalls/Syscalls/NotImplemented.cpp
LinuxSyscalls/Syscalls/Stubs.cpp
)
set(LIBS FEXCore Common CommonCore pthread)
set(NAME FEXLoader)
set(SRCS ELFLoader.cpp)
set(SRCS ELFLoader.cpp ${SYSCALL_SRCS})
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
@@ -72,7 +119,8 @@ target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_link_libraries(${NAME} ${LIBS})
set(NAME TestHarnessRunner)
set(SRCS TestHarnessRunner.cpp)
set(SRCS TestHarnessRunner.cpp
${SYSCALL_SRCS})
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
@@ -90,7 +138,8 @@ target_link_libraries(${NAME} ${LIBS})
set(NAME IRLoader)
set(SRCS
IRLoader.cpp
IRLoader/Loader.cpp)
IRLoader/Loader.cpp
${SYSCALL_SRCS})
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
+10 -3
View File
@@ -2,6 +2,8 @@
#include "Common/EnvironmentLoader.h"
#include "Common/Config.h"
#include "HarnessHelpers.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/SignalDelegator.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
@@ -193,7 +195,6 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::Value<bool> SingleStepConfig{FEXCore::Config::CONFIG_SINGLESTEP, false};
FEXCore::Config::Value<bool> MultiblockConfig{FEXCore::Config::CONFIG_MULTIBLOCK, false};
FEXCore::Config::Value<bool> GdbServerConfig{FEXCore::Config::CONFIG_GDBSERVER, false};
FEXCore::Config::Value<uint64_t> ThreadsConfig{FEXCore::Config::CONFIG_EMULATED_CPU_CORES, 1};
FEXCore::Config::Value<std::string> LDPath{FEXCore::Config::CONFIG_ROOTFSPATH, ""};
FEXCore::Config::Value<std::string> ThunkLibsPath{FEXCore::Config::CONFIG_THUNKLIBSPATH, ""};
FEXCore::Config::Value<bool> SilentLog{FEXCore::Config::CONFIG_SILENTLOGS, false};
@@ -205,6 +206,7 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::Value<bool> ABILocalFlags{FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS, false};
FEXCore::Config::Value<bool> AbiNoPF{FEXCore::Config::CONFIG_ABI_NO_PF, false};
::SilentLog = SilentLog();
if (!::SilentLog) {
@@ -243,15 +245,20 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ROOTFSPATH, LDPath());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_THUNKLIBSPATH, ThunkLibsPath());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_EMULATED_CPU_CORES, ThreadsConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_TSO_ENABLED, TSOEnabledConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SMC_CHECKS, SMCChecksConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS, ABILocalFlags());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DUMPIR, DumpIR());
FEXCore::Config::Set(FEXCore::Config::CONFIG_APP_FILENAME, std::filesystem::canonical(Program));
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0");
std::unique_ptr<FEX::HLE::SignalDelegator> SignalDelegation = std::make_unique<FEX::HLE::SignalDelegator>();
std::unique_ptr<FEXCore::HLE::SyscallHandler> SyscallHandler{FEX::HLE::CreateHandler(Loader.Is64BitMode() ? FEXCore::Context::OperatingMode::MODE_64BIT : FEXCore::Context::OperatingMode::MODE_32BIT, CTX, SignalDelegation.get())};
FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get());
FEXCore::Context::SetSyscallHandler(CTX, SyscallHandler.get());
FEXCore::Context::InitCore(CTX, &Loader);
FEXCore::Context::SetApplicationFile(CTX, std::filesystem::canonical(Program));
FEXCore::Context::ExitReason ShutdownReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN;
+5
View File
@@ -3,6 +3,8 @@
#include "Common/Config.h"
#include "HarnessHelpers.h"
#include "IRLoader/Loader.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/SignalDelegator.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
@@ -118,6 +120,9 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_MAXBLOCKINST, BlockSizeConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_GDBSERVER, GdbServerConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ROOTFSPATH, LDPath());
std::unique_ptr<FEX::HLE::SignalDelegator> SignalDelegation = std::make_unique<FEX::HLE::SignalDelegator>();
FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get());
FEX::IRLoader::InitializeStaticTables();
FEX::IRLoader::Loader Loader(Args[0], Args[1]);
@@ -3,30 +3,30 @@
#include <FEXCore/Utils/LogManager.h>
#include "FEXCore/Core/CodeLoader.h"
#include "Interface/Context/Context.h"
#include "Interface/HLE/FileManagement.h"
#include "Interface/HLE/EmulatedFiles/EmulatedFiles.h"
#include <FEXCore/Core/Context.h>
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/FileManagement.h"
#include "Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h"
using string = std::string;
namespace FEXCore::EmulatedFile {
namespace FEX::EmulatedFile {
std::string GenerateCPUInfo(FEXCore::Context::Context *ctx, uint32_t CPUCores) {
std::ostringstream cpu_stream{};
auto res_0 = ctx->CPUID.RunFunction(0);
auto res_1 = ctx->CPUID.RunFunction(1);
auto res_6 = ctx->CPUID.RunFunction(6);
auto res_7 = ctx->CPUID.RunFunction(7);
auto res_10 = ctx->CPUID.RunFunction(0x10);
auto res_0 = FEXCore::Context::RunCPUIDFunction(ctx, 0, 0);
auto res_1 = FEXCore::Context::RunCPUIDFunction(ctx, 1, 0);
auto res_6 = FEXCore::Context::RunCPUIDFunction(ctx, 6, 0);
auto res_7 = FEXCore::Context::RunCPUIDFunction(ctx, 7, 0);
auto res_10 = FEXCore::Context::RunCPUIDFunction(ctx, 0x10, 0);
auto res_8000_0001 = ctx->CPUID.RunFunction(0x8000'0001);
auto res_8000_0002 = ctx->CPUID.RunFunction(0x8000'0002);
auto res_8000_0003 = ctx->CPUID.RunFunction(0x8000'0003);
auto res_8000_0004 = ctx->CPUID.RunFunction(0x8000'0004);
auto res_8000_0007 = ctx->CPUID.RunFunction(0x8000'0007);
auto res_8000_0008 = ctx->CPUID.RunFunction(0x8000'0008);
auto res_8000_000a = ctx->CPUID.RunFunction(0x8000'000a);
auto res_8000_001f = ctx->CPUID.RunFunction(0x8000'001f);
auto res_8000_0001 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0001, 0);
auto res_8000_0002 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0002, 0);
auto res_8000_0003 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0003, 0);
auto res_8000_0004 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0004, 0);
auto res_8000_0007 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0007, 0);
auto res_8000_0008 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0008, 0);
auto res_8000_000a = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'000a, 0);
auto res_8000_001f = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'001f, 0);
union VendorID {
struct {
@@ -34,7 +34,7 @@ namespace FEXCore::EmulatedFile {
char Str[13];
};
struct {
FEXCore::CPUIDEmu::FunctionResults cpuid;
FEXCore::CPUID::FunctionResults cpuid;
uint8_t null;
};
};
@@ -44,15 +44,15 @@ namespace FEXCore::EmulatedFile {
char Str[49];
};
struct {
FEXCore::CPUIDEmu::FunctionResults cpuid_2;
FEXCore::CPUIDEmu::FunctionResults cpuid_3;
FEXCore::CPUIDEmu::FunctionResults cpuid_4;
FEXCore::CPUID::FunctionResults cpuid_2;
FEXCore::CPUID::FunctionResults cpuid_3;
FEXCore::CPUID::FunctionResults cpuid_4;
uint8_t null;
};
};
union Info {
FEXCore::CPUIDEmu::FunctionResults cpuid;
FEXCore::CPUID::FunctionResults cpuid;
struct {
unsigned Stepping : 4;
unsigned Model : 4;
@@ -319,7 +319,7 @@ namespace FEXCore::EmulatedFile {
"cat_l3")
FLAG(res_10.ebx & (1 << 2),
"cat_l2")
FLAG(false, /* Needs leaf support */
FLAG(false, // Needs leaf support
"cdp_l3")
FLAG(false, "invpcid_single")
FLAG(res_8000_0007.edx & (1 << 7),
@@ -332,7 +332,7 @@ namespace FEXCore::EmulatedFile {
// We don't support Intel's Protected Processor Inventory Number
FLAG(false, "intel_ppin")
FLAG(false, /* Needs leaf support */
FLAG(false, // Needs leaf support
"cdp_l2")
FLAG(res_8000_0008.ebx & (1 << 6),
@@ -425,16 +425,16 @@ namespace FEXCore::EmulatedFile {
"avx512bw")
FLAG(res_7.ebx & (1 << 31),
"avx512vl")
FLAG(false, /* Needs leaf support */ // res_d.eax & (1 << 0) // Leaf 1h
FLAG(false, // Needs leaf support // res_d.eax & (1 << 0) // Leaf 1h
"xsaveopt")
FLAG(false, /* Needs leaf support */ // res_d.eax & (1 << 1) // Leaf 1h
FLAG(false, // Needs leaf support // res_d.eax & (1 << 1) // Leaf 1h
"xsavec")
FLAG(false, /* Needs leaf support */ // res_d.eax & (1 << 2) // Leaf 1h
FLAG(false, // Needs leaf support // res_d.eax & (1 << 2) // Leaf 1h
"xgetbv1")
FLAG(false, /* Needs leaf support */ // res_d.eax & (1 << 3) // Leaf 1h
FLAG(false, // Needs leaf support // res_d.eax & (1 << 3) // Leaf 1h
"xsaves")
FLAG(false, /* Needs leaf support */
FLAG(false, // Needs leaf support
"avx512_bf16")
FLAG(res_8000_0008.ebx & (1 << 0),
"clzero")
@@ -604,11 +604,12 @@ namespace FEXCore::EmulatedFile {
FDReadCreators["/proc/self/auxv"] = &EmulatedFDManager::ProcAuxv;
cpus_online = "0";
if (ctx->Config.EmulatedCPUCores > 1) {
cpus_online += "-" + std::to_string(ctx->Config.EmulatedCPUCores - 1);
uint64_t CPUCores = ThreadsConfig();
if (CPUCores > 1) {
cpus_online += "-" + std::to_string(CPUCores - 1);
}
cpu_info = GenerateCPUInfo(ctx, ctx->Config.EmulatedCPUCores);
cpu_info = GenerateCPUInfo(ctx, CPUCores);
}
EmulatedFDManager::~EmulatedFDManager() {
@@ -633,7 +634,7 @@ namespace FEXCore::EmulatedFile {
int32_t EmulatedFDManager::ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode)
{
uint64_t auxvBase=0, auxvSize=0;
ctx->GetCodeLoader()->GetAuxv(auxvBase, auxvSize);
FEX::HLE::_SyscallHandler->GetCodeLoader()->GetAuxv(auxvBase, auxvSize);
if (!auxvBase) {
LogMan::Msg::D("Failed to get Auxv stack address");
return -1;
@@ -645,6 +646,5 @@ namespace FEXCore::EmulatedFile {
int32_t f = fileno(fp);
return f;
}
}
@@ -1,4 +1,5 @@
#pragma once
#include <FEXCore/Config/Config.h>
#include <cstdint>
#include <functional>
@@ -13,7 +14,7 @@ namespace FEXCore::Context {
struct Context;
}
namespace FEXCore::EmulatedFile {
namespace FEX::EmulatedFile {
class EmulatedFDManager {
public:
EmulatedFDManager(FEXCore::Context::Context *ctx);
@@ -29,5 +30,6 @@ namespace FEXCore::EmulatedFile {
std::unordered_map<std::string, FDReadStringFunc> FDReadCreators;
static int32_t ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode);
FEXCore::Config::Value<uint64_t> ThreadsConfig{FEXCore::Config::CONFIG_EMULATED_CPU_CORES, 1};
};
}
@@ -1,7 +1,7 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/FileManagement.h"
#include "Tests/LinuxSyscalls/FileManagement.h"
#include <FEXCore/Utils/LogManager.h>
#include <cstring>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
@@ -14,12 +14,10 @@
#include <sys/vfs.h>
#include <unistd.h>
namespace FEXCore {
namespace FEX::HLE {
FileManager::FileManager(FEXCore::Context::Context *ctx)
: CTX {ctx}
, EmuFD {ctx} {
: EmuFD {ctx} {
// calculate the non-self link to exe
// Some executables do getpid, stat("/proc/$pid/exe")
int pid = getpid();
@@ -34,11 +32,13 @@ FileManager::~FileManager() {
}
std::string FileManager::GetEmulatedPath(const char *pathname) {
auto RootFSPath = LDPath();
if (pathname[0] != '/' ||
CTX->Config.RootFSPath.empty())
RootFSPath.empty()) {
return {};
}
return CTX->Config.RootFSPath + pathname;
return RootFSPath + pathname;
}
uint64_t FileManager::Open(const char *pathname, [[maybe_unused]] int flags, [[maybe_unused]] uint32_t mode) {
@@ -95,8 +95,9 @@ uint64_t FileManager::FAccessat(int dirfd, const char *pathname, int mode, int f
uint64_t FileManager::Readlink(const char *pathname, char *buf, size_t bufsiz) {
if (strcmp(pathname, "/proc/self/exe") == 0 || strcmp(pathname, PidSelfPath.c_str()) == 0) {
strncpy(buf, Filename.c_str(), bufsiz);
return std::min(bufsiz, Filename.size());
auto App = Filename();
strncpy(buf, App.c_str(), bufsiz);
return std::min(bufsiz, App.size());
}
auto Path = GetEmulatedPath(pathname);
@@ -122,8 +123,9 @@ uint64_t FileManager::Chmod(const char *pathname, mode_t mode) {
uint64_t FileManager::Readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz) {
if (strcmp(pathname, "/proc/self/exe") == 0) {
strncpy(buf, Filename.c_str(), bufsiz);
return std::min(bufsiz, Filename.size());
auto App = Filename();
strncpy(buf, App.c_str(), bufsiz);
return std::min(bufsiz, App.size());
}
auto Path = GetEmulatedPath(pathname);
@@ -7,13 +7,13 @@
#include <sys/socket.h>
#include <poll.h>
#include "Interface/HLE/EmulatedFiles/EmulatedFiles.h"
#include "Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h"
namespace FEXCore::Context {
struct Context;
}
namespace FEXCore {
namespace FEX::HLE {
class FileManager final {
public:
@@ -40,16 +40,14 @@ public:
std::string *FindFDName(int fd);
void SetFilename(std::string const &File) { Filename = File; }
std::string const & GetFilename() const { return Filename; }
private:
FEXCore::Context::Context *CTX;
FEXCore::EmulatedFile::EmulatedFDManager EmuFD;
FEX::EmulatedFile::EmulatedFDManager EmuFD;
std::unordered_map<int32_t, std::string> FDToNameMap;
std::string Filename;
std::string PidSelfPath;
std::string GetEmulatedPath(const char *pathname);
FEXCore::Config::Value<std::string> Filename{FEXCore::Config::CONFIG_APP_FILENAME, ""};
FEXCore::Config::Value<std::string> LDPath{FEXCore::Config::CONFIG_ROOTFSPATH, ""};
};
}
@@ -1,6 +1,6 @@
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/Core/SignalDelegator.h"
#include <FEXCore/Core/Context.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include "Tests/LinuxSyscalls/SignalDelegator.h"
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Utils/LogManager.h>
@@ -8,10 +8,11 @@
#include <string.h>
#include <linux/futex.h>
#include <bits/types/stack_t.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore {
namespace FEX::HLE {
constexpr static uint32_t SS_AUTODISARM = (1U << 31);
constexpr static uint32_t X86_MINSIGSTKSZ = 0x2000U;
@@ -28,11 +29,11 @@ namespace FEXCore {
};
// Guest signal sa_mask is per thread!
// This is the sa_mask from sigaction which is orr'd to the current signal mask
SignalDelegator::GuestSAMask Guest_sa_mask[SignalDelegator::MAX_SIGNALS]{};
FEXCore::GuestSAMask Guest_sa_mask[SignalDelegator::MAX_SIGNALS]{};
// This is the thread's current signal mask
SignalDelegator::GuestSAMask CurrentSignalMask{};
FEXCore::GuestSAMask CurrentSignalMask{};
// The mask prior to a suspend
SignalDelegator::GuestSAMask PreviousSuspendMask{};
FEXCore::GuestSAMask PreviousSuspendMask{};
uint32_t CurrentSignal{};
uint64_t PendingSignals{};
@@ -58,13 +59,13 @@ namespace FEXCore {
return false;
}
uint64_t SigIsMember(SignalDelegator::GuestSAMask *Set, int Signal) {
uint64_t SigIsMember(FEXCore::GuestSAMask *Set, int Signal) {
// Signal 0 isn't real, so everything is offset by one inside the set
Signal -= 1;
return (Set->Val >> Signal) & 1;
}
uint64_t SetSignal(SignalDelegator::GuestSAMask *Set, int Signal) {
uint64_t SetSignal(FEXCore::GuestSAMask *Set, int Signal) {
// Signal 0 isn't real, so everything is offset by one inside the set
Signal -= 1;
return Set->Val | (1ULL << Signal);
@@ -163,7 +164,7 @@ namespace FEXCore {
Thread->StatusCode = -Signal;
// Doesn't return
Thread->CTX->StopThread(Thread);
FEXCore::Context::StopThread(Thread->CTX, Thread);
std::unexpected();
}
}
@@ -396,7 +397,7 @@ namespace FEXCore {
return true;
}
void SignalDelegator::RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func) {
void SignalDelegator::RegisterHostSignalHandler(int Signal, FEXCore::HostSignalDelegatorFunction Func) {
// Linux signal handlers are per-process rather than per thread
// Multiple threads could be calling in to this
std::lock_guard<std::mutex> lk(HostDelegatorMutex);
@@ -404,7 +405,7 @@ namespace FEXCore {
InstallHostThunk(Signal);
}
void SignalDelegator::RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func) {
void SignalDelegator::RegisterFrontendHostSignalHandler(int Signal, FEXCore::HostSignalDelegatorFunction Func) {
// Linux signal handlers are per-process rather than per thread
// Multiple threads could be calling in to this
std::lock_guard<std::mutex> lk(HostDelegatorMutex);
@@ -412,13 +413,13 @@ namespace FEXCore {
InstallHostThunk(Signal);
}
void SignalDelegator::RegisterHostSignalHandlerForGuest(int Signal, HostSignalDelegatorFunctionForGuest Func) {
void SignalDelegator::RegisterHostSignalHandlerForGuest(int Signal, FEXCore::HostSignalDelegatorFunctionForGuest Func) {
std::lock_guard<std::mutex> lk(HostDelegatorMutex);
HostHandlers[Signal].GuestHandler = Func;
InstallHostThunk(Signal);
}
uint64_t SignalDelegator::RegisterGuestSignalHandler(int Signal, const GuestSigAction *Action, GuestSigAction *OldAction) {
uint64_t SignalDelegator::RegisterGuestSignalHandler(int Signal, const FEXCore::GuestSigAction *Action, FEXCore::GuestSigAction *OldAction) {
std::lock_guard<std::mutex> lk(GuestDelegatorMutex);
// If we have an old signal set then give it back
@@ -448,7 +449,7 @@ namespace FEXCore {
bool UsingAltStack{};
uint64_t AltStackBase = reinterpret_cast<uint64_t>(ThreadData.GuestAltStack.ss_sp);
uint64_t AltStackEnd = AltStackBase + ThreadData.GuestAltStack.ss_size;
uint64_t GuestSP = ThreadData.Thread->State.State.gregs[X86State::REG_RSP];
uint64_t GuestSP = ThreadData.Thread->State.State.gregs[FEXCore::X86State::REG_RSP];
if (!(ThreadData.GuestAltStack.ss_flags & SS_DISABLE) &&
GuestSP >= AltStackBase &&
@@ -582,6 +583,7 @@ namespace FEXCore {
CheckForPendingSignals();
SYSCALL_ERRNO();
return Result == -1 ? -errno : Result;
}
}
@@ -14,27 +14,13 @@ namespace Context {
namespace Core {
struct InternalThreadState;
}
}
class SignalDelegator {
namespace FEX::HLE {
class SignalDelegator final : public FEXCore::SignalDelegator {
public:
struct __attribute__((packed)) GuestSAMask {
uint64_t Val;
};
struct __attribute__((packed)) GuestSigAction {
union {
void (*handler)(int);
void (*sigaction)(int, siginfo_t *, void*);
} sigaction_handler;
uint64_t sa_flags;
void (*restorer)(void);
GuestSAMask sa_mask;
};
// Returns true if the host handled the signal
// Arguments are the same as sigaction handler
using HostSignalDelegatorFunctionForGuest = std::function<bool(FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack)>;
SignalDelegator();
/**
@@ -42,15 +28,15 @@ namespace Core {
*
* Required to know which thread has received the signal when it occurs
*/
static void RegisterTLSState(FEXCore::Core::InternalThreadState *Thread);
static void UninstallTLSState(FEXCore::Core::InternalThreadState *Thread);
void RegisterTLSState(FEXCore::Core::InternalThreadState *Thread) override;
void UninstallTLSState(FEXCore::Core::InternalThreadState *Thread) override;
/**
* @brief Masks a thread from receiving any signals that aren't synchronous
*
* Any helper thread that is generated needs to call this routine to ensure it doesn't receive errant signals to handle
*/
static void MaskThreadSignals();
void MaskThreadSignals() override;
/**
* @brief Reallows a thread to receive signals
@@ -67,20 +53,20 @@ namespace Core {
*
* It's a process level signal handler so one must be careful
*/
void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func);
void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func);
void RegisterHostSignalHandler(int Signal, FEXCore::HostSignalDelegatorFunction Func) override;
void RegisterFrontendHostSignalHandler(int Signal, FEXCore::HostSignalDelegatorFunction Func) 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, HostSignalDelegatorFunctionForGuest Func);
void RegisterHostSignalHandlerForGuest(int Signal, FEXCore::HostSignalDelegatorFunctionForGuest Func) override;
/**
* @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 GuestSigAction *Action, struct GuestSigAction *OldAction);
uint64_t RegisterGuestSignalHandler(int Signal, const FEXCore::GuestSigAction *Action, struct FEXCore::GuestSigAction *OldAction);
uint64_t RegisterGuestSigAltStack(const stack_t *ss, stack_t *old_ss);
@@ -91,13 +77,7 @@ namespace Core {
// Called from the thunk handler to handle the signal
void HandleSignal(int Signal, void *Info, void *UContext);
void SetCurrentSignal(uint32_t Signal);
constexpr static size_t MAX_SIGNALS {64};
// Use the last signal just so we are less likely to ever conflict with something that the guest application is using
// 64 is used internally by Valgrind
constexpr static size_t SIGNAL_FOR_PAUSE {63};
void SetCurrentSignal(uint32_t Signal) override;
private:
enum DefaultBehaviour {
@@ -112,10 +92,10 @@ namespace Core {
std::atomic<bool> Installed{};
struct sigaction HostAction{};
struct sigaction OldAction{};
HostSignalDelegatorFunction Handler{};
HostSignalDelegatorFunction FrontendHandler{};
HostSignalDelegatorFunctionForGuest GuestHandler{};
GuestSigAction GuestAction{};
FEXCore::HostSignalDelegatorFunction Handler{};
FEXCore::HostSignalDelegatorFunction FrontendHandler{};
FEXCore::HostSignalDelegatorFunctionForGuest GuestHandler{};
FEXCore::GuestSigAction GuestAction{};
DefaultBehaviour DefaultBehaviour {DEFAULT_TERM};
};
@@ -1,11 +1,9 @@
#include <FEXCore/Utils/LogManager.h>
#include "Common/MathUtils.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Core/X86Enums.h>
#include <fcntl.h>
@@ -22,11 +20,11 @@
#include <sys/syscall.h>
#include <unistd.h>
constexpr uint64_t PAGE_SIZE = 4096;
#define BRK_SIZE 0x1000'0000
namespace FEXCore {
namespace FEX::HLE {
SyscallHandler *_SyscallHandler{};
uint64_t SyscallHandler::HandleBRK(FEXCore::Core::InternalThreadState *Thread, void *Addr) {
std::lock_guard<std::mutex> lk(MMapMutex);
uint64_t Result;
@@ -65,17 +63,18 @@ void SyscallHandler::DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thr
DataSpace = (uint64_t)mmap(nullptr, BRK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
SyscallHandler::SyscallHandler(FEXCore::Context::Context *ctx)
SyscallHandler::SyscallHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation)
: FM {ctx}
, CTX {ctx} {
, SignalDelegation {_SignalDelegation} {
FEX::HLE::_SyscallHandler = this;
}
SyscallHandler *CreateHandler(Context::OperatingMode Mode, FEXCore::Context::Context *ctx) {
if (Mode == Context::MODE_64BIT) {
return FEXCore::HLE::x64::CreateHandler(ctx);
FEX::HLE::SyscallHandler *CreateHandler(FEXCore::Context::OperatingMode Mode, FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation) {
if (Mode == FEXCore::Context::MODE_64BIT) {
return FEX::HLE::x64::CreateHandler(ctx, _SignalDelegation);
}
else {
return FEXCore::HLE::x32::CreateHandler(ctx);
return FEX::HLE::x32::CreateHandler(ctx, _SignalDelegation);
}
}
@@ -1,9 +1,9 @@
#pragma once
#include "Interface/HLE/FileManagement.h"
#include "Tests/LinuxSyscalls/FileManagement.h"
#include "Tests/LinuxSyscalls/SignalDelegator.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/Context.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <atomic>
@@ -11,25 +11,43 @@
#include <mutex>
#include <unordered_map>
#ifndef FEXCORE_VERSION
#define FEXCORE_VERSION "1"
#endif
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore {
namespace FEX::HLE {
void RegisterEpoll();
void RegisterFD();
void RegisterFS();
void RegisterInfo();
void RegisterIO();
void RegisterKey();
void RegisterMemory();
void RegisterMsg();
void RegisterNuma();
void RegisterSched();
void RegisterSemaphore();
void RegisterSHM();
void RegisterSignals();
void RegisterSocket();
void RegisterThread();
void RegisterTime();
void RegisterTimer();
void RegisterNotImplemented();
void RegisterStubs();
// #define DEBUG_STRACE
class SyscallHandler {
class SyscallHandler : public FEXCore::HLE::SyscallHandler {
public:
SyscallHandler(FEXCore::Context::Context *ctx);
SyscallHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation);
virtual ~SyscallHandler() = default;
virtual uint64_t HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) = 0;
void DefaultProgramBreak(FEXCore::Core::InternalThreadState *Thread);
void SetFilename(std::string const &File) { FM.SetFilename(File); }
std::string const & GetFilename() const { return FM.GetFilename(); }
using SyscallPtrArg0 = uint64_t(*)(FEXCore::Core::InternalThreadState *Thread);
using SyscallPtrArg1 = uint64_t(*)(FEXCore::Core::InternalThreadState *Thread, uint64_t);
using SyscallPtrArg2 = uint64_t(*)(FEXCore::Core::InternalThreadState *Thread, uint64_t, uint64_t);
@@ -59,9 +77,16 @@ public:
return &Definitions.at(Syscall);
}
FEXCore::HLE::SyscallABI GetSyscallABI(uint64_t Syscall) override {
auto &Def = Definitions.at(Syscall);
return {Def.NumArgs, true};
}
uint64_t HandleBRK(FEXCore::Core::InternalThreadState *Thread, void *Addr);
FileManager FM;
FEX::HLE::FileManager FM;
FEXCore::CodeLoader *GetCodeLoader() const { return LocalLoader; }
FEX::HLE::SignalDelegator *GetSignalDelegator() { return SignalDelegation; }
#ifdef DEBUG_STRACE
virtual void Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret) = 0;
@@ -69,6 +94,9 @@ public:
FEXCore::Config::Value<bool> IsInterpreter{FEXCore::Config::CONFIG_IS_INTERPRETER, 0};
FEXCore::Config::Value<bool> IsInterpreterInstalled{FEXCore::Config::CONFIG_INTERPRETER_INSTALLED, 0};
FEXCore::Config::Value<std::string> Filename{FEXCore::Config::CONFIG_APP_FILENAME, ""};
FEXCore::Config::Value<uint64_t> ThreadsConfig{FEXCore::Config::CONFIG_EMULATED_CPU_CORES, 1};
FEXCore::Config::Value<bool> Is64BitMode{FEXCore::Config::CONFIG_IS64BIT_MODE, 0};
protected:
std::vector<SyscallFunctionDefinition> Definitions;
@@ -80,20 +108,20 @@ protected:
private:
FEXCore::Context::Context *CTX;
FEX::HLE::SignalDelegator *SignalDelegation;
std::mutex FutexMutex;
std::mutex SyscallMutex;
FEXCore::CodeLoader *LocalLoader{};
};
SyscallHandler *CreateHandler(Context::OperatingMode Mode, FEXCore::Context::Context *ctx);
FEX::HLE::SyscallHandler *CreateHandler(FEXCore::Context::OperatingMode Mode, FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation);
uint64_t HandleSyscall(SyscallHandler *Handler, FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args);
#define SYSCALL_ERRNO() do { if (Result == -1) return -errno; return Result; } while(0)
#define SYSCALL_ERRNO_NULL() do { if (Result == 0) return -errno; return Result; } while(0)
}
namespace FEXCore::HLE {
extern FEX::HLE::SyscallHandler *_SyscallHandler;
#ifdef DEBUG_STRACE
//////
@@ -105,7 +133,7 @@ struct ArgToFmtString {
// fail on unknown types
};
#define ARG_TO_STR(tpy, str) template<> struct FEXCore::HLE::ArgToFmtString<tpy> { inline static const std::string Format = str; };
#define ARG_TO_STR(tpy, str) template<> struct FEX::HLE::ArgToFmtString<tpy> { inline static const std::string Format = str; };
// Base types
ARG_TO_STR(int, "%d")
@@ -177,16 +205,16 @@ struct FunctionToLambda<R(*)(Args...) noexcept> {
// Creates a variadic template lambda from a global function (via FunctionToLambda), then forwards the arguments to the specified function
// also handles errno
#define SYSCALL_FORWARD_ERRNO(function) \
FEXCore::HLE::FunctionToLambda<decltype(&::function)>::ReturnFunctionPointer([](FEXCore::Core::InternalThreadState *Thread, auto... Args) { \
FEXCore::HLE::FunctionToLambda<decltype(&::function)>::RType Result = ::function(Args...); \
do { if (Result == -1) return (FEXCore::HLE::FunctionToLambda<decltype(&::function)>::RType)-errno; return Result; } while(0); \
FEX::HLE::FunctionToLambda<decltype(&::function)>::ReturnFunctionPointer([](FEXCore::Core::InternalThreadState *Thread, auto... Args) { \
FEX::HLE::FunctionToLambda<decltype(&::function)>::RType Result = ::function(Args...); \
do { if (Result == -1) return (FEX::HLE::FunctionToLambda<decltype(&::function)>::RType)-errno; return Result; } while(0); \
})
// Helpers to register a syscall implementation
// Creates a syscall forward from a glibc wrapper, and registers it
#define REGISTER_SYSCALL_FORWARD_ERRNO(function) do { \
FEXCore::HLE::x64::RegisterSyscall(x64::SYSCALL_x64_##function, #function, SYSCALL_FORWARD_ERRNO(function)); \
FEXCore::HLE::x32::RegisterSyscall(x32::SYSCALL_x86_##function, #function, SYSCALL_FORWARD_ERRNO(function)); \
FEX::HLE::x64::RegisterSyscall(FEX::HLE::x64::SYSCALL_x64_##function, #function, SYSCALL_FORWARD_ERRNO(function)); \
FEX::HLE::x32::RegisterSyscall(FEX::HLE::x32::SYSCALL_x86_##function, #function, SYSCALL_FORWARD_ERRNO(function)); \
} while(0)
// Registers syscall for both 32bit and 64bit
@@ -194,7 +222,7 @@ struct FunctionToLambda<R(*)(Args...) noexcept> {
struct impl_##name { \
impl_##name() \
{ \
FEXCore::HLE::x64::RegisterSyscall(x64::SYSCALL_x64_##name, #name, lambda); \
FEXCore::HLE::x32::RegisterSyscall(x32::SYSCALL_x86_##name, #name, lambda); \
FEX::HLE::x64::RegisterSyscall(FEX::HLE::x64::SYSCALL_x64_##name, #name, lambda); \
FEX::HLE::x32::RegisterSyscall(FEX::HLE::x32::SYSCALL_x86_##name, #name, lambda); \
} } impl_##name
@@ -1,16 +1,11 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stdint.h>
#include <sys/epoll.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterEpoll() {
REGISTER_SYSCALL_IMPL(epoll_create, [](FEXCore::Core::InternalThreadState *Thread, int size) -> uint64_t {
@@ -43,6 +38,4 @@ namespace FEXCore::HLE {
SYSCALL_ERRNO();
});
}
}
@@ -1,7 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <fcntl.h>
#include <stdint.h>
@@ -18,7 +17,7 @@
#include <sys/eventfd.h>
#include <sys/sendfile.h>
namespace FEXCore::HLE {
namespace FEX::HLE {
static int RemapFlags(int flags) {
#ifdef _M_X86_64
// Nothing to change here
@@ -50,12 +49,12 @@ namespace FEXCore::HLE {
REGISTER_SYSCALL_IMPL(open, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, int flags, uint32_t mode) -> uint64_t {
flags = RemapFlags(flags);
uint64_t Result = Thread->CTX->SyscallHandler->FM.Open(pathname, flags, mode);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Open(pathname, flags, mode);
SYSCALL_ERRNO();
});
REGISTER_SYSCALL_IMPL(close, [](FEXCore::Core::InternalThreadState *Thread, int fd) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Close(fd);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Close(fd);
SYSCALL_ERRNO();
});
@@ -93,7 +92,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(access, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, int mode) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Access(pathname, mode);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Access(pathname, mode);
SYSCALL_ERRNO();
});
@@ -180,7 +179,7 @@ namespace FEXCore::HLE {
REGISTER_SYSCALL_IMPL(openat, [](FEXCore::Core::InternalThreadState *Thread, int dirfs, const char *pathname, int flags, uint32_t mode) -> uint64_t {
flags = RemapFlags(flags);
uint64_t Result = Thread->CTX->SyscallHandler->FM.Openat(dirfs, pathname, flags, mode);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Openat(dirfs, pathname, flags, mode);
SYSCALL_ERRNO();
});
@@ -220,7 +219,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(readlinkat, [](FEXCore::Core::InternalThreadState *Thread, int dirfd, const char *pathname, char *buf, size_t bufsiz) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Readlinkat(dirfd, pathname, buf, bufsiz);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Readlinkat(dirfd, pathname, buf, bufsiz);
SYSCALL_ERRNO();
});
@@ -230,7 +229,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(faccessat, [](FEXCore::Core::InternalThreadState *Thread, int dirfd, const char *pathname, int mode, int flags) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.FAccessat(dirfd, pathname, mode, flags);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.FAccessat(dirfd, pathname, mode, flags);
SYSCALL_ERRNO();
});
@@ -292,7 +291,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(statx, [](FEXCore::Core::InternalThreadState *Thread, int dirfd, const char *pathname, int flags, uint32_t mask, struct statx *statxbuf) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Statx(dirfd, pathname, flags, mask, statxbuf);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Statx(dirfd, pathname, flags, mask, statxbuf);
SYSCALL_ERRNO();
});
@@ -1,7 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
@@ -15,12 +14,7 @@
#include <fcntl.h>
#include <sys/xattr.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterFS() {
REGISTER_SYSCALL_IMPL(getcwd, [](FEXCore::Core::InternalThreadState *Thread, char *buf, size_t size) -> uint64_t {
uint64_t Result = syscall(SYS_getcwd, buf, size);
@@ -68,7 +62,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(readlink, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, char *buf, size_t bufsiz) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Readlink(pathname, buf, bufsiz);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Readlink(pathname, buf, bufsiz);
SYSCALL_ERRNO();
});
@@ -83,7 +77,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(mknod, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, mode_t mode, dev_t dev) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Mknod(pathname, mode, dev);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Mknod(pathname, mode, dev);
SYSCALL_ERRNO();
});
@@ -111,7 +105,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(statfs, [](FEXCore::Core::InternalThreadState *Thread, const char *path, struct statfs *buf) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->FM.Statfs(path, buf);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Statfs(path, buf);
SYSCALL_ERRNO();
});
@@ -1,17 +1,12 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <linux/aio_abi.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterIO() {
REGISTER_SYSCALL_IMPL(iopl, [](FEXCore::Core::InternalThreadState *Thread, int level) -> uint64_t {
// Just claim we don't have permission
@@ -1,7 +1,6 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <cstring>
#include <linux/kcmp.h>
@@ -18,12 +17,7 @@
#include <sys/klog.h>
#include <unistd.h>
#ifndef FEXCORE_VERSION
#define FEXCORE_VERSION "1"
#endif
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterInfo() {
REGISTER_SYSCALL_IMPL(getrlimit, [](FEXCore::Core::InternalThreadState *Thread, int resource, struct rlimit *rlim) -> uint64_t {
uint64_t Result = ::getrlimit(resource, rlim);
@@ -68,7 +62,7 @@ namespace FEXCore::HLE {
if (Result == 0) {
if (cpu) {
// Ensure we don't return a number over our number of emulated cores
*cpu = LocalCPU % Thread->CTX->Config.EmulatedCPUCores;
*cpu = LocalCPU % FEX::HLE::_SyscallHandler->ThreadsConfig();
}
if (node) {
@@ -1,16 +1,12 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterKey() {
REGISTER_SYSCALL_IMPL(add_key, [](FEXCore::Core::InternalThreadState *Thread, const char *type, const char *description, const void *payload, size_t plen, int32_t /*key_serial_t*/ keyring) -> uint64_t {
uint64_t Result = syscall(SYS_add_key, type, description, payload, plen, keyring);
@@ -1,9 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
@@ -12,15 +9,10 @@
#include <unistd.h>
#include <numaif.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterMemory() {
REGISTER_SYSCALL_IMPL(brk, [](FEXCore::Core::InternalThreadState *Thread, void *addr) -> uint64_t {
uint64_t Result = Thread->CTX->SyscallHandler->HandleBRK(Thread, addr);
uint64_t Result = FEX::HLE::_SyscallHandler->HandleBRK(Thread, addr);
SYSCALL_ERRNO();
});
@@ -1,6 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <mqueue.h>
#include <sys/types.h>
@@ -9,11 +9,7 @@
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterMsg() {
REGISTER_SYSCALL_IMPL(msgget, [](FEXCore::Core::InternalThreadState *Thread, key_t key, int msgflg) -> uint64_t {
uint64_t Result = ::msgget(key, msgflg);
@@ -1,15 +1,11 @@
#include <FEXCore/Utils/LogManager.h>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stdint.h>
#include <sys/epoll.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
#define REGISTER_SYSCALL_NOT_IMPL(name) REGISTER_SYSCALL_IMPL(name, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t { \
LogMan::Msg::D("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
@@ -23,8 +19,7 @@ struct InternalThreadState;
return -EACCES; \
});
namespace FEXCore::HLE {
namespace FEX::HLE {
// these are removed/not implemented in the linux kernel we present
void RegisterNotImplemented() {
@@ -1,19 +1,12 @@
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/shm.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterSHM() {
REGISTER_SYSCALL_IMPL(shmget, [](FEXCore::Core::InternalThreadState *Thread, key_t key, size_t size, int shmflg) -> uint64_t {
uint64_t Result = shmget(key, size, shmflg);
@@ -1,7 +1,6 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stdint.h>
#include <sched.h>
@@ -10,12 +9,7 @@
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterSched() {
REGISTER_SYSCALL_IMPL(sched_yield, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t {
@@ -68,7 +62,7 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(sched_getaffinity, [](FEXCore::Core::InternalThreadState *Thread, pid_t pid, size_t cpusetsize, unsigned char *mask) -> uint64_t {
uint64_t Cores = Thread->CTX->Config.EmulatedCPUCores;
uint64_t Cores = FEX::HLE::_SyscallHandler->ThreadsConfig();
uint64_t Bytes = ((Cores+7) / 8);
// If we don't have at least one byte in the resulting structure
// then we need to return -EINVAL
@@ -1,19 +1,12 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterSemaphore() {
REGISTER_SYSCALL_IMPL(semget, [](FEXCore::Core::InternalThreadState *Thread, key_t key, int nsems, int semflg) -> uint64_t {
uint64_t Result = ::semget(key, nsems, semflg);
@@ -1,32 +1,35 @@
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls/Thread.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Core/SignalDelegator.h>
#include <signal.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::HLE {
namespace SignalDelegator {
struct GuestSigAction;
}
namespace FEX::HLE {
void RegisterSignals() {
REGISTER_SYSCALL_IMPL(rt_sigaction, [](FEXCore::Core::InternalThreadState *Thread, int signum, const SignalDelegator::GuestSigAction *act, SignalDelegator::GuestSigAction *oldact) -> uint64_t {
return Thread->CTX->SignalDelegation.RegisterGuestSignalHandler(signum, act, oldact);
REGISTER_SYSCALL_IMPL(rt_sigaction, [](FEXCore::Core::InternalThreadState *Thread, int signum, const FEXCore::GuestSigAction *act, FEXCore::GuestSigAction *oldact) -> uint64_t {
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->RegisterGuestSignalHandler(signum, act, oldact);
});
REGISTER_SYSCALL_IMPL(rt_sigprocmask, [](FEXCore::Core::InternalThreadState *Thread, int how, const uint64_t *set, uint64_t *oldset) -> uint64_t {
return Thread->CTX->SignalDelegation.GuestSigProcMask(how, set, oldset);
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigProcMask(how, set, oldset);
});
REGISTER_SYSCALL_IMPL(rt_sigpending, [](FEXCore::Core::InternalThreadState *Thread, uint64_t *set, size_t sigsetsize) -> uint64_t {
return Thread->CTX->SignalDelegation.GuestSigPending(set, sigsetsize);
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigPending(set, sigsetsize);
});
REGISTER_SYSCALL_IMPL(rt_sigsuspend, [](FEXCore::Core::InternalThreadState *Thread, uint64_t *unewset, size_t sigsetsize) -> uint64_t {
return Thread->CTX->SignalDelegation.GuestSigSuspend(unewset, sigsetsize);
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigSuspend(unewset, sigsetsize);
});
REGISTER_SYSCALL_IMPL(userfaultfd, [](FEXCore::Core::InternalThreadState *Thread, int flags) -> uint64_t {
@@ -1,17 +1,12 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/socket.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterSocket() {
REGISTER_SYSCALL_IMPL(socket, [](FEXCore::Core::InternalThreadState *Thread, int domain, int type, int protocol) -> uint64_t {
@@ -1,8 +1,8 @@
#include <FEXCore/Utils/LogManager.h>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <sys/time.h>
@@ -21,14 +21,9 @@
#include <linux/aio_abi.h>
#include <mqueue.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
#define SYSCALL_STUB(name) do { ERROR_AND_DIE("Syscall: " #name " stub!"); return -ENOSYS; } while(0)
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterStubs() {
REGISTER_SYSCALL_IMPL(rt_sigreturn, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t {
@@ -1,13 +1,13 @@
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/Syscalls/Thread.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x64/Thread.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/HLE/x32/Thread.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls/Thread.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Thread.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Thread.h"
#include <FEXCore/Core/Context.h>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <grp.h>
#include <limits.h>
@@ -26,12 +26,7 @@
ARG_TO_STR(idtype_t, "%u")
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
FEXCore::Core::InternalThreadState *CreateNewThread(FEXCore::Core::InternalThreadState *Thread, uint32_t flags, void *stack, pid_t *parent_tid, pid_t *child_tid, void *tls) {
FEXCore::Core::CPUState NewThreadState{};
// Clone copies the parent thread's state
@@ -42,12 +37,10 @@ namespace FEXCore::HLE {
NewThreadState.gregs[FEXCore::X86State::REG_RBP] = 0;
NewThreadState.gregs[FEXCore::X86State::REG_RSP] = reinterpret_cast<uint64_t>(stack);
bool Is64Bit = Thread->CTX->Config.Is64BitMode;
auto NewThread = FEXCore::Context::CreateThread(Thread->CTX, &NewThreadState, reinterpret_cast<uint64_t>(parent_tid));
FEXCore::Context::InitializeThread(Thread->CTX, NewThread);
auto NewThread = Thread->CTX->CreateThread(&NewThreadState, reinterpret_cast<uint64_t>(parent_tid));
Thread->CTX->InitializeThread(NewThread);
if (Is64Bit) {
if (FEX::HLE::_SyscallHandler->Is64BitMode()) {
if (flags & CLONE_SETTLS) {
x64::SetThreadArea(NewThread, tls);
}
@@ -89,8 +82,6 @@ namespace FEXCore::HLE {
pid_t Result = fork();
if (Result == 0) {
bool Is64Bit = Thread->CTX->Config.Is64BitMode;
// Child
// update the internal TID
Thread->State.ThreadManager.TID = ::gettid();
@@ -98,14 +89,7 @@ namespace FEXCore::HLE {
Thread->State.ThreadManager.clear_child_tid = nullptr;
// Clear all the other threads that are being tracked
for (auto &DeadThread : Thread->CTX->Threads) {
if (DeadThread == Thread) {
continue;
}
// Setting running to false ensures that when they shutdown we won't send signals to kill them
DeadThread->State.RunningEvents.Running = false;
}
FEXCore::Context::DeleteForkedThreads(Thread->CTX, Thread);
// only a single thread running so no need to remove anything from the thread array
@@ -113,14 +97,14 @@ namespace FEXCore::HLE {
if (stack != nullptr) {
// use specified stack
LogMan::Msg::D("@@@@@@@ Fork uses custom stack");
Thread->State.State.gregs[X86State::REG_RSP] = reinterpret_cast<uint64_t>(stack);
Thread->State.State.gregs[FEXCore::X86State::REG_RSP] = reinterpret_cast<uint64_t>(stack);
} else {
// In the case of fork and nullptr stack then the child uses the same stack space as the parent
// Same virtual address, different addressspace
LogMan::Msg::D("@@@@@@@ Fork uses parent stack");
}
if (Is64Bit) {
if (FEX::HLE::_SyscallHandler->Is64BitMode()) {
if (flags & CLONE_SETTLS) {
x64::SetThreadArea(Thread, tls);
}
@@ -165,21 +149,10 @@ namespace FEXCore::HLE {
});
REGISTER_SYSCALL_IMPL(fork, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t {
if (Thread->CTX->GetThreadCount() != 1) {
LogMan::Msg::E("fork: Fork only supported on single threaded applications. Allowing");
} else {
LogMan::Msg::D("fork: Forking process");
}
return ForkGuest(Thread, 0, 0, 0, 0, 0);
});
REGISTER_SYSCALL_IMPL(vfork, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t {
if (Thread->CTX->GetThreadCount() != 1) {
LogMan::Msg::E("vfork: Fork only supported on single threaded applications. Allowing");
} else {
LogMan::Msg::D("vfork: WARNING: Forking process using fork semantics");
}
return ForkGuest(Thread, 0, 0, 0, 0, 0);
});
@@ -197,7 +170,7 @@ namespace FEXCore::HLE {
}
Thread->StatusCode = status;
Thread->CTX->StopThread(Thread);
FEXCore::Context::StopThread(Thread->CTX, Thread);
return 0;
});
@@ -359,7 +332,7 @@ namespace FEXCore::HLE {
REGISTER_SYSCALL_IMPL(exit_group, [](FEXCore::Core::InternalThreadState *Thread, int status) -> uint64_t {
Thread->StatusCode = status;
Thread->CTX->Stop(false /* Ignore current thread */);
FEXCore::Context::Stop(Thread->CTX);
// This will never be reached
std::unexpected();
});
@@ -7,7 +7,7 @@ struct InternalThreadState;
struct CPUState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
FEXCore::Core::InternalThreadState *CreateNewThread(FEXCore::Core::InternalThreadState *Thread, uint32_t flags, void *stack, pid_t *parent_tid, pid_t *child_tid, void *tls);
uint64_t ForkGuest(FEXCore::Core::InternalThreadState *Thread, uint32_t flags, void *stack, pid_t *parent_tid, pid_t *child_tid, void *tls);
}
@@ -1,6 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
@@ -11,11 +11,7 @@
#include <unistd.h>
#include <utime.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterTime() {
REGISTER_SYSCALL_IMPL(pause, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t {
uint64_t Result = ::pause();
@@ -1,6 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
@@ -9,12 +9,7 @@
#include <time.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE {
namespace FEX::HLE {
void RegisterTimer() {
REGISTER_SYSCALL_IMPL(alarm, [](FEXCore::Core::InternalThreadState *Thread, unsigned int seconds) -> uint64_t {
@@ -1,11 +1,13 @@
#include "Common/MathUtils.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/Utils/LogManager.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <sys/file.h>
#include <sys/eventfd.h>
@@ -18,7 +20,7 @@
#include <sys/vfs.h>
#include <unistd.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
using fd_set32 = uint32_t;
void RegisterFD() {
@@ -116,7 +118,7 @@ namespace FEXCore::HLE::x32 {
REGISTER_SYSCALL_IMPL_X32(stat, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, stat32 *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Stat(pathname, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Stat(pathname, &host_stat);
if (Result != -1) {
*buf = host_stat;
}
@@ -134,7 +136,7 @@ namespace FEXCore::HLE::x32 {
REGISTER_SYSCALL_IMPL_X32(lstat, [](FEXCore::Core::InternalThreadState *Thread, const char *path, stat32 *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Lstat(path, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Lstat(path, &host_stat);
if (Result != -1) {
*buf = host_stat;
}
@@ -143,7 +145,7 @@ namespace FEXCore::HLE::x32 {
REGISTER_SYSCALL_IMPL_X32(stat64, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, stat64_32 *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Stat(pathname, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Stat(pathname, &host_stat);
if (Result != -1) {
*buf = host_stat;
}
@@ -152,7 +154,7 @@ namespace FEXCore::HLE::x32 {
REGISTER_SYSCALL_IMPL_X32(lstat64, [](FEXCore::Core::InternalThreadState *Thread, const char *path, stat64_32 *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Lstat(path, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Lstat(path, &host_stat);
if (Result != -1) {
*buf = host_stat;
@@ -184,7 +186,7 @@ namespace FEXCore::HLE::x32 {
LogMan::Throw::A(sz == sizeof(struct statfs64_32), "This needs to match");
struct statfs host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Statfs(path, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Statfs(path, &host_stat);
if (Result != -1) {
*buf = host_stat;
}
@@ -1,14 +1,10 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/HLE/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <sys/mount.h>
#include <unistd.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
void RegisterFS() {
REGISTER_SYSCALL_IMPL_X32(umount, [](FEXCore::Core::InternalThreadState *Thread, const char *target) -> uint64_t {
uint64_t Result = ::umount(target);
@@ -24,7 +20,7 @@ namespace FEXCore::HLE::x32 {
});
REGISTER_SYSCALL_IMPL_X32(sigprocmask, [](FEXCore::Core::InternalThreadState *Thread, int how, const uint64_t *set, uint64_t *oldset, size_t sigsetsize) -> uint64_t {
return Thread->CTX->SignalDelegation.GuestSigProcMask(how, set, oldset);
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->GuestSigProcMask(how, set, oldset);
});
}
}
@@ -1,22 +1,11 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <sys/resource.h>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
#ifndef FEXCORE_VERSION
#define FEXCORE_VERSION "1"
#endif
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
struct rlimit32 {
uint32_t rlim_cur;
uint32_t rlim_max;
@@ -1,8 +1,5 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include "Common/MathUtils.h"
@@ -11,7 +8,7 @@
#include <stdint.h>
#include <sys/mman.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
class MemAllocator {
private:
static constexpr uint64_t PAGE_SHIFT = 12;
@@ -1,8 +1,8 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
#define REGISTER_SYSCALL_NOT_IMPL_X32(name) REGISTER_SYSCALL_IMPL_X32(name, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t { \
LogMan::Msg::D("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
@@ -1,6 +1,5 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stdint.h>
#include <sched.h>
@@ -9,7 +8,7 @@
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
void RegisterSched() {
REGISTER_SYSCALL_IMPL_X32(sched_rr_get_interval, [](FEXCore::Core::InternalThreadState *Thread, pid_t pid, struct timespec32 *tp) -> uint64_t {
struct timespec tp64{};
@@ -1,6 +1,7 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Utils/LogManager.h>
#include <sys/ipc.h>
#include <sys/msg.h>
@@ -8,7 +9,7 @@
#include <sys/shm.h>
#include <sys/types.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
// Define the IPC ops
enum IPCOp {
OP_SEMOP = 1,
@@ -1,8 +1,5 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Utils/LogManager.h>
@@ -11,7 +8,7 @@
#include <stdint.h>
#include <sys/socket.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
enum SockOp {
OP_SOCKET = 1,
OP_BIND = 2,
@@ -1,38 +1,14 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/HLE/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <fcntl.h>
#include <map>
#include <sys/stat.h>
namespace FEXCore::HLE {
void RegisterEpoll();
void RegisterFD();
void RegisterFS();
void RegisterInfo();
void RegisterIO();
void RegisterKey();
void RegisterMemory();
void RegisterMsg();
void RegisterNuma();
void RegisterSched();
void RegisterSemaphore();
void RegisterSHM();
void RegisterSignals();
void RegisterSocket();
void RegisterThread();
void RegisterTime();
void RegisterTimer();
void RegisterNotImplemented();
void RegisterStubs();
}
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
void RegisterFD();
void RegisterFS();
void RegisterInfo();
@@ -82,9 +58,9 @@ namespace FEXCore::HLE::x32 {
});
}
class x32SyscallHandler final : public FEXCore::SyscallHandler {
class x32SyscallHandler final : public FEX::HLE::SyscallHandler {
public:
x32SyscallHandler(FEXCore::Context::Context *ctx);
x32SyscallHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation);
// In the case that the syscall doesn't hit the optimized path then we still need to go here
uint64_t HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) override;
@@ -119,13 +95,14 @@ void x32SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Re
return -ENOSYS;
}
x32SyscallHandler::x32SyscallHandler(FEXCore::Context::Context *ctx)
: SyscallHandler {ctx} {
x32SyscallHandler::x32SyscallHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation)
: SyscallHandler {ctx, _SignalDelegation} {
OSABI = FEXCore::HLE::SyscallOSABI::OS_LINUX32;
RegisterSyscallHandlers();
}
void x32SyscallHandler::RegisterSyscallHandlers() {
Definitions.resize(FEXCore::HLE::x32::SYSCALL_MAX);
Definitions.resize(FEX::HLE::x32::SYSCALL_MAX);
auto cvt = [](auto in) {
union {
decltype(in) val;
@@ -141,36 +118,36 @@ void x32SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Re
Def.Ptr = cvt(&Unimplemented);
}
FEXCore::HLE::RegisterEpoll();
FEXCore::HLE::RegisterFD();
FEXCore::HLE::RegisterFS();
FEXCore::HLE::RegisterInfo();
FEXCore::HLE::RegisterIO();
FEXCore::HLE::RegisterKey();
FEXCore::HLE::RegisterMemory();
FEXCore::HLE::RegisterMsg();
FEXCore::HLE::RegisterSched();
FEXCore::HLE::RegisterSemaphore();
FEXCore::HLE::RegisterSHM();
FEXCore::HLE::RegisterSignals();
FEXCore::HLE::RegisterSocket();
FEXCore::HLE::RegisterThread();
FEXCore::HLE::RegisterTime();
FEXCore::HLE::RegisterTimer();
FEXCore::HLE::RegisterNotImplemented();
FEXCore::HLE::RegisterStubs();
FEX::HLE::RegisterEpoll();
FEX::HLE::RegisterFD();
FEX::HLE::RegisterFS();
FEX::HLE::RegisterInfo();
FEX::HLE::RegisterIO();
FEX::HLE::RegisterKey();
FEX::HLE::RegisterMemory();
FEX::HLE::RegisterMsg();
FEX::HLE::RegisterSched();
FEX::HLE::RegisterSemaphore();
FEX::HLE::RegisterSHM();
FEX::HLE::RegisterSignals();
FEX::HLE::RegisterSocket();
FEX::HLE::RegisterThread();
FEX::HLE::RegisterTime();
FEX::HLE::RegisterTimer();
FEX::HLE::RegisterNotImplemented();
FEX::HLE::RegisterStubs();
// 32bit specific
FEXCore::HLE::x32::RegisterFD();
FEXCore::HLE::x32::RegisterFS();
FEXCore::HLE::x32::RegisterInfo();
FEXCore::HLE::x32::RegisterMemory();
FEXCore::HLE::x32::RegisterNotImplemented();
FEXCore::HLE::x32::RegisterSched();
FEXCore::HLE::x32::RegisterSemaphore();
FEXCore::HLE::x32::RegisterSocket();
FEXCore::HLE::x32::RegisterThread();
FEXCore::HLE::x32::RegisterTime();
FEX::HLE::x32::RegisterFD();
FEX::HLE::x32::RegisterFS();
FEX::HLE::x32::RegisterInfo();
FEX::HLE::x32::RegisterMemory();
FEX::HLE::x32::RegisterNotImplemented();
FEX::HLE::x32::RegisterSched();
FEX::HLE::x32::RegisterSemaphore();
FEX::HLE::x32::RegisterSocket();
FEX::HLE::x32::RegisterThread();
FEX::HLE::x32::RegisterTime();
// Set all the new definitions
for (auto &Syscall : syscalls_x32) {
@@ -211,8 +188,8 @@ void x32SyscallHandler::Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Re
return -1;
}
FEXCore::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx) {
return new x32SyscallHandler(ctx);
FEX::HLE::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation) {
return new x32SyscallHandler(ctx, _SignalDelegation);
}
}
@@ -1,27 +1,27 @@
#pragma once
#include "Interface/HLE/FileManagement.h"
#include "Tests/LinuxSyscalls/FileManagement.h"
#include <FEXCore/HLE/SyscallHandler.h>
#include "Interface/HLE/x32/Types.h"
#include "Tests/LinuxSyscalls/x32/Types.h"
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <unordered_map>
namespace FEX::HLE {
class SignalDelegator;
class SyscallHandler;
}
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore {
class SyscallHandler;
}
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
#include "SyscallsEnum.h"
FEXCore::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx);
FEX::HLE::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation);
void RegisterSyscallInternal(int SyscallNumber,
#ifdef DEBUG_STRACE
const std::string& TraceFormatString,
@@ -42,7 +42,7 @@ bool RegisterSyscall(int SyscallNumber, const char *Name, R(*fn)(FEXCore::Core::
#ifdef DEBUG_STRACE
auto TraceFormatString = std::string(Name) + "(" + CollectArgsFmtString<Args...>() + ") = %ld";
#endif
FEXCore::HLE::x32::RegisterSyscallInternal(SyscallNumber,
FEX::HLE::x32::RegisterSyscallInternal(SyscallNumber,
#ifdef DEBUG_STRACE
TraceFormatString,
#endif
@@ -80,5 +80,5 @@ bool RegisterSyscall(int num, const char *name, F f){
struct impl_##name { \
impl_##name() \
{ \
FEXCore::HLE::x32::RegisterSyscall(x32::SYSCALL_x86_##name, #name, lambda); \
FEX::HLE::x32::RegisterSyscall(x32::SYSCALL_x86_##name, #name, lambda); \
} } impl_##name
@@ -1,10 +1,10 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/Syscalls/Thread.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Interface/HLE/x32/Thread.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls/Thread.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Thread.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include <FEXCore/Core/Context.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Utils/ELFLoader.h>
@@ -16,9 +16,9 @@
#include <unistd.h>
#include <filesystem>
ARG_TO_STR(FEXCore::HLE::x32::compat_ptr<FEXCore::HLE::x32::stack_t32>, "%x")
ARG_TO_STR(FEX::HLE::x32::compat_ptr<FEX::HLE::x32::stack_t32>, "%x")
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
uint64_t SetThreadArea(FEXCore::Core::InternalThreadState *Thread, void *tls) {
struct x32::user_desc* u_info = reinterpret_cast<struct x32::user_desc*>(tls);
@@ -97,25 +97,20 @@ namespace FEXCore::HLE::x32 {
}
// CLONE_PARENT is ignored (Implied by CLONE_THREAD)
if (Thread->CTX->GetThreadCount() != 1) {
LogMan::Msg::E("clone: Fork only supported on single threaded applications. Allowing");
}
return ForkGuest(Thread, flags, stack, parent_tid, child_tid, tls);
return FEX::HLE::ForkGuest(Thread, flags, stack, parent_tid, child_tid, tls);
} else {
if (!AllFlagsSet(flags, CLONE_SYSVSEM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) {
ERROR_AND_DIE("clone: CLONE_THREAD: Unsuported flags w/ CLONE_THREAD (Shared Resources), %X", flags);
}
auto NewThread = CreateNewThread(Thread, flags, stack, parent_tid, child_tid, tls);
auto NewThread = FEX::HLE::CreateNewThread(Thread, flags, stack, parent_tid, child_tid, tls);
// Return the new threads TID
uint64_t Result = NewThread->State.ThreadManager.GetTID();
// Actually start the thread
Thread->CTX->RunThread(NewThread);
FEXCore::Context::RunThread(Thread->CTX, NewThread);
if (flags & CLONE_VFORK) {
// If VFORK is set then the calling process is suspended until the thread exits with execve or exit
@@ -255,7 +250,7 @@ namespace FEXCore::HLE::x32 {
old64 = *old_ss;
old64_ptr = &old64;
}
uint64_t Result = Thread->CTX->SignalDelegation.RegisterGuestSigAltStack(ss64_ptr, old64_ptr);
uint64_t Result = FEX::HLE::_SyscallHandler->GetSignalDelegator()->RegisterGuestSigAltStack(ss64_ptr, old64_ptr);
if (Result == 0 && old_ss) {
*old_ss = old64;
@@ -291,19 +286,19 @@ namespace FEXCore::HLE::x32 {
};
uint64_t Result{};
if (Thread->CTX->SyscallHandler->IsInterpreter()) {
if (Thread->CTX->SyscallHandler->IsInterpreterInstalled() && ELFLoader::ELFContainer::IsSupportedELF(pathname)) {
if (FEX::HLE::_SyscallHandler->IsInterpreter()) {
if (FEX::HLE::_SyscallHandler->IsInterpreterInstalled() && ELFLoader::ELFContainer::IsSupportedELF(pathname)) {
PushBackDefaultArgs(argv, envp);
Result = execve(pathname, const_cast<char *const *>(&Args[0]), const_cast<char *const *>(&Envp[0]));
SYSCALL_ERRNO();
}
else {
// Otherwise we need to fall down the interpreter unsupported code path
Thread->CTX->GetCodeLoader()->GetExecveArguments(&Args);
FEX::HLE::_SyscallHandler->GetCodeLoader()->GetExecveArguments(&Args);
}
}
else {
Thread->CTX->GetCodeLoader()->GetExecveArguments(&Args);
FEX::HLE::_SyscallHandler->GetCodeLoader()->GetExecveArguments(&Args);
Args.push_back("--");
}
@@ -6,7 +6,7 @@ struct InternalThreadState;
struct CPUState;
}
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
// We must define this ourselves since it doesn't exist on non-x86 platforms
struct user_desc {
uint32_t entry_number;
@@ -1,6 +1,5 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x32/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
@@ -11,7 +10,7 @@
#include <unistd.h>
#include <utime.h>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
void RegisterTime() {
REGISTER_SYSCALL_IMPL_X32(gettimeofday, [](FEXCore::Core::InternalThreadState *Thread, timeval32 *tv, struct timezone *tz) -> uint64_t {
struct timeval tv64{};
@@ -11,7 +11,7 @@
#include <time.h>
#include <type_traits>
namespace FEXCore::HLE::x32 {
namespace FEX::HLE::x32 {
// Basic types to make tracking easier
using compat_ulong_t = uint32_t;
@@ -1,6 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <fcntl.h>
#include <sys/time.h>
@@ -8,7 +8,7 @@
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
struct __attribute__((packed)) guest_stat {
__kernel_ulong_t st_dev;
__kernel_ulong_t st_ino;
@@ -91,7 +91,7 @@ namespace FEXCore::HLE::x64 {
REGISTER_SYSCALL_IMPL_X64(stat, [](FEXCore::Core::InternalThreadState *Thread, const char *pathname, guest_stat *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Stat(pathname, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Stat(pathname, &host_stat);
if (Result != -1) {
CopyStat(buf, &host_stat);
}
@@ -109,7 +109,7 @@ namespace FEXCore::HLE::x64 {
REGISTER_SYSCALL_IMPL_X64(lstat, [](FEXCore::Core::InternalThreadState *Thread, const char *path, guest_stat *buf) -> uint64_t {
struct stat host_stat;
uint64_t Result = Thread->CTX->SyscallHandler->FM.Lstat(path, &host_stat);
uint64_t Result = FEX::HLE::_SyscallHandler->FM.Lstat(path, &host_stat);
if (Result != -1) {
CopyStat(buf, &host_stat);
}
@@ -1,15 +1,11 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <linux/aio_abi.h>
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE::x64{
namespace FEX::HLE::x64 {
void RegisterIO() {
REGISTER_SYSCALL_IMPL_X64(io_getevents, [](FEXCore::Core::InternalThreadState *Thread, aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout) -> uint64_t {
uint64_t Result = ::syscall(SYS_io_getevents, ctx_id, min_nr, nr, events, timeout);
@@ -1,15 +1,12 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <cstring>
#include <sys/utsname.h>
#include <sys/sysinfo.h>
#ifndef FEXCORE_VERSION
#define FEXCORE_VERSION "1"
#endif
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterInfo() {
REGISTER_SYSCALL_IMPL_X64(uname, [](FEXCore::Core::InternalThreadState *Thread, struct utsname *buf) -> uint64_t {
strcpy(buf->sysname, "Linux");
@@ -1,15 +1,11 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/ioctl.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterIoctl() {
REGISTER_SYSCALL_IMPL_X64(ioctl, [](FEXCore::Core::InternalThreadState *Thread, int fd, uint64_t request, void *args) -> uint64_t {
uint64_t Result = ::ioctl(fd, request, args);
@@ -1,11 +1,11 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <sys/mman.h>
#include <sys/shm.h>
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterMemory() {
REGISTER_SYSCALL_IMPL_X64(munmap, [](FEXCore::Core::InternalThreadState *Thread, void *addr, size_t length) -> uint64_t {
uint64_t Result = ::munmap(addr, length);
@@ -1,14 +1,10 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <mqueue.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterMsg() {
REGISTER_SYSCALL_IMPL_X64(mq_timedsend, [](FEXCore::Core::InternalThreadState *Thread, mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout) -> uint64_t {
uint64_t Result = ::mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, abs_timeout);
@@ -1,8 +1,8 @@
#include <FEXCore/Utils/LogManager.h>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
#define REGISTER_SYSCALL_NOT_IMPL_X64(name) REGISTER_SYSCALL_IMPL_X64(name, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t { \
LogMan::Msg::D("Using deprecated/removed syscall: " #name); \
return -ENOSYS; \
@@ -1,6 +1,6 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <stdint.h>
#include <sched.h>
@@ -9,11 +9,7 @@
#include <sys/syscall.h>
#include <unistd.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterSched() {
REGISTER_SYSCALL_IMPL_X64(sched_rr_get_interval, [](FEXCore::Core::InternalThreadState *Thread, pid_t pid, struct timespec *tp) -> uint64_t {
uint64_t Result = ::sched_rr_get_interval(pid, tp);
@@ -1,11 +1,10 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/Context/Context.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <sys/sem.h>
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterSemaphore() {
REGISTER_SYSCALL_IMPL_X64(semop, [](FEXCore::Core::InternalThreadState *Thread, int semid, struct sembuf *sops, size_t nsops) -> uint64_t {
uint64_t Result = ::semop(semid, sops, nsops);
@@ -1,8 +1,8 @@
#include "Interface/Context/Context.h"
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Core/Context.h>
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterSocket() {
REGISTER_SYSCALL_IMPL_X64(accept, [](FEXCore::Core::InternalThreadState *Thread, int sockfd, struct sockaddr *addr, socklen_t *addrlen) -> uint64_t {
uint64_t Result = ::accept(sockfd, addr, addrlen);
@@ -1,32 +1,12 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <map>
namespace FEXCore::HLE {
void RegisterEpoll();
void RegisterFD();
void RegisterFS();
void RegisterInfo();
void RegisterIO();
void RegisterKey();
void RegisterMemory();
void RegisterMsg();
void RegisterNuma();
void RegisterSched();
void RegisterSemaphore();
void RegisterSHM();
void RegisterSignals();
void RegisterSocket();
void RegisterThread();
void RegisterTime();
void RegisterTimer();
void RegisterNotImplemented();
void RegisterStubs();
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterFD();
void RegisterInfo();
void RegisterIO();
@@ -78,9 +58,9 @@ namespace FEXCore::HLE::x64 {
});
}
class x64SyscallHandler final : public FEXCore::SyscallHandler {
class x64SyscallHandler final : public FEX::HLE::SyscallHandler {
public:
x64SyscallHandler(FEXCore::Context::Context *ctx);
x64SyscallHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation);
// In the case that the syscall doesn't hit the optimized path then we still need to go here
uint64_t HandleSyscall(FEXCore::Core::InternalThreadState *Thread, FEXCore::HLE::SyscallArguments *Args) override;
@@ -118,13 +98,15 @@ namespace FEXCore::HLE::x64 {
return -1;
}
x64SyscallHandler::x64SyscallHandler(FEXCore::Context::Context *ctx)
: SyscallHandler {ctx} {
x64SyscallHandler::x64SyscallHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation)
: SyscallHandler {ctx, _SignalDelegation} {
OSABI = FEXCore::HLE::SyscallOSABI::OS_LINUX64;
RegisterSyscallHandlers();
}
void x64SyscallHandler::RegisterSyscallHandlers() {
Definitions.resize(FEXCore::HLE::x64::SYSCALL_MAX);
Definitions.resize(FEX::HLE::x64::SYSCALL_MAX);
auto cvt = [](auto in) {
union {
decltype(in) val;
@@ -140,38 +122,38 @@ namespace FEXCore::HLE::x64 {
Def.Ptr = cvt(&Unimplemented);
}
FEXCore::HLE::RegisterEpoll();
FEXCore::HLE::RegisterFD();
FEXCore::HLE::RegisterFS();
FEXCore::HLE::RegisterInfo();
FEXCore::HLE::RegisterIO();
FEXCore::HLE::RegisterKey();
FEXCore::HLE::RegisterMemory();
FEXCore::HLE::RegisterMsg();
FEXCore::HLE::RegisterSched();
FEXCore::HLE::RegisterSemaphore();
FEXCore::HLE::RegisterSHM();
FEXCore::HLE::RegisterSignals();
FEXCore::HLE::RegisterSocket();
FEXCore::HLE::RegisterThread();
FEXCore::HLE::RegisterTime();
FEXCore::HLE::RegisterTimer();
FEXCore::HLE::RegisterNotImplemented();
FEXCore::HLE::RegisterStubs();
FEX::HLE::RegisterEpoll();
FEX::HLE::RegisterFD();
FEX::HLE::RegisterFS();
FEX::HLE::RegisterInfo();
FEX::HLE::RegisterIO();
FEX::HLE::RegisterKey();
FEX::HLE::RegisterMemory();
FEX::HLE::RegisterMsg();
FEX::HLE::RegisterSched();
FEX::HLE::RegisterSemaphore();
FEX::HLE::RegisterSHM();
FEX::HLE::RegisterSignals();
FEX::HLE::RegisterSocket();
FEX::HLE::RegisterThread();
FEX::HLE::RegisterTime();
FEX::HLE::RegisterTimer();
FEX::HLE::RegisterNotImplemented();
FEX::HLE::RegisterStubs();
// 64bit specific
FEXCore::HLE::x64::RegisterFD();
FEXCore::HLE::x64::RegisterInfo();
FEXCore::HLE::x64::RegisterIO();
FEXCore::HLE::x64::RegisterIoctl();
FEXCore::HLE::x64::RegisterMemory();
FEXCore::HLE::x64::RegisterMsg();
FEXCore::HLE::x64::RegisterSched();
FEXCore::HLE::x64::RegisterSocket();
FEXCore::HLE::x64::RegisterSemaphore();
FEXCore::HLE::x64::RegisterThread();
FEXCore::HLE::x64::RegisterTime();
FEXCore::HLE::x64::RegisterNotImplemented();
FEX::HLE::x64::RegisterFD();
FEX::HLE::x64::RegisterInfo();
FEX::HLE::x64::RegisterIO();
FEX::HLE::x64::RegisterIoctl();
FEX::HLE::x64::RegisterMemory();
FEX::HLE::x64::RegisterMsg();
FEX::HLE::x64::RegisterSched();
FEX::HLE::x64::RegisterSocket();
FEX::HLE::x64::RegisterSemaphore();
FEX::HLE::x64::RegisterThread();
FEX::HLE::x64::RegisterTime();
FEX::HLE::x64::RegisterNotImplemented();
// Set all the new definitions
for (auto &Syscall : syscalls_x64) {
@@ -214,8 +196,7 @@ namespace FEXCore::HLE::x64 {
return -1;
}
FEXCore::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx) {
return new x64SyscallHandler(ctx);
FEX::HLE::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation) {
return new x64SyscallHandler(ctx, _SignalDelegation);
}
}
@@ -1,6 +1,6 @@
#pragma once
#include "Interface/HLE/FileManagement.h"
#include "Tests/LinuxSyscalls/FileManagement.h"
#include <FEXCore/HLE/SyscallHandler.h>
#include <atomic>
@@ -8,19 +8,19 @@
#include <mutex>
#include <unordered_map>
namespace FEX::HLE {
class SignalDelegator;
class SyscallHandler;
}
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore {
class SyscallHandler;
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
#include "SyscallsEnum.h"
FEXCore::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx);
FEX::HLE::SyscallHandler *CreateHandler(FEXCore::Context::Context *ctx, FEX::HLE::SignalDelegator *_SignalDelegation);
void RegisterSyscallInternal(int SyscallNumber,
#ifdef DEBUG_STRACE
const std::string& TraceFormatString,
@@ -41,7 +41,7 @@ bool RegisterSyscall(int SyscallNumber, const char *Name, R(*fn)(FEXCore::Core::
#ifdef DEBUG_STRACE
auto TraceFormatString = std::string(Name) + "(" + CollectArgsFmtString<Args...>() + ") = %ld";
#endif
FEXCore::HLE::x64::RegisterSyscallInternal(SyscallNumber,
FEX::HLE::x64::RegisterSyscallInternal(SyscallNumber,
#ifdef DEBUG_STRACE
TraceFormatString,
#endif
@@ -79,5 +79,5 @@ bool RegisterSyscall(int num, const char *name, F f){
struct impl_##name { \
impl_##name() \
{ \
FEXCore::HLE::x64::RegisterSyscall(x64::SYSCALL_x64_##name, #name, lambda); \
FEX::HLE::x64::RegisterSyscall(x64::SYSCALL_x64_##name, #name, lambda); \
} } impl_##name
@@ -1,14 +1,14 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/Syscalls/Thread.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x64/Thread.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Thread.h"
#include "Tests/LinuxSyscalls/Syscalls/Thread.h"
#include "Interface/Context/Context.h"
#include "Interface/Core/InternalThreadState.h"
#include "Interface/HLE/Syscalls.h"
#include <FEXCore/Core/Context.h>
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/Utils/ELFLoader.h>
#include <FEXCore/Utils/LogManager.h>
#include <stdint.h>
#include <linux/futex.h>
@@ -17,7 +17,7 @@
#include <unistd.h>
#include <filesystem>
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
uint64_t SetThreadArea(FEXCore::Core::InternalThreadState *Thread, void *tls) {
Thread->State.State.fs = reinterpret_cast<uint64_t>(tls);
return 0;
@@ -96,27 +96,21 @@ namespace FEXCore::HLE::x64 {
// CLONE_PARENT is ignored (Implied by CLONE_THREAD)
if (Thread->CTX->GetThreadCount() != 1) {
LogMan::Msg::E("clone: Fork only supported on single threaded applications. Allowing");
} else {
LogMan::Msg::D("clone: Forking process");
}
return ForkGuest(Thread, flags, stack, parent_tid, child_tid, tls);
return FEX::HLE::ForkGuest(Thread, flags, stack, parent_tid, child_tid, tls);
} else {
if (!AllFlagsSet(flags, CLONE_SYSVSEM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)) {
ERROR_AND_DIE("clone: CLONE_THREAD: Unsuported flags w/ CLONE_THREAD (Shared Resources), %X", flags);
}
auto NewThread = CreateNewThread(Thread, flags, stack, parent_tid, child_tid, tls);
auto NewThread = FEX::HLE::CreateNewThread(Thread, flags, stack, parent_tid, child_tid, tls);
// Return the new threads TID
uint64_t Result = NewThread->State.ThreadManager.GetTID();
LogMan::Msg::D("Child [%d] starting at: 0x%lx. Parent was at 0x%lx", Result, NewThread->State.State.rip, Thread->State.State.rip);
// Actually start the thread
Thread->CTX->RunThread(NewThread);
FEXCore::Context::RunThread(Thread->CTX, NewThread);
if (flags & CLONE_VFORK) {
// If VFORK is set then the calling process is suspended until the thread exits with execve or exit
@@ -138,7 +132,7 @@ namespace FEXCore::HLE::x64 {
});
REGISTER_SYSCALL_IMPL_X64(sigaltstack, [](FEXCore::Core::InternalThreadState *Thread, const stack_t *ss, stack_t *old_ss) -> uint64_t {
return Thread->CTX->SignalDelegation.RegisterGuestSigAltStack(ss, old_ss);
return FEX::HLE::_SyscallHandler->GetSignalDelegator()->RegisterGuestSigAltStack(ss, old_ss);
});
// launch a new process under fex
@@ -153,18 +147,18 @@ namespace FEXCore::HLE::x64 {
}
uint64_t Result{};
if (Thread->CTX->SyscallHandler->IsInterpreter()) {
if (Thread->CTX->SyscallHandler->IsInterpreterInstalled() && ELFLoader::ELFContainer::IsSupportedELF(pathname)) {
if (FEX::HLE::_SyscallHandler->IsInterpreter()) {
if (FEX::HLE::_SyscallHandler->IsInterpreterInstalled() && ELFLoader::ELFContainer::IsSupportedELF(pathname)) {
Result = execve(pathname, argv, envp);
SYSCALL_ERRNO();
}
else {
// Otherwise we need to fall down the interpreter unsupported code path
Thread->CTX->GetCodeLoader()->GetExecveArguments(&Args);
FEX::HLE::_SyscallHandler->GetCodeLoader()->GetExecveArguments(&Args);
}
}
else {
Thread->CTX->GetCodeLoader()->GetExecveArguments(&Args);
FEX::HLE::_SyscallHandler->GetCodeLoader()->GetExecveArguments(&Args);
Args.push_back("--");
}
@@ -6,7 +6,7 @@ struct InternalThreadState;
struct CPUState;
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
uint64_t SetThreadArea(FEXCore::Core::InternalThreadState *Thread, void *tls);
void AdjustRipForNewThread(FEXCore::Core::CPUState *Thread);
}
@@ -1,6 +1,5 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/x64/Syscalls.h"
#include <stddef.h>
#include <stdint.h>
@@ -11,11 +10,7 @@
#include <unistd.h>
#include <utime.h>
namespace FEXCore::Core {
struct InternalThreadState;
}
namespace FEXCore::HLE::x64 {
namespace FEX::HLE::x64 {
void RegisterTime() {
REGISTER_SYSCALL_IMPL_X64(gettimeofday, [](FEXCore::Core::InternalThreadState *Thread, struct timeval *tv, struct timezone *tz) -> uint64_t {
uint64_t Result = ::gettimeofday(tv, tz);
+8
View File
@@ -2,6 +2,8 @@
#include "Common/EnvironmentLoader.h"
#include "CommonCore/HostFactory.h"
#include "HarnessHelpers.h"
#include "Tests/LinuxSyscalls/Syscalls.h"
#include "Tests/LinuxSyscalls/SignalDelegator.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
@@ -94,7 +96,13 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Context::SetCustomCPUBackendFactory(CTX, HostFactory::CPUCreationFactory);
FEXCore::Context::InitializeContext(CTX);
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode() ? "1" : "0");
std::unique_ptr<FEX::HLE::SignalDelegator> SignalDelegation = std::make_unique<FEX::HLE::SignalDelegator>();
std::unique_ptr<FEXCore::HLE::SyscallHandler> SyscallHandler{FEX::HLE::CreateHandler(Loader.Is64BitMode() ? FEXCore::Context::OperatingMode::MODE_64BIT : FEXCore::Context::OperatingMode::MODE_32BIT, CTX, SignalDelegation.get())};
FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get());
FEXCore::Context::SetSyscallHandler(CTX, SyscallHandler.get());
bool Result1 = FEXCore::Context::InitCore(CTX, &Loader);
if (!Result1)