Open Sonicadvance1 opened 4 months ago
Implemented a hack for EFLAGS.TF. Signal handler entry needs to clear EFLAGS to a known good state when a TF happens (Maybe with other signals as well?) UPC then continues forward and tries to ptrace itself which results in a new error message.
Error at hooking API "LdrFindResource_U"
Dumping first 32 bytes:
<bytes>
Ptrace issue has been known since #1335
diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp
index 9db0e7c52..6e6784a13 100644
--- a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp
+++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp
@@ -732,6 +732,31 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, const FEXCore
offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - offsetof(FEXCore::Core::InternalThreadState, BaseFrameState));
}
+ ldrb(TMP1, STATE, offsetof(FEXCore::Core::CPUState, flags[X86State::RFLAG_TF_LOC]));
+
+ ARMEmitter::SingleUseForwardLabel TFCheck{};
+ cbz(ARMEmitter::Size::i64Bit, TMP1, &TFCheck);
+
+ // Do TFCheck.
+ ///< XXX: Correct?
+ Core::CpuStateFrame::SynchronousFaultDataStruct State = {
+ .FaultToTopAndGeneratedException = 1,
+ .Signal = SIGTRAP,
+ .TrapNo = 0,
+ .si_code = 0,
+ .err_code = 0,
+ };
+
+ uint64_t Constant {};
+ memcpy(&Constant, &State, sizeof(State));
+
+ LoadConstant(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r1, Constant);
+ str(ARMEmitter::XReg::x1, STATE, offsetof(FEXCore::Core::CpuStateFrame, SynchronousFaultData));
+ ldr(TMP1, STATE, offsetof(FEXCore::Core::CpuStateFrame, Pointers.Common.GuestSignal_SIGTRAP));
+ br(TMP1);
+
+ Bind(&TFCheck);
+
// LOGMAN_THROW_A_FMT(RAData->HasFullRA(), "Arm64 JIT only works with RA");
SpillSlots = RAData->SpillSlots();
diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp
index 588fc77d5..eb37cf6d7 100644
--- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp
+++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp
@@ -412,7 +412,9 @@ void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Threa
Frame->State.rip = guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_RIP];
// XXX: Full context setting
- CTX->SetFlagsFromCompactedEFLAGS(Thread, guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_EFL]);
+ uint32_t eflags = guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_EFL];
+ eflags &= ~(1U << FEXCore::X86State::RFLAG_TF_LOC);
+ CTX->SetFlagsFromCompactedEFLAGS(Thread, eflags);
#define COPY_REG(x) Frame->State.gregs[FEXCore::X86State::REG_##x] = guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_##x];
COPY_REG(R8);
@@ -479,7 +481,9 @@ void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thre
ArchHelpers::Context::SetState(ucontext, reinterpret_cast<uint64_t>(Frame));
// XXX: Full context setting
- CTX->SetFlagsFromCompactedEFLAGS(Thread, guest_uctx->sc.flags);
+ uint32_t eflags = guest_uctx->sc.flags;
+ eflags &= ~(1U << FEXCore::X86State::RFLAG_TF_LOC);
+ CTX->SetFlagsFromCompactedEFLAGS(Thread, eflags);
Frame->State.rip = guest_uctx->sc.ip;
Frame->State.cs_idx = guest_uctx->sc.cs;
@@ -558,7 +562,9 @@ void SignalDelegator::RestoreRTFrame_ia32(FEXCore::Core::InternalThreadState* Th
ArchHelpers::Context::SetState(ucontext, reinterpret_cast<uint64_t>(Frame));
// XXX: Full context setting
- CTX->SetFlagsFromCompactedEFLAGS(Thread, guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_EFL]);
+ uint32_t eflags = guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_EFL];
+ eflags &= ~(1U << FEXCore::X86State::RFLAG_TF_LOC);
+ CTX->SetFlagsFromCompactedEFLAGS(Thread, eflags);
Frame->State.rip = guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_EIP];
Frame->State.cs_idx = guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_CS];
@@ -1201,6 +1207,7 @@ bool SignalDelegator::HandleDispatcherGuestSignal(FEXCore::Core::InternalThreadS
Frame->State.rip = reinterpret_cast<uint64_t>(GuestAction->sigaction_handler.sigaction);
Frame->State.gregs[FEXCore::X86State::REG_RSP] = NewGuestSP;
+ Frame->State.flags[FEXCore::X86State::RFLAG_TF_LOC] = 0;
// The guest starts its signal frame with a zero initialized FPU
// Set that up now. Little bit costly but it's a requirement
For the hack.
What a nightmare.