69 lines
1.9 KiB
C++
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;
|
|
}
|
|
}
|