/* * Copyright (c) 2023 Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #pragma once #include #include "perms.h" /** * Returns length of a capability: * length = limit - base * Length of a NULL capability is returned as 0. */ size_t cheri_length_get_zero(const void * __capability cap); /** * Returns limit of the capability as a pointer. * Note that limit for a NULL pointer is returned as NULL. */ const void * __capability cheri_get_limit(const void * __capability cap); /** * Returns difference between the address and the limit * of a capability: tail = limit - (base + offset) if this * capability is in bounds, otherwise, returns NULL. */ size_t cheri_get_tail(const void * __capability cap); /** * Returns true if capability is in bounds. */ bool cheri_in_bounds(const void * __capability cap); /** * Returns true if a capability is dereferenceable: * capability's tag is set, it is not sealed and it * is in bounds. */ bool cheri_is_deref(const void * __capability cap); /** * Returns true if capability is local. */ bool cheri_is_local(const void * __capability cap); /** * Convert capability into string representation. * If dst is NULL, a pointer to a static object is returned. * Using it may be unsafe. */ const char *cap_to_str(char *dst, const void * __capability cap); const char *cap_perms_to_str(char *dst, const void * __capability cap); const char *cap_seal_to_str(char *dst, const void * __capability cap); #if defined(__GNUC__) && !defined(__clang__) && defined(__CHERI__) // GCC does not provide this builtin. inline static void * __capability __builtin_cheri_stack_get() { void * __capability ret; __asm__ volatile ("mov %0, csp" : "=C"(ret)); return ret; } #endif #ifndef cheri_csp_get #define cheri_csp_get() __builtin_cheri_stack_get() #endif /** * Access CID register. */ inline static void * __capability __builtin_cheri_cid_get() { void * __capability ret; __asm__ volatile ("mrs %0, CID_EL0" : "=C"(ret)); return ret; } #ifndef cheri_cid_get #define cheri_cid_get() __builtin_cheri_cid_get() #endif /** * Create LPB-sealed sentry. */ inline static void * __capability morello_lpb_sentry_create(void *cap) { void * __capability ret; __asm__ ("seal %0, %1, lpb" : "=C"(ret) : "C"(cap)); return ret; } /** * Create LB-sealed sentry. */ inline static void * __capability morello_lb_sentry_create(void *cap) { void * __capability ret; __asm__ ("seal %0, %1, lb" : "=C"(ret) : "C"(cap)); return ret; } /** * Checks if given permissions are present in the capability. */ inline static bool cheri_check_perms(const void * __capability cap, size_t perms) { return (cheri_perms_get(cap) | ~perms) == ~0; } #ifndef cheri_copy_from_high #define cheri_copy_from_high(cap) __builtin_cheri_copy_from_high(cap) #endif