Implemented sceKernelMTypeProtect and sceKernelMProtect (#387)

* Fixed ORBIS_KERNEL_MAP_OP_TYPE_PROTECT for batchmap2

* Fix merge

* Changed 4 to ORBIS_KERNEL_MAP_OP_TYPE_PROTECT

* Removed MProtect from AddressSpace

* Added Mtyprotect and moved Mprotect to ORBIS_KERNEL_MAP_OP_PROTECT

* Changed Protect for Windows

* reverted the previous function

* Fixed Mtypeprotect and MProtect

* ''

* ''

* Took out logs stopping build

* clang-format issues

* Fixed the order of mtypeprotect and mprotect in batchmap2

* ''

* update branch

* ''

* Fixed nits

* ''

* Update submodules to latest commits

* ''

* reverted ffmpeg

* ''

* Fixed the nits

* ''

* ''

* ''

* ''

* ''

* Fix clang formatting, DEBUG_ASSERT, and extra spacing

* Fix build issues

* Revert "Fix build issues"

This reverts commit 9185f96ec9.

* ''

* ''

* ''

* Changes for MemoryProt Format

* ''

* ''

* ''
This commit is contained in:
menaman123 2024-09-04 16:36:23 -04:00 committed by GitHub
parent 0dd6e257c5
commit b9c6093717
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 202 additions and 25 deletions

View file

@ -15,6 +15,7 @@
#include <fcntl.h>
#include <sys/mman.h>
#endif
#include "libraries/error_codes.h"
#ifdef __APPLE__
// Reserve space for the system address space using a zerofill section.
@ -231,27 +232,36 @@ struct AddressSpace::Impl {
void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) {
DWORD new_flags{};
if (read && write) {
if (read && write && execute) {
new_flags = PAGE_EXECUTE_READWRITE;
} else if (read && write) {
new_flags = PAGE_READWRITE;
} else if (read && !write) {
new_flags = PAGE_READONLY;
} else if (!read && !write) {
} else if (execute && !read && not write) {
new_flags = PAGE_EXECUTE;
} else if (!read && !write && !execute) {
new_flags = PAGE_NOACCESS;
} else {
UNIMPLEMENTED_MSG("Protection flag combination read={} write={}", read, write);
LOG_CRITICAL(Common_Memory,
"Unsupported protection flag combination for address {:#x}, size {}",
virtual_addr, size);
return;
}
const VAddr virtual_end = virtual_addr + size;
auto [it, end] = placeholders.equal_range({virtual_addr, virtual_end});
while (it != end) {
const size_t offset = std::max(it->lower(), virtual_addr);
const size_t protect_length = std::min(it->upper(), virtual_end) - offset;
DWORD old_flags{};
if (!VirtualProtect(virtual_base + offset, protect_length, new_flags, &old_flags)) {
LOG_CRITICAL(Common_Memory, "Failed to change virtual memory protect rules");
}
++it;
DWORD old_flags{};
bool success =
VirtualProtect(reinterpret_cast<void*>(virtual_addr), size, new_flags, &old_flags);
if (!success) {
LOG_ERROR(Common_Memory,
"Failed to change virtual memory protection for address {:#x}, size {}",
virtual_addr, size);
}
// Use assert to ensure success in debug builds
DEBUG_ASSERT(success && "Failed to change virtual memory protection");
}
HANDLE process{};
@ -493,7 +503,10 @@ void AddressSpace::Unmap(VAddr virtual_addr, size_t size, VAddr start_in_vma, VA
}
void AddressSpace::Protect(VAddr virtual_addr, size_t size, MemoryPermission perms) {
return impl->Protect(virtual_addr, size, true, true, true);
const bool read = True(perms & MemoryPermission::Read);
const bool write = True(perms & MemoryPermission::Write);
const bool execute = True(perms & MemoryPermission::Execute);
return impl->Protect(virtual_addr, size, read, write, execute);
}
} // namespace Core