Skip to content

Commit

Permalink
Thunks: Wire up TLS handling in the frontend
Browse files Browse the repository at this point in the history
Because it was moved from the backend to the frontend, re-wire up the
TLS handling which requires going through our syscall handler.
  • Loading branch information
Sonicadvance1 committed Sep 20, 2024
1 parent c6c74e4 commit 3eb59df
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 28 deletions.
8 changes: 4 additions & 4 deletions Source/Tools/FEXLoader/FEXLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,12 @@ int main(int argc, char** argv, char** const envp) {
FEX::TSO::SetupTSOEmulation(CTX.get());

auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName);

auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get()) :
FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), std::move(Allocator));

auto ThunkHandler = FEX::HLE::CreateThunkHandler();

auto SyscallHandler = Loader.Is64BitMode() ?
FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get(), ThunkHandler.get()) :
FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), ThunkHandler.get(), std::move(Allocator));

// Load VDSO in to memory prior to mapping our ELFs.
auto VDSOMapping = FEX::VDSO::LoadVDSOThunks(Loader.Is64BitMode(), SyscallHandler.get());

Expand Down
15 changes: 13 additions & 2 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ desc: Glue logic, brk allocations
#include "LinuxSyscalls/x64/Syscalls.h"
#include "LinuxSyscalls/x32/Types.h"
#include "LinuxSyscalls/x64/Types.h"
#include "Thunks.h"

#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/Context.h>
Expand Down Expand Up @@ -740,12 +741,13 @@ void SyscallHandler::DefaultProgramBreak(uint64_t Base, uint64_t Size) {
DataSpaceStartingSize = Size;
}

SyscallHandler::SyscallHandler(FEXCore::Context::Context* _CTX, FEX::HLE::SignalDelegator* _SignalDelegation)
SyscallHandler::SyscallHandler(FEXCore::Context::Context* _CTX, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler)
: TM {_CTX, _SignalDelegation}
, SeccompEmulator {this, _SignalDelegation}
, FM {_CTX}
, CTX {_CTX}
, SignalDelegation {_SignalDelegation} {
, SignalDelegation {_SignalDelegation}
, ThunkHandler {ThunkHandler} {
FEX::HLE::_SyscallHandler = this;
HostKernelVersion = CalculateHostKernelVersion();
GuestKernelVersion = CalculateGuestKernelVersion();
Expand Down Expand Up @@ -872,6 +874,15 @@ void SyscallHandler::UnlockAfterFork(FEXCore::Core::InternalThreadState* LiveThr
TM.UnlockAfterFork(LiveThread, Child);
}

void SyscallHandler::RegisterTLSState(FEX::HLE::ThreadStateObject* Thread) {
SignalDelegation->RegisterTLSState(Thread);
ThunkHandler->RegisterTLSState(CTX, Thread);
}

void SyscallHandler::UninstallTLSState(FEX::HLE::ThreadStateObject* Thread) {
SignalDelegation->UninstallTLSState(Thread);
}

static bool isHEX(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}
Expand Down
8 changes: 7 additions & 1 deletion Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ namespace FEX::HLE {

class SyscallHandler;
class SignalDelegator;
class ThunkHandler;

void RegisterEpoll(FEX::HLE::SyscallHandler* Handler);
void RegisterFD(FEX::HLE::SyscallHandler* Handler);
void RegisterFS(FEX::HLE::SyscallHandler* Handler);
Expand Down Expand Up @@ -255,6 +257,9 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source
void LockBeforeFork(FEXCore::Core::InternalThreadState* Thread);
void UnlockAfterFork(FEXCore::Core::InternalThreadState* LiveThread, bool Child);

void RegisterTLSState(FEX::HLE::ThreadStateObject* Thread);
void UninstallTLSState(FEX::HLE::ThreadStateObject* Thread);

SourcecodeResolver* GetSourcecodeResolver() override {
return this;
}
Expand All @@ -273,7 +278,7 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source
constexpr static uint64_t TASK_MAX_64BIT = (1ULL << 48);

protected:
SyscallHandler(FEXCore::Context::Context* _CTX, FEX::HLE::SignalDelegator* _SignalDelegation);
SyscallHandler(FEXCore::Context::Context* _CTX, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler);

fextl::vector<SyscallFunctionDefinition> Definitions {std::max<std::size_t>(FEX::HLE::x64::SYSCALL_x64_MAX, FEX::HLE::x32::SYSCALL_x86_MAX),
{
Expand All @@ -297,6 +302,7 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source
private:

FEX::HLE::SignalDelegator* SignalDelegation;
FEX::HLE::ThunkHandler* ThunkHandler;

std::mutex FutexMutex;
std::mutex SyscallMutex;
Expand Down
8 changes: 4 additions & 4 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ static void* ThreadHandler(void* Data) {
Thread->ThreadInfo.PID = ::getpid();
Thread->ThreadInfo.TID = FHU::Syscalls::gettid();

FEX::HLE::_SyscallHandler->GetSignalDelegator()->RegisterTLSState(Thread);
FEX::HLE::_SyscallHandler->RegisterTLSState(Thread);
CTX->ExecutionThread(Thread->Thread);
FEX::HLE::_SyscallHandler->GetSignalDelegator()->UninstallTLSState(Thread);
FEX::HLE::_SyscallHandler->UninstallTLSState(Thread);
FEX::HLE::_SyscallHandler->TM.DestroyThread(Thread);
return nullptr;
}
Expand Down Expand Up @@ -224,13 +224,13 @@ uint64_t HandleNewClone(FEX::HLE::ThreadStateObject* Thread, FEXCore::Context::C
FEX::HLE::_SyscallHandler->TM.TrackThread(Thread);
}

FEX::HLE::_SyscallHandler->GetSignalDelegator()->RegisterTLSState(Thread);
FEX::HLE::_SyscallHandler->RegisterTLSState(Thread);

// Start exuting the thread directly
// Our host clone starts in a new stack space, so it can't return back to the JIT space
CTX->ExecutionThread(Thread->Thread);

FEX::HLE::_SyscallHandler->GetSignalDelegator()->UninstallTLSState(Thread);
FEX::HLE::_SyscallHandler->UninstallTLSState(Thread);

// The rest of the context remains as is and the thread will continue executing
return Thread->Thread->StatusCode;
Expand Down
10 changes: 5 additions & 5 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ void RegisterTimer(FEX::HLE::SyscallHandler* Handler);
void RegisterPassthrough(FEX::HLE::SyscallHandler* Handler);

x32SyscallHandler::x32SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation,
fextl::unique_ptr<MemAllocator> Allocator)
: SyscallHandler {ctx, _SignalDelegation}
FEX::HLE::ThunkHandler* ThunkHandler, fextl::unique_ptr<MemAllocator> Allocator)
: SyscallHandler {ctx, _SignalDelegation, ThunkHandler}
, AllocHandler {std::move(Allocator)} {
OSABI = FEXCore::HLE::SyscallOSABI::OS_LINUX32;
RegisterSyscallHandlers();
Expand Down Expand Up @@ -91,9 +91,9 @@ void x32SyscallHandler::RegisterSyscallHandlers() {
#endif
}

fextl::unique_ptr<FEX::HLE::SyscallHandler>
CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, fextl::unique_ptr<MemAllocator> Allocator) {
return fextl::make_unique<x32SyscallHandler>(ctx, _SignalDelegation, std::move(Allocator));
fextl::unique_ptr<FEX::HLE::SyscallHandler> CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation,
FEX::HLE::ThunkHandler* ThunkHandler, fextl::unique_ptr<MemAllocator> Allocator) {
return fextl::make_unique<x32SyscallHandler>(ctx, _SignalDelegation, ThunkHandler, std::move(Allocator));
}

} // namespace FEX::HLE::x32
10 changes: 6 additions & 4 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ namespace Core {

namespace FEX::HLE {
class SignalDelegator;
}
class ThunkHandler;
} // namespace FEX::HLE

namespace FEX::HLE::x32 {

class x32SyscallHandler final : public FEX::HLE::SyscallHandler {
public:
x32SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, fextl::unique_ptr<MemAllocator> Allocator);
x32SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler,
fextl::unique_ptr<MemAllocator> Allocator);

FEX::HLE::MemAllocator* GetAllocator() {
return AllocHandler.get();
Expand Down Expand Up @@ -65,8 +67,8 @@ class x32SyscallHandler final : public FEX::HLE::SyscallHandler {
fextl::unique_ptr<MemAllocator> AllocHandler {};
};

fextl::unique_ptr<FEX::HLE::SyscallHandler>
CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, fextl::unique_ptr<MemAllocator> Allocator);
fextl::unique_ptr<FEX::HLE::SyscallHandler> CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation,
FEX::HLE::ThunkHandler* ThunkHandler, fextl::unique_ptr<MemAllocator> Allocator);
//////
// REGISTER_SYSCALL_IMPL implementation
// Given a syscall name + a lambda, and it will generate an strace string, extract number of arguments
Expand Down
9 changes: 5 additions & 4 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x64/Syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ void RegisterTime(FEX::HLE::SyscallHandler* Handler);
void RegisterNotImplemented(FEX::HLE::SyscallHandler* Handler);
void RegisterPassthrough(FEX::HLE::SyscallHandler* Handler);

x64SyscallHandler::x64SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation)
: SyscallHandler {ctx, _SignalDelegation} {
x64SyscallHandler::x64SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler)
: SyscallHandler {ctx, _SignalDelegation, ThunkHandler} {
OSABI = FEXCore::HLE::SyscallOSABI::OS_LINUX64;

RegisterSyscallHandlers();
Expand Down Expand Up @@ -80,7 +80,8 @@ void x64SyscallHandler::RegisterSyscallHandlers() {
#endif
}

fextl::unique_ptr<FEX::HLE::SyscallHandler> CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation) {
return fextl::make_unique<x64SyscallHandler>(ctx, _SignalDelegation);
fextl::unique_ptr<FEX::HLE::SyscallHandler>
CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler) {
return fextl::make_unique<x64SyscallHandler>(ctx, _SignalDelegation, ThunkHandler);
}
} // namespace FEX::HLE::x64
6 changes: 4 additions & 2 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/x64/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ tags: LinuxSyscalls|syscalls-x86-64
namespace FEX::HLE {
class SignalDelegator;
class SyscallHandler;
class ThunkHandler;
} // namespace FEX::HLE

namespace FEXCore::Core {
Expand All @@ -32,7 +33,7 @@ struct InternalThreadState;
namespace FEX::HLE::x64 {
class x64SyscallHandler final : public FEX::HLE::SyscallHandler {
public:
x64SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation);
x64SyscallHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler);

void* GuestMmap(FEXCore::Core::InternalThreadState* Thread, void* addr, size_t length, int prot, int flags, int fd, off_t offset) override;
int GuestMunmap(FEXCore::Core::InternalThreadState* Thread, void* addr, uint64_t length) override;
Expand Down Expand Up @@ -60,7 +61,8 @@ class x64SyscallHandler final : public FEX::HLE::SyscallHandler {
void RegisterSyscallHandlers();
};

fextl::unique_ptr<FEX::HLE::SyscallHandler> CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation);
fextl::unique_ptr<FEX::HLE::SyscallHandler>
CreateHandler(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator* _SignalDelegation, FEX::HLE::ThunkHandler* ThunkHandler);

//////
// REGISTER_SYSCALL_IMPL implementation
Expand Down
4 changes: 2 additions & 2 deletions Source/Tools/TestHarnessRunner/TestHarnessRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ int main(int argc, char** argv, char** const envp) {

if (!IsHostRunner) {
#ifndef _WIN32
auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get()) :
FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), std::move(Allocator));
auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get(), nullptr) :
FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), nullptr, std::move(Allocator));

#else
auto SyscallHandler = FEX::WindowsHandlers::CreateSyscallHandler();
Expand Down

0 comments on commit 3eb59df

Please sign in to comment.