CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Toggle main menu visibility
Loading...
Searching...
No Matches
sdk
include
__compartment-macros.h
Go to the documentation of this file.
1
// Copyright Microsoft and CHERIoT Contributors.
2
// SPDX-License-Identifier: MIT
3
4
#pragma once
5
#include <__cheri_sealed.h>
6
#include <cdefs.h>
7
#include <stdbool.h>
8
9
/**
10
* \file
11
*
12
* Helper macros used by compartment-macros.h.
13
*
14
* Do not use any of the macros in this file directly.
15
*
16
* These are separated to make the documentation of compartment-macros.h
17
* cleaner.
18
*/
19
20
/**
21
* \internal
22
*
23
* Helper macro for MMIO and pre-shared object imports, should not be used
24
* directly.
25
*/
26
#define IMPORT_CAPABILITY_WITH_PERMISSIONS_HELPER(type, \
27
name, \
28
prefix, \
29
mangledName, \
30
permitLoad, \
31
permitStore, \
32
permitLoadStoreCapabilities, \
33
permitLoadMutable, \
34
permitLoadGlobal) \
35
({ \
36
type *ret;
/* NOLINT(bugprone-macro-parentheses) */
\
37
__asm(".ifndef " mangledName "\n" \
38
" .type " mangledName ",@object\n" \
39
" .section .compartment_imports." #name \
40
",\"awG\",@progbits," mangledName ",comdat\n" \
41
" .globl " mangledName "\n" \
42
" .p2align 3\n" mangledName ":\n" \
43
" .word " #prefix #name "\n" \
44
" .word " #prefix #name "_end - " #prefix #name " + %c1\n" \
45
" .size " mangledName ", 8\n" \
46
" .previous\n" \
47
".endif\n" \
48
"1:" \
49
" auipcc %0," \
50
" %%cheriot_compartment_hi(" mangledName ")\n" \
51
" clc %0, %%cheriot_compartment_lo_i(1b)(%0)\n" \
52
: "=C"(ret) \
53
: "i"(((permitLoad) ? (1 << 31) : 0) + \
54
((permitStore) ? (1 << 30) : 0) + \
55
((permitLoadStoreCapabilities) ? (1 << 29) : 0) + \
56
((permitLoadMutable) ? (1 << 28) : 0) + \
57
((permitLoadGlobal) ? (1 << 27) : 0))); \
58
ret; \
59
})
60
61
// NOLINTBEGIN
62
#define CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG_true(flag) flag
63
#define CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG_1(flag) flag
64
#define CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG_false(flag) ""
65
#define CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG_0(flag) ""
66
67
#define CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG(cond, flag) \
68
CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG_##cond(flag)
69
// NOLINTEND
70
71
#define CHERIOT_COMPARTMENT_MACROS_JOIN_FLAGS(pL, pS, pC, pM, pG) \
72
CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG(pL, "R") \
73
CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG(pS, "W") \
74
CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG(pC, "c") \
75
CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG(pM, "m") \
76
CHERIOT_COMPARTMENT_MACROS_PERMIT_FLAG(pG, "g")
77
78
#define CHERIOT_COMPARTMENT_MACROS_TOKEN_PASTE_INNER(x, y) x##y
79
#define CHERIOT_COMPARTMENT_MACROS_TOKEN_PASTE(x, y) \
80
CHERIOT_COMPARTMENT_MACROS_TOKEN_PASTE_INNER(x, y)
81
82
#if defined(__has_attribute) && __has_attribute(cheriot_mmio)
83
/**
84
* \internal
85
*
86
* Helper for `MMIO_CAPABILITY_WITH_PERMISSIONS_` that forces evaluation of the
87
* `__COUNTER__` macro.
88
*/
89
# define MMIO_CAPABILITY_WITH_PERMISSIONS_INNER( \
90
type, \
91
name, \
92
permitLoad, \
93
permitStore, \
94
permitLoadStoreCapabilities, \
95
permitLoadMutable, \
96
permitLoadGlobal, \
97
cValue) \
98
({ \
99
/* NOLINTBEGIN(bugprone-macro-parentheses) */
\
100
_Static_assert(permitLoad || permitStore, \
101
"Importing an MMIO capability with no permissions " \
102
"is not allowed."); \
103
_Pragma("GCC diagnostic push") \
104
_Pragma("GCC diagnostic ignored \"-Wundefined-internal\"") \
105
__attribute__((cheri_no_subobject_bounds)) \
106
__attribute__((cheriot_mmio( \
107
#name, \
108
CHERIOT_COMPARTMENT_MACROS_JOIN_FLAGS( \
109
permitLoad, \
110
permitStore, \
111
permitLoadStoreCapabilities, \
112
permitLoadMutable, \
113
permitLoadGlobal)))) volatile extern char cValue; \
114
(type *)&cValue; \
115
_Pragma("GCC diagnostic pop") \
116
/* NOLINTEND(bugprone-macro-parentheses) */
\
117
})
118
#else
119
/**
120
* \internal
121
*
122
* Helper macro, should not be used directly.
123
*/
124
# define MMIO_CAPABILITY_WITH_PERMISSIONS_HELPER( \
125
type, \
126
name, \
127
mangledName, \
128
permitLoad, \
129
permitStore, \
130
permitLoadStoreCapabilities, \
131
permitLoadMutable, \
132
permitLoadGlobal) \
133
IMPORT_CAPABILITY_WITH_PERMISSIONS_HELPER(type, \
134
name, \
135
__export_mem_, \
136
mangledName, \
137
permitLoad, \
138
permitStore, \
139
permitLoadStoreCapabilities, \
140
permitLoadMutable, \
141
permitLoadGlobal)
142
143
#endif
144
145
#if defined(__has_attribute) && __has_attribute(cheriot_shared_object)
146
/**
147
* \internal
148
*
149
* Helper for implementing `SHARED_OBJECT_WITH_PERMISSIONS`, expanding the
150
* definition of `__COUNTER__`, passed as the final macro parameter.
151
*/
152
# define SHARED_OBJECT_WITH_PERMISSIONS_INNER(type, \
153
name, \
154
permitLoad, \
155
permitStore, \
156
permitLoadStoreCapabilities, \
157
permitLoadMutable, \
158
permitLoadGlobal, \
159
cValue) \
160
({ \
161
/* NOLINTBEGIN(bugprone-macro-parentheses) */
\
162
_Static_assert( \
163
permitLoad || permitStore, \
164
"Importing a shared object capability with no permissions " \
165
"is not allowed."); \
166
_Pragma("GCC diagnostic push") \
167
_Pragma("GCC diagnostic ignored \"-Wundefined-internal\"") \
168
__attribute__((cheri_no_subobject_bounds)) \
169
__attribute__((cheriot_shared_object( \
170
#name, \
171
CHERIOT_COMPARTMENT_MACROS_JOIN_FLAGS( \
172
permitLoad, \
173
permitStore, \
174
permitLoadStoreCapabilities, \
175
permitLoadMutable, \
176
permitLoadGlobal)))) extern char cValue; \
177
(type *)&cValue; \
178
_Pragma("GCC diagnostic pop") \
179
/* NOLINTEND(bugprone-macro-parentheses) */
\
180
})
181
#endif
182
183
/**
184
* \internal
185
*
186
* Helper macro, used by `STATIC_SEALING_TYPE`. Do not use this
187
* directly, it exists to avoid error-prone copying and pasting
188
* of the mangled name for a static sealing type.
189
*/
190
#define CHERIOT_EMIT_STATIC_SEALING_TYPE(name) \
191
({ \
192
TokenKey ret;
/* NOLINT(bugprone-macro-parentheses) */
\
193
__asm( \
194
".ifndef __import." name "\n" \
195
" .type __import." name ",@object\n" \
196
" .section .compartment_imports." name ",\"awG\",@progbits," name \
197
",comdat\n" \
198
" .globl __import." name "\n" \
199
" .p2align 3\n" \
200
"__import." name ":\n" \
201
" .word __export." name "\n" \
202
" .word 0\n" \
203
" .previous\n" \
204
".endif\n" \
205
".ifndef __export." name "\n" \
206
" .type __export." name ",@object\n" \
207
" .section .compartment_exports." name ",\"awG\",@progbits," name \
208
",comdat\n" \
209
" .globl __export." name "\n" \
210
" .p2align 2\n" \
211
"__export." name ":\n" \
212
" .half 0\n"
/* function start and stack size initialised to 0 */
\
213
" .byte 0\n" \
214
" .byte 0b100000\n"
/* Set the flag that indicates that this is a \
215
sealing key. */
\
216
" .size __export." name ", 4\n" \
217
" .previous\n" \
218
".endif\n" \
219
"1:\n" \
220
" auipcc %0, %%cheriot_compartment_hi(__import." name ")\n" \
221
" clc %0, %%cheriot_compartment_lo_i(1b)(%0)\n" \
222
: "=C"(ret)); \
223
ret; \
224
})
225
226
/**
227
* \internal
228
*
229
* Helper macro that evaluates to the compartment of the current
230
* compilation unit, as a string.
231
*/
232
#define COMPARTMENT_NAME_STRING __XSTRING(__CHERI_COMPARTMENT__)
Generated by
1.18.0