Skip to content

Commit

Permalink
Linux/FaultSafeUserMemAccess: Break out fault safe handler
Browse files Browse the repository at this point in the history
This is going to get used by gdbserver soon for ensuring memory accesses
are fault safe, because it tries to read outside of correct memory
bounds at times.
  • Loading branch information
Sonicadvance1 committed Dec 16, 2024
1 parent 527752c commit dc35e23
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 12 deletions.
14 changes: 2 additions & 12 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,18 +578,8 @@ void SignalDelegator::HandleGuestSignal(FEX::HLE::ThreadStateObject* ThreadObjec
ERROR_AND_DIE_FMT("X86 shouldn't hit this InterruptFaultPage");
#endif
}
} else if (Signal == SIGSEGV && (SigInfo.si_code == SEGV_MAPERR || SigInfo.si_code == SEGV_ACCERR) &&
FaultSafeUserMemAccess::IsFaultLocation(ArchHelpers::Context::GetPc(UContext))) {
// If you want to emulate EFAULT behaviour then enable this if-statement.
// Do this once we find an application that depends on this.
if constexpr (false) {
// Return from the subroutine, returning EFAULT.
ArchHelpers::Context::SetArmReg(UContext, 0, EFAULT);
ArchHelpers::Context::SetPc(UContext, ArchHelpers::Context::GetArmReg(UContext, 30));
return;
} else {
ERROR_AND_DIE_FMT("Received invalid data to syscall. Crashing now!");
}
} else if (FaultSafeUserMemAccess::TryHandleSafeFault(Signal, SigInfo, UContext)) {
ERROR_AND_DIE_FMT("Received invalid data to syscall. Crashing now!");
} else {
if (IsAsyncSignal(&SigInfo, Signal) && MustDeferSignal) {
// If the signal is asynchronous (as determined by si_code) and FEX is in a state of needing
Expand Down
13 changes: 13 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ desc: Glue logic, STRACE magic
#include "LinuxSyscalls/LinuxAllocator.h"
#include "LinuxSyscalls/ThreadManager.h"
#include "LinuxSyscalls/Seccomp/SeccompEmulator.h"
#include "ArchHelpers/MContext.h"

#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/Thunks.h>
Expand Down Expand Up @@ -674,6 +675,18 @@ namespace FaultSafeUserMemAccess {
}
#endif
bool IsFaultLocation(uint64_t PC);

static inline bool TryHandleSafeFault(int Signal, siginfo_t const &SigInfo, void *UContext) {
if (Signal == SIGSEGV && (SigInfo.si_code == SEGV_MAPERR || SigInfo.si_code == SEGV_ACCERR) &&
FaultSafeUserMemAccess::IsFaultLocation(ArchHelpers::Context::GetPc(UContext))) {
// Return from the subroutine, returning EFAULT.
ArchHelpers::Context::SetArmReg(UContext, 0, EFAULT);
ArchHelpers::Context::SetPc(UContext, ArchHelpers::Context::GetArmReg(UContext, 30));
return true;
}

return false;
}
} // namespace FaultSafeUserMemAccess

} // namespace FEX::HLE
Expand Down

0 comments on commit dc35e23

Please sign in to comment.