| 364 | } |
| 365 | |
| 366 | static void LoadStateFromECContext(FEXCore::Core::InternalThreadState* Thread, CONTEXT& Context) { |
| 367 | auto& State = Thread->CurrentFrame->State; |
| 368 | |
| 369 | if ((Context.ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { |
| 370 | // General register state |
| 371 | State.gregs[FEXCore::X86State::REG_RAX] = Context.Rax; |
| 372 | State.gregs[FEXCore::X86State::REG_RCX] = Context.Rcx; |
| 373 | State.gregs[FEXCore::X86State::REG_RDX] = Context.Rdx; |
| 374 | State.gregs[FEXCore::X86State::REG_RBX] = Context.Rbx; |
| 375 | |
| 376 | State.gregs[FEXCore::X86State::REG_RSI] = Context.Rsi; |
| 377 | State.gregs[FEXCore::X86State::REG_RDI] = Context.Rdi; |
| 378 | State.gregs[FEXCore::X86State::REG_R8] = Context.R8; |
| 379 | State.gregs[FEXCore::X86State::REG_R9] = Context.R9; |
| 380 | State.gregs[FEXCore::X86State::REG_R10] = Context.R10; |
| 381 | State.gregs[FEXCore::X86State::REG_R11] = Context.R11; |
| 382 | State.gregs[FEXCore::X86State::REG_R12] = Context.R12; |
| 383 | State.gregs[FEXCore::X86State::REG_R13] = Context.R13; |
| 384 | State.gregs[FEXCore::X86State::REG_R14] = Context.R14; |
| 385 | State.gregs[FEXCore::X86State::REG_R15] = Context.R15; |
| 386 | } |
| 387 | |
| 388 | if ((Context.ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { |
| 389 | State.rip = Context.Rip; |
| 390 | State.gregs[FEXCore::X86State::REG_RSP] = Context.Rsp; |
| 391 | State.gregs[FEXCore::X86State::REG_RBP] = Context.Rbp; |
| 392 | CTX->SetFlagsFromCompactedEFLAGS(Thread, Context.EFlags); |
| 393 | } |
| 394 | |
| 395 | if ((Context.ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { |
| 396 | State.es_idx = Context.SegEs & 0xffff; |
| 397 | State.cs_idx = Context.SegCs & 0xffff; |
| 398 | State.ss_idx = Context.SegSs & 0xffff; |
| 399 | State.ds_idx = Context.SegDs & 0xffff; |
| 400 | State.fs_idx = Context.SegFs & 0xffff; |
| 401 | State.gs_idx = Context.SegGs & 0xffff; |
| 402 | |
| 403 | // The TEB is the only populated GDT entry by default |
| 404 | const auto TEB = reinterpret_cast<uint64_t>(NtCurrentTeb()); |
| 405 | auto GDT = State.GetSegmentFromIndex(State, (Context.SegGs & 0xffff)); |
| 406 | State.SetGDTBase(GDT, TEB); |
| 407 | State.SetGDTLimit(GDT, 0xF'FFFFU); |
| 408 | State.gs_cached = TEB; |
| 409 | State.fs_cached = 0; |
| 410 | State.es_cached = 0; |
| 411 | State.cs_cached = 0; |
| 412 | State.ss_cached = 0; |
| 413 | State.ds_cached = 0; |
| 414 | } |
| 415 | |
| 416 | if ((Context.ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) { |
| 417 | // Floating-point register state |
| 418 | if ((Context.ContextFlags & CONTEXT_XSTATE) == CONTEXT_XSTATE) { |
| 419 | const auto* Ymm = RtlLocateExtendedFeature(reinterpret_cast<CONTEXT_EX*>(&Context + 1), XSTATE_AVX, nullptr); |
| 420 | CTX->SetXMMRegistersFromState(Thread, reinterpret_cast<const __uint128_t*>(Context.FltSave.XmmRegisters), |
| 421 | reinterpret_cast<const __uint128_t*>(Ymm)); |
| 422 | } else { |
| 423 | CTX->SetXMMRegistersFromState(Thread, reinterpret_cast<const __uint128_t*>(Context.FltSave.XmmRegisters), nullptr); |
no test coverage detected