feat(libkernel): implement madvise

This commit is contained in:
Hannah Lyons 2026-10-08 11:20:27 -04:00
parent c9da0f93cf
commit d7e52cb295
2 changed files with 29 additions and 0 deletions

View File

@ -1,6 +1,7 @@
#include "DirectMemory.hpp"
#include "SceTypes.hpp"
#include "prx/libc/include/general/VabiMacros.hpp"
#include "prx/libc/include/General.hpp"
#include <limits>
#include <new>
#include <stdexcept>
@ -19,6 +20,9 @@ constexpr int GuestPrivate = 0x2;
constexpr int GuestAnonymous = 0x1000;
constexpr int GuestSyncAsync = 0x1;
constexpr int GuestSyncInvalidate = 0x2;
constexpr int GuestAdviceCore = 9;
constexpr int GuestAdviceProtect = 10;
constexpr std::uintptr_t GuestUserAddressEnd = 0x800000000000;
bool RoundLength(std::size_t length, std::size_t& rounded) {
constexpr auto mask = PS5_PAGE_SIZE - 1;
@ -149,4 +153,14 @@ int APS5_VABI msync_nid_postfix(void* address, std::size_t length, int flags) {
return 0;
}
int APS5_VABI madvise_nid_postfix(void* address, std::size_t length, int advice) {
if (advice == GuestAdviceProtect) NotImplemented_nid_no_patch("madvise MADV_PROTECT");
const auto start = reinterpret_cast<std::uintptr_t>(address);
if (advice < 0 || advice > GuestAdviceCore || start > GuestUserAddressEnd || length > GuestUserAddressEnd - start) {
SetError(GuestInvalid);
return -1;
}
return 0;
}
}

View File

@ -37,6 +37,7 @@ extern "C" {
void* APS5_VABI mmap_nid_postfix(void*, std::size_t, int, int, int, std::int64_t) noexcept;
int APS5_VABI munmap_nid_postfix(void*, std::size_t) noexcept;
int APS5_VABI mprotect_nid_postfix(void*, std::size_t, int) noexcept;
int APS5_VABI madvise_nid_postfix(void*, std::size_t, int);
int* APS5_VABI __error_nid_postfix();
int APS5_VABI sceKernelMapNamedFlexibleMemory(void**, std::size_t, int, int, const char*);
int APS5_VABI sceKernelMapNamedFlexibleMemoryInternal(void**, std::size_t, int, int, const char*);
@ -1136,6 +1137,19 @@ int main() {
GuestAllocations::Mutation mutation;
Require(mutation.Find(memory).writable);
}
for (int advice = 0; advice <= 9; ++advice) Require(madvise_nid_postfix(memory, page * 3, advice) == 0);
Require(memory[0] == 42 && memory[page * 2] == 73);
Require(madvise_nid_postfix(memory + 1, 0, 4) == 0);
Require(madvise_nid_postfix(memory, page, 11) == -1 && *__error_nid_postfix() == 22);
*__error_nid_postfix() = 0;
Require(madvise_nid_postfix(memory, page, -1) == -1 && *__error_nid_postfix() == 22);
*__error_nid_postfix() = 0;
Require(madvise_nid_postfix(memory, 0, 11) == -1 && *__error_nid_postfix() == 22);
*__error_nid_postfix() = 0;
Require(madvise_nid_postfix(memory, std::numeric_limits<std::size_t>::max(), 0) == -1 && *__error_nid_postfix() == 22);
*__error_nid_postfix() = 0;
Require(madvise_nid_postfix(reinterpret_cast<void*>(0x800000000000), 1, 0) == -1 && *__error_nid_postfix() == 22);
Require(madvise_nid_postfix(reinterpret_cast<void*>(0x7fffffffc000), 0x4000, 4) == 0);
Require(munmap_nid_postfix(memory + 1, page) == -1 && *__error_nid_postfix() == 22);
Require(munmap_nid_postfix(memory, 0) == -1 && *__error_nid_postfix() == 22);
Require(memory[0] == 42);
@ -1145,6 +1159,7 @@ int main() {
Require(memory[page * 2] == 73);
Require(munmap_nid_postfix(memory + page * 2, page) == 0);
Require(munmap_nid_postfix(memory, page) == -1);
Require(madvise_nid_postfix(memory, page, 4) == 0);
*__error_nid_postfix() = 0;
Require(mprotect_nid_postfix(memory, page, 1) == -1 && *__error_nid_postfix() == 22);
*__error_nid_postfix() = 0;