mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 17:00:19 +02:00
Merge pull request #582 from Sonicadvance1/move_syscalls
Moves FEXCore's SignalDelegator and SyscallHandler to the frontend
This commit is contained in:
commit
ef75b8e4ec
93 files changed
+863
-895
No files matched your search
-46
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace FEXCore::Config {
|
||||
CONFIG_DUMP_GPRS,
|
||||
CONFIG_IS_INTERPRETER,
|
||||
CONFIG_INTERPRETER_INSTALLED,
|
||||
CONFIG_APP_FILENAME,
|
||||
};
|
||||
|
||||
enum ConfigCore {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace FEXCore::CPUID {
|
||||
struct FunctionResults {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
};
|
||||
}
|
||||
|
||||
+10
-13
@@ -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);
|
||||
}
|
||||
@@ -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};
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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/)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
+35
-35
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -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};
|
||||
};
|
||||
}
|
||||
+14
-12
@@ -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);
|
||||
+6
-8
@@ -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, ""};
|
||||
};
|
||||
}
|
||||
+18
-16
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
+15
-35
@@ -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};
|
||||
};
|
||||
|
||||
+13
-14
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+51
-23
@@ -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
|
||||
|
||||
+4
-11
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+11
-12
@@ -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();
|
||||
});
|
||||
|
||||
+7
-13
@@ -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();
|
||||
});
|
||||
|
||||
+4
-9
@@ -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
|
||||
+5
-11
@@ -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) {
|
||||
+4
-8
@@ -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);
|
||||
+5
-13
@@ -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();
|
||||
});
|
||||
|
||||
+4
-8
@@ -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);
|
||||
+4
-9
@@ -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() {
|
||||
+4
-11
@@ -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);
|
||||
+5
-11
@@ -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
|
||||
+4
-11
@@ -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);
|
||||
+14
-11
@@ -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 {
|
||||
+4
-9
@@ -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 {
|
||||
+4
-9
@@ -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 {
|
||||
+17
-44
@@ -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();
|
||||
});
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
+4
-8
@@ -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();
|
||||
+4
-9
@@ -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 {
|
||||
+11
-9
@@ -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;
|
||||
}
|
||||
+4
-8
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
+3
-14
@@ -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;
|
||||
+3
-6
@@ -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;
|
||||
+3
-3
@@ -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; \
|
||||
+3
-4
@@ -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{};
|
||||
+5
-4
@@ -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,
|
||||
+3
-6
@@ -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,
|
||||
+41
-64
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+11
-11
@@ -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
|
||||
File renamed without changes.
File renamed without changes.
+16
-21
@@ -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("--");
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
+3
-4
@@ -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{};
|
||||
+1
-1
@@ -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;
|
||||
+6
-6
@@ -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);
|
||||
}
|
||||
+3
-7
@@ -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);
|
||||
+5
-8
@@ -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");
|
||||
+3
-7
@@ -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);
|
||||
+4
-4
@@ -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);
|
||||
+4
-8
@@ -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);
|
||||
+3
-3
@@ -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; \
|
||||
+4
-8
@@ -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);
|
||||
+4
-5
@@ -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);
|
||||
+4
-4
@@ -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);
|
||||
+44
-63
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+10
-10
@@ -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
|
||||
File renamed without changes.
File renamed without changes.
+16
-22
@@ -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("--");
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
+3
-8
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user