use std::{
alloc::{Layout, alloc, alloc_zeroed, realloc},
ffi::c_void,
ptr,
sync::atomic::{AtomicPtr, Ordering},
};
use crate::{
api::tee_api_panic::TEE_Panic,
tee_api_defines::{TEE_MALLOC_FILL_ZERO, TEE_MALLOC_NO_FILL, TEE_MALLOC_NO_SHARE, TEE_SUCCESS},
tee_api_types::TEE_Result,
};
static TEE_API_INSTANCE_DATA: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
pub const TEE_NULL_SIZED_VA: *mut c_void = 1 as *mut c_void;
pub const TEE_NULL_SIZED_NO_SHARE_VA: *mut c_void = 2 as *mut c_void;
pub const TEE_USER_MEM_HINT_NO_FILL_ZERO: u32 = 0x80000000;
#[unsafe(no_mangle)]
pub extern "C" fn TEE_CheckMemoryAccessRights(
_accessFlags: u32,
_buffer: *mut c_void,
_size: usize,
) -> TEE_Result {
TEE_SUCCESS
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_SetInstanceData(instanceData: *const c_void) {
TEE_API_INSTANCE_DATA.store(instanceData as _, Ordering::Release);
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_GetInstanceData() -> *const c_void {
TEE_API_INSTANCE_DATA.load(Ordering::Acquire)
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_Malloc(size: usize, hint: u32) -> *mut c_void {
let layout = match Layout::from_size_align(size, std::mem::align_of::<u8>()) {
Ok(layout) => layout,
Err(_) => return ptr::null_mut(),
};
match hint {
TEE_MALLOC_FILL_ZERO => {
if size == 0 {
return TEE_NULL_SIZED_VA;
}
unsafe { alloc_zeroed(layout) as _ }
}
TEE_MALLOC_NO_FILL => {
TEE_Panic(0);
ptr::null_mut()
}
TEE_MALLOC_NO_SHARE => {
if size == 0 {
return TEE_NULL_SIZED_NO_SHARE_VA;
}
unsafe { alloc_zeroed(layout) as _ }
}
hint if hint == TEE_MALLOC_NO_FILL | TEE_MALLOC_NO_SHARE => {
if size == 0 {
return TEE_NULL_SIZED_NO_SHARE_VA;
}
unsafe { alloc(layout) as _ }
}
TEE_USER_MEM_HINT_NO_FILL_ZERO => {
if size == 0 {
return TEE_NULL_SIZED_VA;
}
unsafe { alloc(layout) as _ }
}
_ => {
eprintln!("Invalid hint: 0x{:x}", hint);
ptr::null_mut()
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_Realloc(buffer: *mut c_void, newSize: usize) -> *mut c_void {
let layout = match Layout::from_size_align(newSize, std::mem::align_of::<u8>()) {
Ok(layout) => layout,
Err(_) => return ptr::null_mut(),
};
if newSize == 0 {
TEE_Free(buffer);
}
unsafe { realloc(buffer as _, layout, newSize) as _ }
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_Free(buffer: *mut c_void) {
unsafe { libc::free(buffer) }
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MemMove(dest: *mut c_void, src: *const c_void, size: usize) {
unsafe { libc::memmove(dest, src, size) };
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MemCompare(
_buffer1: *const c_void,
_buffer2: *const c_void,
_size: usize,
) -> i32 {
-1
}
#[unsafe(no_mangle)]
pub extern "C" fn TEE_MemFill(buff: *mut c_void, x: u32, size: usize) {
unsafe { libc::memset(buff, x as _, size) };
}