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