mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 11:01:01 +02:00
FEXCore: Move LDT/GDT management to the frontend
This will allow the frontend to manage LDT and GDT so that Linux will be able to install 32-bit code segments.
This commit is contained in:
5 files changed
+91
-30
No files matched your search
@@ -644,6 +644,7 @@ NTSTATUS ProcessInit() {
|
||||
CTX->SetSignalDelegator(SignalDelegator.get());
|
||||
CTX->SetSyscallHandler(SyscallHandler.get());
|
||||
CTX->InitCore();
|
||||
|
||||
InvalidationTracker.emplace(*CTX, Threads);
|
||||
|
||||
HandleImageMap(NtDllBase);
|
||||
@@ -924,6 +925,24 @@ NTSTATUS ThreadInit() {
|
||||
|
||||
auto* Thread = CTX->CreateThread(0, 0);
|
||||
|
||||
// Default segment setup.
|
||||
auto Frame = Thread->CurrentFrame;
|
||||
auto NewSegments = new FEXCore::Core::CPUState::gdt_segment[32];
|
||||
|
||||
// Setup initial code-segment GDT
|
||||
auto &GDT = NewSegments[FEXCore::Core::CPUState::DEFAULT_USER_CS];
|
||||
FEXCore::Core::CPUState::SetGDTBase(&GDT, 0);
|
||||
FEXCore::Core::CPUState::SetGDTLimit(&GDT, 0xF'FFFFU);
|
||||
GDT.L = 1; // L = Long Mode = 64-bit
|
||||
GDT.D = 0; // D = Default Operand SIze = Reserved
|
||||
|
||||
Frame->State.segment_arrays[FEXCore::Core::CPUState::SEGMENT_ARRAY_INDEX_GDT] = &NewSegments[0];
|
||||
// TODO: LDTs are currently unsupported, mirror them to GDT.
|
||||
Frame->State.segment_arrays[FEXCore::Core::CPUState::SEGMENT_ARRAY_INDEX_LDT] = &NewSegments[0];
|
||||
|
||||
Frame->State.cs_idx = FEXCore::Core::CPUState::DEFAULT_USER_CS << 3;
|
||||
Frame->State.cs_cached = FEXCore::Core::CPUState::CalculateGDTBase(GDT);
|
||||
|
||||
FEX::Windows::CallRetStack::InitializeThread(Thread);
|
||||
Thread->CurrentFrame->Pointers.Common.ExitFunctionEC = reinterpret_cast<uintptr_t>(&ExitFunctionEC);
|
||||
CPUArea.StateFrame() = Thread->CurrentFrame;
|
||||
@@ -935,7 +954,7 @@ NTSTATUS ThreadInit() {
|
||||
CPUArea.DispatcherLoopTopEnterECFillSRA() = EnterECFillSRA;
|
||||
|
||||
CPUArea.ContextAmd64() = {.ContextFlags = CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT,
|
||||
.AMD64_SegCs = 0x33,
|
||||
.AMD64_SegCs = (FEXCore::Core::CPUState::DEFAULT_USER_CS << 3) | 3,
|
||||
.AMD64_SegDs = 0x2b,
|
||||
.AMD64_SegEs = 0x2b,
|
||||
.AMD64_SegFs = 0x53,
|
||||
@@ -1000,9 +1019,13 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) {
|
||||
StatAllocHandler->DeallocateSlot(CPUArea.ThreadState()->ThreadStats);
|
||||
}
|
||||
}
|
||||
auto ThreadState = CPUArea.ThreadState();
|
||||
|
||||
FEX::Windows::CallRetStack::DestroyThread(CPUArea.ThreadState());
|
||||
CTX->DestroyThread(CPUArea.ThreadState());
|
||||
// GDT and LDT are mirrored, only free one.
|
||||
delete [] ThreadState->CurrentFrame->State.segment_arrays[FEXCore::Core::CPUState::SEGMENT_ARRAY_INDEX_GDT];
|
||||
|
||||
FEX::Windows::CallRetStack::DestroyThread(ThreadState);
|
||||
CTX->DestroyThread(ThreadState);
|
||||
::VirtualFree(reinterpret_cast<void*>(CPUArea.EmulatorStackLimit()), 0, MEM_RELEASE);
|
||||
if (ThreadTID == GetCurrentThreadId()) {
|
||||
FEX::Windows::DeinitCRTThread();
|
||||
|
||||
Reference in new issue
Block a user