xref: /xnu-11215/bsd/sys/constrained_ctypes.h (revision 8d741a5d)
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  * 4. ABI Compatibility Considerations
379  *
380  *      The pointer instrumentation process has ABI implications.
381  *
382  *      When the pointer insrumentation is enabled, the size of `bidirectional'
383  *      and `checked' pointers exceeds the size of the machine word.
384  *
385  *      Thus, if there is a concern that the instrumentation is enabled only in
386  *      some compilation units that use the function, these constrained
387  *      pointers can not be used for function parameters.
388  *
389  *      Instead, one should rely on `__counted_by(count)' or `__sized_by(size)'
390  *      attributes. These attributes accept as a parameter the name of a
391  *      variable that contains the cont of items, or the byte size, of the
392  *      pointed-to array. Use of these attributes does not change the size of
393  *      the pointer.
394  *
395  *      The tradeoff is between maintaining code readabilty and ABI compatibility.
396  *
397  *      A common pattern is to split the function into the implementation,
398  *      which is statically linked and therefore is ABI-safe, and the interface
399  *      wrapper, which uses `__counted_by' or `__sized_by' to preserve ABI
400  *      compatibility.
401  *
402  *
403  * 4.1. When ABI is a concern, replace `bidirectional' and `checked'
404  *        with  `__counted_by(count)` and `__sized_by(size)` for vector
405  *        parameters.
406  *
407  *
408  *      Examples:
409  *
410  *      (1) Using `const thing_ref_t __counted_by(count)' instead of `const
411  *          thing_ref_ptr_t' for vector input in a wrapper:
412  *
413  *      errno_t thing_find_best_compat(const thing_ref_t __counted_by(count)things,
414  *                                     thing_ref_ref_t best, size_t count)
415  *      {
416  *              // __counted_by implicitly upgraded to `checked'
417  *              return thing_find_best(things, best, count);
418  *      }
419  *
420  *      (2) Using `thing_ref_t __counted_by(count)' instead of `thing_ref_ptr_t'
421  *          for vector output in a wrapper.
422  *
423  *      errno_t thing_copy_things_compat(thing_ref_t __counted_by(count)src,
424  *                                       things_ref_t __counted_by(count)dst,
425  *                                       size_t count)
426  *      {
427  *              // __counted_by implicitly upgraded to `checked'
428  *              return thing_copy_things(src, dst, count);
429  *      }
430  *
431  *
432  * 4.2. When ABI is a concern, use `__counted_by(count)' and
433  *        `__sized_by(size)' for struct members that point to arrays.
434  *
435  *      Examples:
436  *
437  *      (1) Using a structure that points to array of things:
438  *
439  *      struct things_crate {
440  *              size_t                               tc_count;
441  *              struct thing * __counted_by(tc_count)tc_things;
442  *      };
443  *
444  * 5. Naming conventions
445  *
446  *      If `typename' is the name of a C type, and `tag' is a constraint tag
447  *      (one of `ref', `ptr', or `bptr'), then the name of a pointer to
448  *      `typename' constrained by `tag' is `basetag_tag_t', where `basename'
449  *      is defined by:
450  *
451  *      (a) If `typename' is a name of an integral type, then `basetag' is same
452  *          as `typename'.
453  *      (b) If `typename' is a name of a function type, then `basetag' is same
454  *          as `typename'.
455  *      (c) If `typename' is a name of a structure, then `basetag' is formed by
456  *          stripping the `struct' keyword from `typename'.
457  *      (d) If `typename' is a name of an enumeration, then `basetag' is formed
458  *          by stripping the `enum' keyword from `typename'.
459  *      (e) If `typename' is a name of a typedef to a struct or an enum that ends
460  *          with `_t', then `basetag' is formed by stripping the `_t' suffix
461  *          from `typename'. See (h) below for when `typename' is a pointer typedef.
462  *      (f) If `typename' is a name of constrained pointer type ending with `_t',
463  *          then `basetag' is formed by stripping the `_t' suffix from `typename'.
464  *
465  *      Additionally, constrained pointers to constrained const pointers are a
466  *      special case:
467  *
468  *      (g) If `typename' is a name of a constrained pointer type, ending with
469  *          `_{innertag}_t', and `typename' has `const' qualifier, then `basetag'
470  *          is formed by replacing `_{innertag}_t' with `_c{innertag}'
471  *
472  *      Finally, sometimes `name_t' represents not `struct name' but `struct name *'.
473  *      This creates additional special case:
474  *
475  *      (h) If `typename' is a pointer typedef named `{struct}_t`, such as
476  *          `mbuf_t',  then creating a constrained pointer to a `typename' would
477  *           require creating a  constrained pointer to an unconstrained pointer,
478  *           which is not supported at the moment. Instead, a constrained pointer to
479  *           `typeof(*typename)` must be created first, and constrained again. Using
480  *           the `mbuf_t` example, first one should create a constrained pointer to
481  *           `struct mbuf`, e.g, `mbuf_bptr_t`, and then constrain it again with
482  *           `tag`, leading to `mbuf_bptr_ref_t'.
483  *
484  *      Examples:
485  *
486  *      (1) `int_ref_t' is a `reference pointer' to `int', following the rule (a) above.
487  *      (2) `so_pru_ref_t' is a `reference pointer' to function `so_pru',
488  *          following the rule (b) above.
489  *      (3) `socket_ref_t' is a `reference pointer' to `struct socket',
490  *          following the rule (c) above.
491  *      (4) `classq_pkt_type_ref_t' is a `reference pointer' to `enum classq_pkt_type'
492  *          following the rule (d) above.
493  *      (5) `classq_pkt_type_ref_t' is a also `reference pointer' to `classq_pkt_type_t'
494  *          following the rule (e) above.
495  *      (6) `socket_ref_ref_t' is a `reference pointer' to `socket_ref_t`,
496  *          following the rule (f) above.
497  *      (7) `socket_cref_ref_t' is a `reference pointer' to `socket_ref_t const`,
498  *          following the rule (g) above.
499  *      (8) `mbuf_ref_ref_t', is a `reference pointer' to `mbuf_ref_t`, and is one
500  *          possible result of creating a `reference pointer' to `mbuf_t',
501  *          following the rule (h) above.
502  *      (9) `mbuf_bptr_ref_t', is a `reference pointer' to `mbuf_bptr_t`, and
503  *          is another possible result of creating a `reference pointer' to
504  *          `mbuf_t', following the rule (h) above.
505  *
506  */
507 
508 /*
509  * Constraint contract constants.
510  *
511  * At the moment only clang (when compiled with `ptrcheck' feature) supports
512  * pointer tagging via `__single', `__indexable' and `__bidi_indexable' attributes.
513  *
514  * During the transitional period, the `__indexable__' and `__bidi_indexable'
515  * constraints will decay to raw pointers if the `ptrcheck' feature is not enabled.
516  * Once the transitional period is over, the `__CCT_CONTRACT_ATTR_{B}PTR' constraints
517  * will stop decaying to raw pointers when built by sufficiently recent version
518  * of clang.
519  *
520  * Support for other compilers will be added after the introduction of support
521  * for pointer tagging on those compilers.
522  */
523 #if defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE)
524 #if defined(__clang__)
525 #define __CCT_CONTRACT_ATTR___CCT_REF         __single
526 #define __CCT_CONTRACT_ATTR___CCT_CREF        const __single
527 #if  __has_ptrcheck
528 #define __CCT_CONTRACT_ATTR___CCT_BPTR        __bidi_indexable
529 #define __CCT_CONTRACT_ATTR___CCT_PTR         __indexable
530 #else /* __clang__ + __has_ptrcheck */
531 #define __CCT_CONTRACT_ATTR___CCT_BPTR
532 #define __CCT_CONTRACT_ATTR___CCT_PTR
533 #endif /* __clang__ + !__has_ptrcheck */
534 #else /* !__clang__ */
535 #define __CCT_CONTRACT_ATTR___CCT_REF
536 #define __CCT_CONTRACT_ATTR___CCT_CREF        const
537 #define __CCT_CONTRACT_ATTR___CCT_BPTR
538 #define __CCT_CONTRACT_ATTR___CCT_PTR
539 #endif /* __clang__ */
540 
541 #define __CCT_CONTRACT_TAG___CCT_REF          _ref
542 #define __CCT_CONTRACT_TAG___CCT_CREF         _cref
543 #define __CCT_CONTRACT_TAG___CCT_BPTR         _bptr
544 #define __CCT_CONTRACT_TAG___CCT_PTR          _ptr
545 
546 /* Helper macros */
547 #define __CCT_DEFER(F, ...) F(__VA_ARGS__)
548 #define __CCT_CONTRACT_TO_ATTR(kind) __CONCAT(__CCT_CONTRACT_ATTR_, kind)
549 #define __CCT_CONTRACT_TO_TAG(kind)  __CCT_DEFER(__CONCAT, __CCT_CONTRACT_TAG_, kind)
550 
551 #define __CCT_COUNT_ARGS1(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, N, ...) N
552 #define __CCT_COUNT_ARGS(...) \
553 	__CCT_COUNT_ARGS1(, __VA_ARGS__, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
554 #define __CCT_DISPATCH1(base, N, ...) __CONCAT(base, N)(__VA_ARGS__)
555 #define __CCT_DISPATCH(base, ...) \
556 	__CCT_DISPATCH1(base, __CCT_COUNT_ARGS(__VA_ARGS__), __VA_ARGS__)
557 
558 /* Covert a contract list to a type suffix */
559 #define __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_1(kind)                                                \
560 	__CCT_DEFER(__CONCAT, __CCT_CONTRACT_TO_TAG(kind), _t)
561 #define __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_2(kind1, kind2)                                        \
562 	__CCT_DEFER(__CONCAT, __CCT_CONTRACT_TO_TAG(kind1),                                             \
563 	         __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_1(kind2))
564 #define __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_3(kind1, kind2, kind3)                                 \
565 	__CCT_DEFER(__CONCAT, __CCT_CONTRACT_TO_TAG(kind1),                                             \
566 	         __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_2(kind2, kind3))
567 
568 /* Create typedefs for the constrained pointer type */
569 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPE_3(basetype, basetag, kind)                               \
570 typedef basetype * __CCT_CONTRACT_TO_ATTR(kind)                                                     \
571 	__CCT_DEFER(__CONCAT, basetag,  __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_1(kind))
572 
573 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPE_4(basetype, basetag, kind1, kind2)                       \
574 typedef basetype * __CCT_CONTRACT_TO_ATTR(kind1)                                                    \
575 	         * __CCT_CONTRACT_TO_ATTR(kind2)                                                        \
576 	__CCT_DEFER(__CONCAT, basetag,  __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_2(kind1, kind2))
577 
578 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPE_5(basetype, basetag, kind1, kind2, kind3)                \
579 typedef basetype * __CCT_CONTRACT_TO_ATTR(kind1)                                                    \
580 	         * __CCT_CONTRACT_TO_ATTR(kind2)                                                        \
581 	         * __CCT_CONTRACT_TO_ATTR(kind3)                                                        \
582 	__CCT_DEFER(__CONCAT, basetag,  __CCT_CONTRACT_LIST_TO_TAGGED_SUFFIX_3(kind1, kind2, kind3))
583 #endif /* defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE) */
584 
585 /*
586  * Lower level type constructor.
587  */
588 #if defined(KERNEL) || defined(__CCT_ENABLE_USER_SPACE)
589 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...)                                  \
590 	__CCT_DISPATCH(__CCT_DECLARE_CONSTRAINED_PTR_TYPE, basetype, basetag, __VA_ARGS__)
591 #else /* !defined(KERNEL) && !defined(__CCT_ENABLE_USER_SPACE) */
592 #if defined(__clang__)
593 #pragma clang diagnostic push
594 #pragma clang diagnostic ignored "-Wextra-semi"
595 #endif /* defined(__clang__) */
596 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, ...)
597 #if defined(__clang__)
598 #pragma clang diagnostic pop
599 #endif /* defined(__clang__) */
600 #endif /* !defined(KERNEL) && !defined(__CCT_ENABLE_USER_SPACE) */
601 
602 /*
603  * Higher level type constructors.
604  */
605 #if defined(KERNEL)
606 /*
607  * The constrained types that can potentially break the ABI are not exposed
608  * into the user-space.
609  */
610 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag)                                      \
611 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF);                                   \
612 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_BPTR);                                  \
613 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_PTR);                                   \
614 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_REF);                        \
615 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_PTR);                        \
616 __CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_PTR, __CCT_REF)
617 #else /* !defined(KERNEL) */
618 #if defined(__CCT_ENABLE_USER_SPACE)
619 /* Limiting the higher-level constructor to the ABI-preserving constructs. */
620 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag)                                      \
621 	__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF);                               \
622 	__CCT_DECLARE_CONSTRAINED_PTR_TYPE(basetype, basetag, __CCT_REF, __CCT_REF)
623 #else /* !defined(__CCT_ENABLE_USER_SPACE) */
624 /* Disabling the higher-level constructor */
625 #if defined(__clang__)
626 #pragma clang diagnostic push
627 #pragma clang diagnostic ignored "-Wextra-semi"
628 #endif /* defined(__clang__) */
629 #define __CCT_DECLARE_CONSTRAINED_PTR_TYPES(basetype, basetag)
630 #if defined(__clang__)
631 #pragma clang diagnostic pop
632 #endif /* defined(__clang__) */
633 #endif /* !defined(__CCT_ENABLE_USER_SPACE) */
634 #endif /* !defined(KERNEL) */
635 
636 #endif /* __CONSTRAINED_CTYPES__ */
637