#[derive(Debug)]
pub struct AllocFailed;
impl std::error::Error for AllocFailed {}
use std::fmt;
impl fmt::Display for AllocFailed {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Alloc failed")
}
}
#[cfg(target_os = "windows")]
pub mod p {
use super::AllocFailed;
use windows_sys::Win32::System::Memory::{VirtualAlloc2, MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE, PAGE_NOACCESS};
const MEM_64K_PAGES: u32 = 0x20400000;
use windows_sys::Win32::Foundation::GetLastError;
use core::ffi::c_void;
use core::ptr::null_mut;
pub const SC_FOR_PAGE: u8 = crate::reqali_to_sc(65_536, 65_536);
#[allow(unsafe_code)]
pub fn sys_alloc(reqsize: usize) -> Result<*mut u8, AllocFailed> {
let p = unsafe {
VirtualAlloc2(null_mut(), std::ptr::null(), reqsize, MEM_RESERVE, PAGE_NOACCESS, null_mut(), 0)
};
if !p.is_null() {
Ok(p as *mut u8)
} else {
let error = unsafe { GetLastError() };
eprintln!("VirtualAlloc reserve failed with error code: {}", error);
Err(AllocFailed)
}
}
#[allow(unsafe_code)]
pub fn sys_commit(pin: *mut u8, reqsize: usize) -> Result<*mut u8, AllocFailed> {
let pout = unsafe {
VirtualAlloc2(null_mut(), pin as *mut c_void, reqsize, MEM_COMMIT | MEM_64K_PAGES, PAGE_READWRITE, null_mut(), 0)
};
if !pout.is_null() {
Ok(pout as *mut u8)
} else {
let error = unsafe { GetLastError() };
println!("VirtualAlloc commit failed with error code: {}", error);
Err(AllocFailed)
}
}
}
#[cfg(target_os = "linux")]
pub mod p {
use super::AllocFailed;
use rustix::mm::{MapFlags, ProtFlags, mmap_anonymous};
use std::ptr;
pub const SC_FOR_PAGE: u8 = crate::reqali_to_sc(4096, 4096);
#[allow(unsafe_code)]
pub fn sys_alloc(reqsize: usize) -> Result<*mut u8, AllocFailed> {
match unsafe {
mmap_anonymous(ptr::null_mut(), reqsize, ProtFlags::READ | ProtFlags::WRITE, MapFlags::PRIVATE | MapFlags::NORESERVE)
} {
Ok(p) => Ok(p as *mut u8),
Err(_) => Err(AllocFailed),
}
}
}
#[cfg(target_vendor = "apple")]
pub mod p {
use super::AllocFailed;
use mach_sys::kern_return::KERN_SUCCESS;
use mach_sys::port::mach_port_t;
use mach_sys::traps::mach_task_self;
use mach_sys::vm::mach_vm_allocate;
use mach_sys::vm_statistics::VM_FLAGS_ANYWHERE;
use mach_sys::vm_types::{mach_vm_address_t, mach_vm_size_t};
pub const SC_FOR_PAGE: u8 = crate::reqali_to_sc(16_384, 16_384);
#[allow(unsafe_code)]
pub fn sys_alloc(size: usize) -> Result<*mut u8, AllocFailed> {
let task: mach_port_t = unsafe { mach_task_self() };
let mut address: mach_vm_address_t = 0;
let size: mach_vm_size_t = size as mach_vm_size_t;
let retval;
unsafe {
retval = mach_vm_allocate(task, &mut address, size, VM_FLAGS_ANYWHERE);
}
if retval == KERN_SUCCESS {
Ok(address as *mut u8)
} else {
Err(AllocFailed)
}
}
}