//
// hardened-malloc-sys: Rust bindings for GrapheneOS allocator
// src/lib.rs: Extern definitions for allocator functions
//
// Copyright (c) 2025 Ali Polatel <alip@chesswob.org>
// Based in part upon hardened_malloc-rs/src/bindings.rs which is
//   Copyright (c) strawberry <strawberry@puppygock.gay>
//   SPDX-License-Identifier: Apache-2.0 OR MIT
//
// SPDX-License-Identifier: MIT

#![no_std]

use core::ffi::{c_int, c_void};

// ideally we would use c_size_t but it's unstable

#[allow(dead_code)]
extern "C" {
    /* C standard */
    pub fn malloc(size: usize) -> *mut c_void;
    pub fn calloc(nmemb: usize, size: usize) -> *mut c_void;
    pub fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void;
    pub fn aligned_alloc(alignment: usize, size: usize) -> *mut c_void;
    pub fn free(ptr: *mut c_void);

    /* POSIX */
    pub fn posix_memalign(memptr: *mut *mut c_void, alignment: usize, size: usize) -> c_int;

    /* hardened_malloc extensions */
    /// return an upper bound on object size for any pointer based on malloc
    /// metadata
    pub fn malloc_object_size(ptr: *const c_void) -> usize;

    /// similar to malloc_object_size, but avoiding locking so the results are
    /// much more limited
    pub fn malloc_object_size_fast(ptr: *const c_void) -> usize;

    /// The free function with an extra parameter for passing the size requested
    /// at allocation time.
    ///
    /// This offers the same functionality as C++14 sized deallocation and can
    /// be used to implement it.
    ///
    /// A performance-oriented allocator would use this as a performance
    /// enhancement with undefined behavior on a mismatch. Instead, this
    /// hardened allocator implementation uses it to improve security by
    /// checking that the passed size matches the allocated size.
    pub fn free_sized(ptr: *mut c_void, expected_size: usize) -> c_void;
}
