CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
cdefs.h
1// Copyright Microsoft and CHERIoT Contributors.
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
6/*
7 * Testing against Clang-specific extensions.
8 */
9#ifndef __has_attribute
10# define __has_attribute(x) 0
11#endif
12#ifndef __has_extension
13# define __has_extension __has_feature
14#endif
15#ifndef __has_feature
16# define __has_feature(x) 0
17#endif
18#ifndef __has_include
19# define __has_include(x) 0
20#endif
21#ifndef __has_builtin
22# define __has_builtin(x) 0
23#endif
24
25/// Helper to use C++ in headers only in C++ mode.
26#ifdef __cplusplus
27# define __if_cxx(x) x
28# define __if_c(x)
29#else
30# define __if_cxx(x)
31# define __if_c(x) x
32#endif
33
34/// Allow the C99 spelling of bool in C++
35#ifdef __cplusplus
36using _Bool = bool;
37#endif
38
39#if defined(__cplusplus)
40# define __BEGIN_DECLS \
41 extern "C" \
42 {
43# define __END_DECLS }
44# define __DECL extern "C"
45#else
46# define __BEGIN_DECLS
47# define __END_DECLS
48# define __DECL
49#endif
50
51#define __weak_symbol __attribute__((weak))
52#define __dead2 __attribute__((noreturn))
53#define __pure2 __attribute__((const))
54#define __noinline __attribute__((noinline))
55#define __always_inline __attribute__((always_inline))
56#define __unused __attribute__((unused))
57#define __used __attribute__((used))
58#define __packed __attribute__((packed))
59#define __aligned(x) __attribute__((aligned(x)))
60#define __section(x) __attribute__((section(x)))
61#define __alloc_size(x) __attribute__((alloc_size(x)))
62#define __alloc_align(x) __attribute__((alloc_align(x)))
63#if __has_attribute(cheriot_minimum_stack)
64# define __cheriot_minimum_stack(x) __attribute__((cheriot_minimum_stack(x)))
65#else
66# warning \
67 "cheriot_minimum_stack attribute not supported, please update your compiler"
68# define __cheriot_minimum_stack(x)
69#endif
70#define __cheri_no_subobject_bounds __attribute__((cheri_no_subobject_bounds))
71
72// When running clang-tidy, we use the same compile flags for everything and so
73// will get errors about things being defined in the wrong compartment, so
74// define away the compartment name and pretend everything is local for now.
75#if defined(CLANG_TIDY) || defined(__CHERIOT_BAREMETAL__)
76# define __cheri_compartment(x)
77# define __cheriot_compartment(x)
78#else
79# if __has_attribute(cheriot_compartment)
80# define __cheri_compartment(x) __attribute__((cheriot_compartment(x)))
81# define __cheriot_compartment(x) __attribute__((cheriot_compartment(x)))
82# else
83# define __cheri_compartment(x) __attribute__((cheri_compartment(x)))
84# define __cheriot_compartment(x) __attribute__((cheri_compartment(x)))
85# endif
86#endif
87
88// Define the CHERIoT calling-convention attributes macros to nothing if we're
89// targeting bare metal and to the correct attributes if we're targeting the
90// RTOS.
91#ifdef __CHERIOT_BAREMETAL__
92# define __cheri_libcall
93# define __cheriot_libcall
94# define __cheri_callback
95# define __cheriot_callback
96#else
97# if __has_attribute(cheriot_libcall)
98# define __cheri_libcall __attribute__((cheriot_libcall))
99# define __cheriot_libcall __attribute__((cheriot_libcall))
100# else
101# define __cheri_libcall __attribute__((cheri_libcall))
102# define __cheriot_libcall __attribute__((cheri_libcall))
103# endif
104# if __has_attribute(cheriot_libcall)
105# define __cheri_callback __attribute__((cheriot_ccallback))
106# define __cheriot_callback __attribute__((cheriot_ccallback))
107# else
108# define __cheri_callback __attribute__((cheri_ccallback))
109# define __cheriot_callback __attribute__((cheri_ccallback))
110# endif
111#endif
112
113#define offsetof(a, b) __builtin_offsetof(a, b)
114
115#define __predict_true(exp) __builtin_expect((exp), 1)
116#define __predict_false(exp) __builtin_expect((exp), 0)
117
118#define __XSTRING(a) __STRING(a)
119#define __STRING(a) #a
120/// Inner implementation for `__pragma`
121#define __pragma_helper(x) _Pragma(#x)
122/// Helper that allows pragma strings to be constructed with concatenation
123#define __pragma(x) __pragma_helper(x)
124
125#ifdef __clang__
126/**
127 * Helper that pushes the diagnostic stack and adds the argument (specified as
128 * a string, of the form "-W{warning}") to the ignored list.
129 */
130# define __clang_ignored_warning_push(x) \
131 _Pragma("clang diagnostics push") __pragma(clang diagnostic ignored x)
132/**
133 * Undoes the most recent `__clang_ignored_warning_push`.
134 */
135# define __clang_ignored_warning_pop() _Pragma("clang diagnostics pop")
136#else
137# define __clang_ignored_warning_push(x)
138# define __clang_ignored_warning_pop()
139#endif
140
141#if defined(CHERIOT_EXPERIMENTAL_APIS_WARN)
142# define CHERIOT_EXPERIMENTAL(msg) __attribute__((deprecated(msg)))
143#else
144# define CHERIOT_EXPERIMENTAL(msg)
145#endif
146
147#if !defined(CLANG_TIDY) && !__has_builtin(__builtin_cheri_top_get)
148# error Your compiler is too old for this version of CHERIoT RTOS, please upgrade to a newer version
149#endif
150
151#if (defined(__CHERIOT__) && __CHERIOT__ < 20250113) || \
152 (defined(__CHERIOT_BAREMETAL__) && __CHERIOT_BAREMETAL__ < 20250113)
153# error Your compiler is too old for this version of CHERIoT RTOS, please upgrade to a newer version
154#endif
155
156#define CHERIOT_VERSION_TRIPLE(major, minor, patch) \
157 ((major * 10000) + (minor * 100) + (patch))
158
159/**
160 * Helper for declaring standard library functions that should be exported
161 * as __cheri_libcall, but which should not have their names mangled. This
162 * is needed to enable LLVM optimizations to trigger on standard library
163 * functions.
164 */
165#define CHERIOT_DECLARE_STANDARD_LIBCALL(name, ret, ...) \
166 __cheri_libcall ret name(__VA_ARGS__) __asm__(#name);