Files
MontaukOS/kernel/src/Api/UserMemory.hpp
T

69 lines
1.9 KiB
C++

#pragma once
#include <cstddef>
#include <cstdint>
#include <Sched/Scheduler.hpp>
#include <Memory/Paging.hpp>
namespace montauk::abi::UserMemory {
static constexpr uint64_t USER_SPACE_END = 0x0000800000000000ULL;
inline bool IsUserPtr(uint64_t addr) {
return addr == 0 || addr < USER_SPACE_END;
}
inline bool ValidUserPtr(uint64_t addr) {
return addr != 0 && addr < USER_SPACE_END;
}
inline uint64_t CurrentPml4() {
auto* proc = Sched::GetCurrentProcessPtr();
return proc ? proc->pml4Phys : 0;
}
inline bool Range(uint64_t addr, uint64_t size, bool requireWrite = false) {
if (size == 0) return true;
if (!ValidUserPtr(addr)) return false;
if (addr + size < addr) return false;
if (addr + size > USER_SPACE_END) return false;
uint64_t pml4Phys = CurrentPml4();
if (pml4Phys == 0) return false;
return Memory::VMM::Paging::IsUserRangeAccessible(pml4Phys, addr, size, requireWrite);
}
inline bool OptionalRange(uint64_t addr, uint64_t size, bool requireWrite = false) {
return addr == 0 || Range(addr, size, requireWrite);
}
template<typename T>
inline bool Readable(uint64_t addr) {
return Range(addr, sizeof(T), false);
}
template<typename T>
inline bool Writable(uint64_t addr) {
return Range(addr, sizeof(T), true);
}
inline bool String(uint64_t addr, uint64_t maxLen) {
if (!ValidUserPtr(addr) || maxLen == 0) return false;
uint64_t pml4Phys = CurrentPml4();
if (pml4Phys == 0) return false;
const char* str = (const char*)addr;
for (uint64_t i = 0; i < maxLen; i++) {
if (!Memory::VMM::Paging::IsUserRangeAccessible(pml4Phys, addr + i, 1, false)) {
return false;
}
if (str[i] == '\0') return true;
}
return false;
}
}