mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-19 18:36:53 +02:00
Fix macOS aggregate test build (#536)
* tests: add Darwin memory test support * tests: fix x86_64 aggregate test build * tests: verify macOS memory and shader tests * tests: validate macOS death-test setup before fork --------- Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
@@ -16,6 +16,15 @@
|
||||
#include <windows.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#elif defined(__APPLE__)
|
||||
#include <limits.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <map>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <map>
|
||||
#include <sys/mman.h>
|
||||
@@ -56,6 +65,26 @@ int ToHostProt(uint32_t protection) {
|
||||
}
|
||||
|
||||
uint32_t Protection(const void *address) {
|
||||
#if defined(__APPLE__)
|
||||
mach_vm_address_t region_address =
|
||||
reinterpret_cast<mach_vm_address_t>(address);
|
||||
mach_vm_size_t region_size = 0;
|
||||
vm_region_basic_info_data_64_t info{};
|
||||
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
|
||||
mach_port_t object_name = MACH_PORT_NULL;
|
||||
Check(mach_vm_region(mach_task_self(), ®ion_address, ®ion_size,
|
||||
VM_REGION_BASIC_INFO_64,
|
||||
reinterpret_cast<vm_region_info_t>(&info), &info_count,
|
||||
&object_name) == KERN_SUCCESS,
|
||||
"mach_vm_region failed");
|
||||
if (object_name != MACH_PORT_NULL) {
|
||||
mach_port_deallocate(mach_task_self(), object_name);
|
||||
}
|
||||
return (info.protection & VM_PROT_WRITE) != 0
|
||||
? PAGE_READWRITE
|
||||
: (info.protection & VM_PROT_READ) != 0 ? PAGE_READONLY
|
||||
: PAGE_NOACCESS;
|
||||
#else
|
||||
const auto addr = reinterpret_cast<uintptr_t>(address);
|
||||
std::FILE *maps = std::fopen("/proc/self/maps", "r");
|
||||
Check(maps != nullptr, "open /proc/self/maps failed");
|
||||
@@ -77,6 +106,7 @@ uint32_t Protection(const void *address) {
|
||||
}
|
||||
std::fclose(maps);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::map<void *, size_t> &AllocationSizes() {
|
||||
@@ -90,7 +120,15 @@ int VirtualFree(void *address, size_t, DWORD) {
|
||||
if (it == sizes.end()) {
|
||||
return 0;
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
const int ok = mach_vm_deallocate(mach_task_self(),
|
||||
reinterpret_cast<mach_vm_address_t>(address),
|
||||
it->second) == KERN_SUCCESS
|
||||
? 1
|
||||
: 0;
|
||||
#else
|
||||
const int ok = ::munmap(address, it->second) == 0 ? 1 : 0;
|
||||
#endif
|
||||
sizes.erase(it);
|
||||
return ok;
|
||||
}
|
||||
@@ -100,7 +138,16 @@ int VirtualProtect(void *address, size_t size, uint32_t protection,
|
||||
if (old_protection != nullptr) {
|
||||
*old_protection = Protection(address);
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
return mach_vm_protect(mach_task_self(),
|
||||
reinterpret_cast<mach_vm_address_t>(address), size,
|
||||
false, static_cast<vm_prot_t>(ToHostProt(protection))) ==
|
||||
KERN_SUCCESS
|
||||
? 1
|
||||
: 0;
|
||||
#else
|
||||
return ::mprotect(address, size, ToHostProt(protection)) == 0 ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
uint32_t Protection(const void *address) {
|
||||
@@ -144,6 +191,16 @@ uint8_t *Allocate(uint64_t size, uint32_t protection = PAGE_READWRITE,
|
||||
MEM_RESERVE | MEM_COMMIT, protection));
|
||||
Check(memory == reinterpret_cast<void *>(test_address),
|
||||
"fixed low VirtualAlloc failed");
|
||||
#elif defined(__APPLE__)
|
||||
mach_vm_address_t raw = test_address;
|
||||
Check(mach_vm_allocate(mach_task_self(), &raw, size, VM_FLAGS_FIXED) ==
|
||||
KERN_SUCCESS &&
|
||||
mach_vm_protect(mach_task_self(), raw, size, false,
|
||||
static_cast<vm_prot_t>(ToHostProt(protection))) ==
|
||||
KERN_SUCCESS,
|
||||
"fixed low mach_vm_allocate failed");
|
||||
auto *memory = reinterpret_cast<uint8_t *>(raw);
|
||||
AllocationSizes()[memory] = static_cast<size_t>(size);
|
||||
#else
|
||||
void *raw = ::mmap(reinterpret_cast<void *>(test_address), size,
|
||||
ToHostProt(protection),
|
||||
@@ -540,10 +597,23 @@ void CheckDeathCase(const char *name) {
|
||||
CloseHandle(process.hThread);
|
||||
CloseHandle(process.hProcess);
|
||||
#else
|
||||
#if defined(__APPLE__)
|
||||
std::vector<char> path(PATH_MAX);
|
||||
uint32_t path_size = static_cast<uint32_t>(path.size());
|
||||
if (_NSGetExecutablePath(path.data(), &path_size) != 0) {
|
||||
path.resize(path_size);
|
||||
Check(_NSGetExecutablePath(path.data(), &path_size) == 0,
|
||||
"_NSGetExecutablePath failed");
|
||||
}
|
||||
#endif
|
||||
const pid_t pid = ::fork();
|
||||
Check(pid >= 0, "fork failed");
|
||||
if (pid == 0) {
|
||||
#if defined(__APPLE__)
|
||||
::execl(path.data(), "PageManagerTests", "--death", name, nullptr);
|
||||
#else
|
||||
::execl("/proc/self/exe", "PageManagerTests", "--death", name, nullptr);
|
||||
#endif
|
||||
std::_Exit(0x7e);
|
||||
}
|
||||
int status = 0;
|
||||
|
||||
Reference in New Issue
Block a user