1/*
2 * Copyright (c) 2000-2022 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef __CONSTRAINED_CTYPES__
30#define __CONSTRAINED_CTYPES__
31
32#include <sys/cdefs.h>
33
34/*
35 * Constraining pointer types based on contracts.
36 *
37 * 1. List of supported constrained pointers.
38 *
39 * 1.1. `Reference' pointers.
40 *
41 * The `reference' pointers point to a single entity. The pointer
42 * arithmetics are not supported for the `reference' pointers.
43 *
44 * The `reference' pointers are fully ABI compatible with
45 * the unconstrained C pointers.
46 *
47 * The naming convention for the `reference' pointers uses
48 * the `ref' constraint tag. See `Naming conventions' below for furhter
49 * discussion.
50 *
51 * Examples:
52 *
53 * (1) `socket_ref_t' is `reference' pointer to `struct socket'.
54 * (2) `uint32_ref_t' is `reference' pointer to `uint32_t'.
55 *
56 *
57 * 1.2. `Checked' pointers.
58 *
59 * The `checked' pointers represent contigous data arrays, which
60 * can be traversed only in the direction of increasing memory addresses.
61 * The pointer arithmetics are partially supported: decrements (p--, --p)
62 * are disallowed.
63 *
64 * The `checked' pointers are not ABI-compatible with plain C pointers,
65 * due to the boundary checks instrumentation. See `ABI
66 * Compatibility Considerations' below for further discussion.
67 *
68 * The naming convention for the `checked' pointers uses the `ptr'
69 * constraint tag. See `Naming conventions' below for furhter discussion.
70 *
71 * Examples:
72 *
73 * (1) `socket_ptr_t' is `checked' pointer to `struct socket'.
74 * (2) `uint32_ptr_t' is `checked' pointer to `uint32_t'.
75 *
76 *
77 * 1.3. `Bidirectional' pointers.
78 *
79 * The `bidirectional' pointers represent contigous data arrays,
80 * which can be traversed in both directions. The pointer arithmetics are
81 * fully supported for the `array' pointers.
82 *
83 * The `bidirectional' pointers are not ABI-compatible with plain C
84 * pointers, due to the boundary checks instrumentation. Additionally,
85 * passing `bidirectional' pointers to functions require the use of stack.
86 * See `ABI Compatibility Considerations' below for further discussion.
87 *
88 * The naming convention for the `bidirectional' pointers uses
89 * the `bptr' constraint tag. See `Naming conventions' below for furhter
90 * discussion.
91 *
92 * Examples:
93 *
94 * (1) `socket_bptr_t' is `bidirectional' pointer to `struct socket'.
95 * (2) `uint32_bptr_t' is `bidirectional' pointer to `uint32_t'.
96 *
97 *
98 * 1.4. Multidimensional constrained pointers.
99 *
100 * Constraining multidimensional pointers is achieved by iteratively
101 * applying the constraints from the innermost type to the outermost type.
102 *
103 * Pointer arithmetics are supported for the dimensions that
104 * are not constrained to a `reference' or `const reference'.
105 *
106 * If any of the dimension constraints isn't ABI-compatible with its
107 * unconstrained counterpart, then the entire constrained multidimensional
108 * pointer is not ABI-compatible with the corresponding unconstrained
109 * multidimensional pointer. Otherwise, the two are ABI-compatible. See
110 * `ABI compatibility' below for further discussion.
111 *
112 * The naming convention for the multidimensional constrained pointers
113 * combines the naming tags that correspond to the individual constraints.
114 * See `Naming conventions' below for furhter discussion.
115 *
116 * Examples:
117 *
118 * (1) `socket_ref_bptr_t' is a `bidirectional' pointer to a `reference'
119 * pointer to `struct socket'.
120 * (2) `socket_ptr_ref_t' is a `reference' pointer to a `checked'
121 * pointer to `struct socket'.
122 *
123 *
124 * 1.5. Using `const', `volatile', and `restrict' type qualifiers with
125 * constrained types.
126 *
127 * The use of the `const', `volatile', and `restrict' type qualifiers
128 * (a.k.a. "CRV qualifiers") follows the syntax of the C language.
129 *
130 * As a special case, if a `const' qualifier is applied to inner
131 * dimensions of a multidimensional constrained pointer type, the
132 * constraint tag is prepended with letter `c'; thus `cref' can be used
133 * for const-qualified `reference' pointer. This abbreviation is only
134 * supported for the `const' qualifier, as use of `volatile' or `restrict'
135 * for inner constrained types is quite uncommon. See `Multidimensional
136 * constrained pointers' above and `Naming conventions' below for further
137 * discussion.
138 *
139 * Examples:
140 *
141 * (1) `socket_ref_t const' is the const-qualified `reference' pointer
142 * to `struct socket'.
143 * (2) `socket_ptr_t volatile' is the volatile-qualified `checked' pointer
144 * to `struct socket'.
145 * (3) `socket_ptr_ref_t const' is a const-qualified `reference' pointer
146 * to a `checked' pointer to `struct socket'.
147 * (4) `socket_cref_ptr_t const' is a `checked' pointer to a
148 * const-qualified `reference' pointer to `struct socket'.
149 *
150 *
151 * 1.6. Combining constrained pointers and unconstrained pointers.
152 *
153 * Unconstrained pointers to constrained pointers follow
154 * the standard C syntax. Defining constrained pointers to
155 * unconstrained pointers is possible via defining a constrained pointer
156 * to a typedef.
157 *
158 * Examples:
159 *
160 * (1) `socket_ref_t *' is an unconstrained pointer to `socket_ref_t', i.e.
161 * unconstrained pointer to a `reference' pointer to `struct socket'.
162 * (2) `socket_ref_t const *' is an unconstrained pointer to `socket_ref_t const',
163 * i.e. an unconstrained pointer to a const-qualified `reference'
164 * pointer to `struct socket'.
165 * (3) `socket_ref_t * const' is a const-qualified unconstrained pointer to
166 * `socket_ref_t', i.e. a const-qualified unconstrained pointer to a
167 * `reference' pointer to `struct socket'.
168 * (4) `intptr_ref_t' is a `reference' pointer to `intptr_t', i.e.
169 * a `reference' pointer to an unconstrained pointer to `int'. Note
170 * the use of `intptr_t' typedef, which is necessary at the moment.
171 *
172 *
173 * 2. Defining constrained pointer types.
174 *
175 * 2.1. Declaring multiple constrained types simultaneously.
176 *
177 * `__CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag)`
178 * is the suggested way to declare constrained pointer types.
179 *
180 * Parameters:
181 *
182 * `basetype`: the pointee type, including `struct' or `enum' keywords.
183 * `basetag`: the prefix of the constrained type.
184 *
185 * This macro acts differently in the user-space and the kernel-space
186 * code.
187 * When used in the user-space code, the macro will declare
188 * types which are ABI-safe. See `ABI Compatibility Considerations'
189 * below for more details on ABI-safety. In the user-space code,
190 * the macro is guarded by the `__CCT_ENABLE_USER_SPACE' compilation
191 * flag.
192 * When used in the kernel-space code, the macro will declare
193 * the common constrained types.
194 *
195 * Examples:
196 *
197 * (1) When used from the user space, and `__CCT_ENABLE_USER_SPACE'
198 * is defined, the expression
199 * `__CCT_DECLARE_CONSTRAINED_PTR_TYPES(struct socket, socket);'
200 * will declare types:
201 *
202 * (a) `socket_ref_t': the `reference' to `struct socket'
203 * (b) `socket_ref_ref_t': the `reference to reference'
204 * to `struct socket'.
205 *
206 * (2) When used from the kernel space,
207 * `__CCT_DECLARE_CONSTRAINED_PTR_TYPES(struct socket, socket);'
208 * will declare the above types, plus:
209 *
210 * (c) `socket_ptr_t': `checked' pointer to `struct socket'.
211 * (d) `socket_bptr_t': `bidirectional' pointer to `struct socket'.
212 * (e) `socket_ref_ptr_t': `checked' pointer to a `reference'
213 * to `struct socket'.
214 * (f) `socket_ptr_ref_t': `reference' to a `checked' pointer
215 * to `struct socket'.
216 *
217 * These additional types are not ABI-safe, and therefore are not exposed
218 * to the user space. See `ABI Compatibility Considerations' below.
219 *
220 *
221 * 2.2. Declaring individual constrained types.
222 *
223 * The above macro attempts to do many things at once, and under some
224 * circumstances can be not appropriate. For these circumstances, a
225 * finer-graned declarator can be used:
226 *
227 * `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...)'
228 *
229 * Parameters:
230 *
231 * `basetype`: the pointee type.
232 * `basetag`: the prefix of the constrained type.
233 * `...`: list of constraints:
234 * - `__CCT_REF' for the "reference" contract;
235 * - `__CCT_CREF' for the "const reference" contract;
236 * - `__CCT_PTR' for the "checked pointer" contract; or
237 * - `__CCT_BPTR' for the "bidirectional pointer" contract.
238 *
239 * Examples:
240 *
241 * (1) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, __CCT_REF)'
242 * will declare the type
243 * `reference' pointer to `struct socket'
244 * and call this type by `socket_ref_t'
245 *
246 * (2) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, __CCT_REF, __CCT_PTR)'
247 * will declare the type
248 * `checked' pointer to `socket_ref_t'
249 * which in turn is equivalent to the type
250 * `checked' pointer to `reference' pointer to `struct socket'
251 *
252 * (3) `__CCT_DECLARE_CONSTRAINED_PTR_TYPE(struct socket, socket, __CCT_REF, __CCT_PTR, __CCT_REF)'
253 * will declare the type
254 * `reference' pointer to `socket_ref_ptr_t'
255 * which is equivalent to the type
256 * `reference' pointer to `checked' pointer to `socket_ref_t'
257 * which in turn is equivalent to the type
258 * `reference' pointer to `checked' pointer to `reference' pointer to `struct socket'
259 *
260 *
261 * 3. Using constrained pointer types.
262 *
263 * 3.1. Using constrained pointers for local variables.
264 *
265 * Constraining the pointers on the stack reduces the risk of stack
266 * overflow. Therefore, it is highly suggested to use the constrained
267 * versions of the pointers for stack parameters. For local array
268 * variables, opt for the `bidirectional' pointers. If only a single value
269 * needs to be pointed, opt for the `reference' pointers.
270 *
271 * There are two alternative approaches for using the `reference' pointers.
272 * One approach is to explicitly use `thing_ref_t ptr` instead of `thing *ptr`.
273 * The other approach is to surround the code with the directives
274 * `__ASSUME_PTR_ABI_SINGLE_BEGIN' and `__ASSUME_PTR_ABI_SINGLE_END', which
275 * will have the effect of turning every unconstrained pointer to its
276 * `reference' counterpart.
277 *
278 *
279 * 3.2. Using constrained pointers for function parameters
280 *
281 * 3.2.1. Use `reference' pointers for scalar parameters.
282 *
283 * Scalar parameters are safe to use across ABI boundaries.
284 *
285 * Examples:
286 *
287 * (1) Using `reference' pointers for scalar input:
288 *
289 * errno_t thing_is_valid(const thing_ref_t t)
290 * {
291 * return t == NULL ? EINVAL : 0;
292 * }
293 *
294 *
295 * (2) Using `reference' pointers for scalar output, which is
296 * allocated by the caller:
297 *
298 * errno_t thing_copy(const thing_ref_t src, thing_ref_t dst)
299 * {
300 * if (src == NULL || dst == NULL) {
301 * return EINVAL;
302 * }
303 * bcopy(src, dst);
304 * return 0;
305 * }
306 *
307 * (3) Using `reference to reference' for scalar output that is
308 * allocated by the callee:
309 *
310 * errno_t thing_dup(const thing_ref_t src, thing_ref_ref_t dst)
311 * {
312 * *dst = malloc(sizeof(*dst));
313 * bcopy(src, *dst, sizeof(*src));
314 * return 0;
315 * }
316 *
317 *
318 * 3.2.2. Use `checked' pointers for vector parameters.
319 *
320 * When the ABI isn't a concern, use of `checked' pointers
321 * increases the code readability.
322 *
323 * See `ABI Compatibility Considerations' below for vector parameters when
324 * ABI is a concern.
325 *
326 * Examples:
327 *
328 * (1) Using `checked' pointers for vector input:
329 *
330 * errno_t thing_find_best(const thing_ref_ptr_t things,
331 * thing_ref_ref_t best, size_t count)
332 * {
333 * for (int i = 0; i < count; i++) {
334 * if (thing_is_the_best(things[i])) {
335 * *best = things[i];
336 * return 0;
337 * }
338 * }
339 * return ENOENT; // no best thing
340 * }
341 *
342 * (2) Using `checked' pointers for vector output parameters that
343 * are allocated by caller:
344 *
345 * errno_t thing_copy_things(thing_ref_ptr_t src, thing_ref_ptr_t dst,
346 * size_t count)
347 * {
348 * for (int i = 0; i < count; i++) {
349 * dst[i] = malloc(sizeof(*dst[i]));
350 * bcopy(src[i], dst[i], sizeof(*src[i]));
351 * }
352 * return 0;
353 * }
354 *
355 * (3) Using `reference to checked' pointers for vector output
356 * parameters that are allocated by callee:
357 *
358 * errno_t thing_dup_things(thing_ref_ptr_t src, thing_ref_ptr_ref_t dst,
359 * size_t count)
360 * {
361 * *dst = malloc(sizeof(**src) * count);
362 * return thing_copy_things(src, *dst, count);
363 * }
364 *
365 *
366 * 3.3. Using constrained pointers in struct definitions
367 *
368 * Examples:
369 *
370 * (1) Using a structure that points to array of things:
371 *
372 * struct things_crate {
373 * size_t tc_count;
374 * thing_bptr_t tc_things;
375 * };
376 *
377 *
378 * 3.4. Variable-size structures
379 *
380 * Constrained pointer instrumentation depends on knowing the size of the
381 * structures. If the structure contains a variable array, the array needs
382 * to be annotated by `__sized_by' or `__counted_by' attribute:
383 *
384 * Example:
385 *
386 * struct sockaddr {
387 * __uint8_t sa_len;
388 * sa_family_t sa_family;
389 * char sa_data[__counted_by(sa_len - 2)];
390 * };
391 *
392 *
393 * 4. ABI Compatibility Considerations
394 *
395 * The pointer instrumentation process has ABI implications.
396 *
397 * When the pointer insrumentation is enabled, the size of `bidirectional'
398 * and `checked' pointers exceeds the size of the machine word.
399 *
400 * Thus, if there is a concern that the instrumentation is enabled only in
401 * some compilation units that use the function, these constrained
402 * pointers can not be used for function parameters.
403 *
404 * Instead, one should rely on `__counted_by(count)' or `__sized_by(size)'
405 * attributes. These attributes accept as a parameter the name of a
406 * variable that contains the cont of items, or the byte size, of the
407 * pointed-to array. Use of these attributes does not change the size of
408 * the pointer.
409 *
410 * The tradeoff is between maintaining code readabilty and ABI compatibility.
411 *
412 * A common pattern is to split the function into the implementation,
413 * which is statically linked and therefore is ABI-safe, and the interface
414 * wrapper, which uses `__counted_by' or `__sized_by' to preserve ABI
415 * compatibility.
416 *
417 *
418 * 4.1. When ABI is a concern, replace `bidirectional' and `checked'
419 * with `__counted_by(count)` and `__sized_by(size)` for vector
420 * parameters.
421 *
422 *
423 * Examples:
424 *
425 * (1) Using `const thing_ref_t __counted_by(count)' instead of `const
426 * thing_ref_ptr_t' for vector input in a wrapper:
427 *
428 * errno_t thing_find_best_compat(const thing_ref_t __counted_by(count)things,
429 * thing_ref_ref_t best, size_t count)
430 * {
431 * // __counted_by implicitly upgraded to `checked'
432 * return thing_find_best(things, best, count);
433 * }
434 *
435 * (2) Using `thing_ref_t __counted_by(count)' instead of `thing_ref_ptr_t'
436 * for vector output in a wrapper.
437 *
438 * errno_t thing_copy_things_compat(thing_ref_t __counted_by(count)src,
439 * things_ref_t __counted_by(count)dst,
440 * size_t count)
441 * {
442 * // __counted_by implicitly upgraded to `checked'
443 * return thing_copy_things(src, dst, count);
444 * }
445 *
446 *
447 * 4.2. When ABI is a concern, use `__counted_by(count)' and
448 * `__sized_by(size)' for struct members that point to arrays.
449 *
450 * Examples:
451 *
452 * (1) Using a structure that points to array of things:
453 *
454 * struct things_crate {
455 * size_t tc_count;
456 * struct thing * __counted_by(tc_count)tc_things;
457 * };
458 *
459 * 5. Naming conventions
460 *
461 * If `typename' is the name of a C type, and `tag' is a constraint tag
462 * (one of `ref', `ptr', or `bptr'), then the name of a pointer to
463 * `typename' constrained by `tag' is `basetag_tag_t', where `basename'
464 * is defined by:
465 *
466 * (a) If `typename' is a name of an integral type, then `basetag' is same
467 * as `typename'.
468 * (b) If `typename' is a name of a function type, then `basetag' is same
469 * as `typename'.
470 * (c) If `typename' is a name of a structure, then `basetag' is formed by
471 * stripping the `struct' keyword from `typename'.
472 * (d) If `typename' is a name of an enumeration, then `basetag' is formed
473 * by stripping the `enum' keyword from `typename'.
474 * (e) If `typename' is a name of a typedef to a struct or an enum that ends
475 * with `_t', then `basetag' is formed by stripping the `_t' suffix
476 * from `typename'. See (h) below for when `typename' is a pointer typedef.
477 * (f) If `typename' is a name of constrained pointer type ending with `_t',
478 * then `basetag' is formed by stripping the `_t' suffix from `typename'.
479 *
480 * Additionally, constrained pointers to constrained const pointers are a
481 * special case:
482 *
483 * (g) If `typename' is a name of a constrained pointer type, ending with
484 * `_{innertag}_t', and `typename' has `const' qualifier, then `basetag'
485 * is formed by replacing `_{innertag}_t' with `_c{innertag}'
486 *
487 * Finally, sometimes `name_t' represents not `struct name' but `struct name *'.
488 * This creates additional special case:
489 *
490 * (h) If `typename' is a pointer typedef named `{struct}_t`, such as
491 * `mbuf_t', then creating a constrained pointer to a `typename' would
492 * require creating a constrained pointer to an unconstrained pointer,
493 * which is not supported at the moment. Instead, a constrained pointer to
494 * `typeof(*typename)` must be created first, and constrained again. Using
495 * the `mbuf_t` example, first one should create a constrained pointer to
496 * `struct mbuf`, e.g, `mbuf_bptr_t`, and then constrain it again with
497 * `tag`, leading to `mbuf_bptr_ref_t'.
498 *
499 * Examples:
500 *
501 * (1) `int_ref_t' is a `reference pointer' to `int', following the rule (a) above.
502 * (2) `so_pru_ref_t' is a `reference pointer' to function `so_pru',
503 * following the rule (b) above.
504 * (3) `socket_ref_t' is a `reference pointer' to `struct socket',
505 * following the rule (c) above.
506 * (4) `classq_pkt_type_ref_t' is a `reference pointer' to `enum classq_pkt_type'
507 * following the rule (d) above.
508 * (5) `classq_pkt_type_ref_t' is a also `reference pointer' to `classq_pkt_type_t'
509 * following the rule (e) above.
510 * (6) `socket_ref_ref_t' is a `reference pointer' to `socket_ref_t`,
511 * following the rule (f) above.
512 * (7) `socket_cref_ref_t' is a `reference pointer' to `socket_ref_t const`,
513 * following the rule (g) above.
514 * (8) `mbuf_ref_ref_t', is a `reference pointer' to `mbuf_ref_t`, and is one
515 * possible result of creating a `reference pointer' to `mbuf_t',
516 * following the rule (h) above.
517 * (9) `mbuf_bptr_ref_t', is a `reference pointer' to `mbuf_bptr_t`, and
518 * is another possible result of creating a `reference pointer' to
519 * `mbuf_t', following the rule (h) above.
520 *
521 */
522
523/*
524 * Constraint contract constants.
525 *
526 * At the moment only clang (when compiled with `ptrcheck' feature) supports
527 * pointer tagging via `__single', `__indexable' and `__bidi_indexable' attributes.
528 *
529 * During the transitional period, the `__indexable__' and `__bidi_indexable'
530 * constraints will decay to raw pointers if the `ptrcheck' feature is not enabled.
531 * Once the transitional period is over, the `__CCT_CONTRACT_ATTR_{B}PTR' constraints
532 * will stop decaying to raw pointers when built by sufficiently recent version
533 * of clang.
534 *
535 * Support for other compilers will be added after the introduction of support
536 * for pointer tagging on those compilers.
537 */
538#if defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE)
539#if defined(__clang__)
540#define __CCT_CONTRACT_ATTR___CCT_REF __single
541#define __CCT_CONTRACT_ATTR___CCT_CREF const __single
542#if __has_ptrcheck
543#define __CCT_CONTRACT_ATTR___CCT_BPTR __bidi_indexable
544#define __CCT_CONTRACT_ATTR___CCT_PTR __indexable
545#else /* __clang__ + __has_ptrcheck */
546#define __CCT_CONTRACT_ATTR___CCT_BPTR
547#define __CCT_CONTRACT_ATTR___CCT_PTR
548#endif /* __clang__ + !__has_ptrcheck */
549#else /* !__clang__ */
550#define __CCT_CONTRACT_ATTR___CCT_REF
551#define __CCT_CONTRACT_ATTR___CCT_CREF const
552#define __CCT_CONTRACT_ATTR___CCT_BPTR
553#define __CCT_CONTRACT_ATTR___CCT_PTR
554#endif /* __clang__ */
555
556#define __CCT_CONTRACT_TAG___CCT_REF _ref
557#define __CCT_CONTRACT_TAG___CCT_CREF _cref
558#define __CCT_CONTRACT_TAG___CCT_BPTR _bptr
559#define __CCT_CONTRACT_TAG___CCT_PTR _ptr
560
561/* Helper macros */
562#define __CCT_DEFER(F, ...) F(__VA_ARGS__)
563#define __CCT_CONTRACT_TO_ATTR(kind) __CONCAT(__CCT_CONTRACT_ATTR_, kind)
564#define __CCT_CONTRACT_TO_TAG(kind) __CCT_DEFER(__CONCAT, __CCT_CONTRACT_TAG_, kind)
565
566#define __CCT_COUNT_ARGS1(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, N, ...) N
567#define __CCT_COUNT_ARGS(...) \
568 __CCT_COUNT_ARGS1(, __VA_ARGS__, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
569#define __CCT_DISPATCH1(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
570#define __CCT_DISPATCH(base, ...) \
571 __CCT_DISPATCH1(base, __CCT_COUNT_ARGS(__VA_ARGS__), __VA_ARGS__)
572
573/* Covert a contract list to a type suffix */
574#define __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_1(kind) \
575 __CCT_DEFER(__CONCAT, __CCT_CONTRACT_TO_TAG(kind), _t)
576#define __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_2(kind1, kind2) \
577 __CCT_DEFER(__CONCAT, __CCT_CONTRACT_TO_TAG(kind1), \
578 __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_1(kind2))
579#define __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_3(kind1, kind2, kind3) \
580 __CCT_DEFER(__CONCAT, __CCT_CONTRACT_TO_TAG(kind1), \
581 __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_2(kind2, kind3))
582
583/* Create typedefs for the constrained pointer type */
584#define __CCT_DECLARE_CONSTRAINED_PTR_TYPE_3(basetype, basetag, kind) \
585typedef basetype * __CCT_CONTRACT_TO_ATTR(kind) \
586 __CCT_DEFER(__CONCAT, basetag, __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_1(kind))
587
588#define __CCT_DECLARE_CONSTRAINED_PTR_TYPE_4(basetype, basetag, kind1, kind2) \
589typedef basetype * __CCT_CONTRACT_TO_ATTR(kind1) \
590 * __CCT_CONTRACT_TO_ATTR(kind2) \
591 __CCT_DEFER(__CONCAT, basetag, __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_2(kind1, kind2))
592
593#define __CCT_DECLARE_CONSTRAINED_PTR_TYPE_5(basetype, basetag, kind1, kind2, kind3) \
594typedef basetype * __CCT_CONTRACT_TO_ATTR(kind1) \
595 * __CCT_CONTRACT_TO_ATTR(kind2) \
596 * __CCT_CONTRACT_TO_ATTR(kind3) \
597 __CCT_DEFER(__CONCAT, basetag, __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_3(kind1, kind2, kind3))
598#endif /* defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE) */
599
600/*
601 * Lower level type constructor.
602 */
603#if defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE)
604#define __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...) \
605 __CCT_DISPATCH(__CCT_DECLARE_CONSTRAINED_PTR_TYPE, basetype, basetag, __VA_ARGS__)
606#else /* !defined(KERNEL) && !defined(__CCT_ENABLE_USER_SPACE) */
607#if defined(__clang__)
608#pragma clang diagnostic push
609#pragma clang diagnostic ignored "-Wextra-semi"
610#endif /* defined(__clang__) */
611#define __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...)
612#if defined(__clang__)
613#pragma clang diagnostic pop
614#endif /* defined(__clang__) */
615#endif /* !defined(KERNEL) && !defined(__CCT_ENABLE_USER_SPACE) */
616
617/*
618 * Higher level type constructors.
619 */
620#if defined(KERNEL)
621/*
622 * The constrained types that can potentially break the ABI are not exposed
623 * into the user-space.
624 */
625#define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag) \
626__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF); \
627__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_BPTR); \
628__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_PTR); \
629__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_REF); \
630__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_PTR); \
631__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_PTR, __CCT_REF)
632#else /* !defined(KERNEL) */
633#if defined(__CCT_ENABLE_USER_SPACE)
634/* Limiting the higher-level constructor to the ABI-preserving constructs. */
635#define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag) \
636 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF); \
637 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_REF)
638#else /* !defined(__CCT_ENABLE_USER_SPACE) */
639/* Disabling the higher-level constructor */
640#if defined(__clang__)
641#pragma clang diagnostic push
642#pragma clang diagnostic ignored "-Wextra-semi"
643#endif /* defined(__clang__) */
644#define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag)
645#if defined(__clang__)
646#pragma clang diagnostic pop
647#endif /* defined(__clang__) */
648#endif /* !defined(__CCT_ENABLE_USER_SPACE) */
649#endif /* !defined(KERNEL) */
650
651#endif /* __CONSTRAINED_CTYPES__ */
652