Files
FEX-Emu--FEX/Source/Tools/LinuxEmulation/LinuxSyscalls/FaultSafeMemcpy.cpp
T
Paulo Matos 2b4ec88dae Whole-tree reformat
This follows discussions from #3413.
Followup commits add clang-format file, script and blame ignore lists.
2024-04-12 16:26:02 +02:00

70 lines
1.6 KiB
C++

// SPDX-License-Identifier: MIT
#include "LinuxSyscalls/Syscalls.h"
namespace FEX::HLE::FaultSafeMemcpy {
#ifdef _M_ARM_64
__attribute__((naked)) size_t CopyFromUser(void* Dest, const void* Src, size_t Size) {
__asm volatile(R"(
// Early exit if a memcpy of size zero.
cbz x2, 2f;
1:
.globl CopyFromUser_FaultInst
CopyFromUser_FaultInst:
ldrb w3, [x1], 1; // <- This line can fault.
strb w3, [x0], 1;
sub x2, x2, 1;
cbnz x2, 1b;
2:
mov x0, 0;
ret;
)" ::
: "memory");
}
__attribute__((naked)) size_t CopyToUser(void* Dest, const void* Src, size_t Size) {
__asm volatile(R"(
// Early exit if a memcpy of size zero.
cbz x2, 2f;
1:
ldrb w3, [x1], 1;
.globl CopyToUser_FaultInst
CopyToUser_FaultInst:
strb w3, [x0], 1; // <- This line can fault.
sub x2, x2, 1;
cbnz x2, 1b;
2:
mov x0, 0;
ret;
)" ::
: "memory");
}
extern "C" uint64_t CopyFromUser_FaultInst;
void* const CopyFromUser_FaultLocation = &CopyFromUser_FaultInst;
extern "C" uint64_t CopyToUser_FaultInst;
void* const CopyToUser_FaultLocation = &CopyToUser_FaultInst;
bool IsFaultLocation(uint64_t PC) {
return reinterpret_cast<void*>(PC) == CopyFromUser_FaultLocation || reinterpret_cast<void*>(PC) == CopyToUser_FaultLocation;
}
#else
size_t CopyFromUser(void* Dest, const void* Src, size_t Size) {
memcpy(Dest, Src, Size);
return Size;
}
size_t CopyToUser(void* Dest, const void* Src, size_t Size) {
memcpy(Dest, Src, Size);
return Size;
}
bool IsFaultLocation(uint64_t PC) {
return false;
}
#endif
} // namespace FEX::HLE::FaultSafeMemcpy