use crate::util::constants::BYTES_IN_ADDRESS;
use crate::util::malloc::library::*;
use crate::util::Address;
use crate::vm::VMBinding;
pub fn align_alloc(size: usize, align: usize) -> Address {
let mut ptr = std::ptr::null_mut::<libc::c_void>();
let ptr_ptr = std::ptr::addr_of_mut!(ptr);
let result = unsafe { posix_memalign(ptr_ptr, align, size) };
if result != 0 {
return Address::ZERO;
}
let address = Address::from_mut_ptr(ptr);
crate::util::memory::zero(address, size);
address
}
pub fn align_offset_alloc<VM: VMBinding>(size: usize, align: usize, offset: usize) -> Address {
let actual_size = size + align + BYTES_IN_ADDRESS;
let raw = unsafe { calloc(1, actual_size) };
let address = Address::from_mut_ptr(raw);
if address.is_zero() {
return address;
}
let mod_offset = offset % align;
let mut result =
crate::util::alloc::allocator::align_allocation_no_fill::<VM>(address, align, mod_offset);
if result - BYTES_IN_ADDRESS < address {
result += align;
}
let malloc_res_ptr: *mut usize = (result - BYTES_IN_ADDRESS).to_mut_ptr();
unsafe { malloc_res_ptr.write_unaligned(address.as_usize()) };
result
}
pub fn offset_malloc_usable_size(address: Address) -> usize {
let malloc_res_ptr: *mut usize = (address - BYTES_IN_ADDRESS).to_mut_ptr();
let malloc_res = unsafe { malloc_res_ptr.read_unaligned() } as *mut libc::c_void;
unsafe { malloc_usable_size(malloc_res) }
}
pub fn offset_free(address: Address) {
let malloc_res_ptr: *mut usize = (address - BYTES_IN_ADDRESS).to_mut_ptr();
let malloc_res = unsafe { malloc_res_ptr.read_unaligned() } as *mut libc::c_void;
unsafe { free(malloc_res) };
}
pub use crate::util::malloc::library::free;
pub fn get_malloc_usable_size(address: Address, is_offset_malloc: bool) -> usize {
if is_offset_malloc {
offset_malloc_usable_size(address)
} else {
unsafe { malloc_usable_size(address.to_mut_ptr()) }
}
}
pub fn alloc<VM: VMBinding>(size: usize, align: usize, offset: usize) -> (Address, bool) {
let address: Address;
let mut is_offset_malloc = false;
if align <= 16 && offset == 0 {
let raw = unsafe { calloc(1, size) };
address = Address::from_mut_ptr(raw);
debug_assert!(address.is_aligned_to(align));
} else if align > 16 && offset == 0 {
address = align_alloc(size, align);
debug_assert!(
address.is_aligned_to(align),
"Address: {:x} is not aligned to the given alignment: {}",
address,
align
);
} else {
address = align_offset_alloc::<VM>(size, align, offset);
is_offset_malloc = true;
debug_assert!(
(address + offset).is_aligned_to(align),
"Address: {:x} is not aligned to the given alignment: {} at offset: {}",
address,
align,
offset
);
}
(address, is_offset_malloc)
}