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