Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | /* * Copyright (c) 2025 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #ifndef OS_X18_H #define OS_X18_H #if defined(__arm64__) #include <stdbool.h> #include <sys/cdefs.h> #include <os/availability.h> __BEGIN_DECLS /*! * @function os_custom_x18_abi * * @abstract * * Switch thread into or out of custom ABI usage for the x18 register. * * This API comes with lots of caveats. Users of this API must take a * disproportionate amount of care, so it is strongly advised to only * use this API if absolutely required. * * Under normal operation, x18 is reserved for operating system usage, * and may therefore not be touched by any application code. The Apple * ARM64 Application Binary Interface codifies this by stating: "The * platforms reserve register x18. Don’t use this register." * * However, there are special situations, such as when implementing * compatibility layers for other ABIs, where custom usage x18 becomes * a necessity, notably when it is part of the ABI contract itself * (for example, used as a TSD base). * * This API enables per-thread use of x18 under such special * circumstances. To use it, application code must issue * `os_custom_x18_abi(true)` at the boundary between the regular macOS * application code and the code using the custom ABI. When in this * mode, x18 behaves like any other general purpose register for this * thread: It has no other semantics towards the operating system * other than holding arbitrary values, and it will get saved and * restored across context switches like any other GPR. When switching * back from the custom ABI code to macOS application code, * `os_custom_x18_abi(false)` must then be issued, in order to restore * the proper system-defined operating semantics for x18 again. * * Note that code running after `os_custom_x18_abi(true)` must not * call, directly or in the form of callbacks, into any macOS * library/framework code in the current thread, with the exception of * `os_custom_x18_abi() and `os_custom_x18_abi_get()` themselves. * * Great care must also be taken with signal handlers and other * asynchronous code entry points. These should either not call into * any macOS library/framework code (note that this includes POSIX * interfaces), or bracket such calls between * `os_custom_x18_abi(false)` and `os_custom_x18_abi(true)`, iff the * custom x18 ABI is enabled according to `os_custom_x18_abi_get()`. * Any other regular limitations for signal handler code calling into * OS functions apply as well. Unless the use of signals is absolutely * required, masking all signals before entering custom x18 ABI mode * avoids any complication with signal handlers. * * Also note that the operating system does not preserve any x18 value * from within the custom ABI code across `os_custom_x18_abi()` * calls. Effectively, calling `os_custom_x18_abi(false)` destroys * x18's value. In the likely case that the application code wishes to * preserve x18's content for the custom ABI code, the application * code must save and restore the affected thread's x18 value itself. * * `os_custom_x18_abi()` will, however, properly save and restore x18 * for its system-defined operating semantics, meaning that * application code must not restore x18 in the other direction, * i.e. after switching back from custom ABI code to macOS code, nor * does it have to save the value before entering custom ABI code (the * application code may actually not have the proper information to do * so safely). In summary, application code is in charge of x18's * value on the "custom ABI side", while macOS itself is in charge of * the value on the "macOS side". * * @param custom true to switch the thread into custom ABI x18 usage, * false to switch back to regular macOS x18 semantics. * */ API_UNAVAILABLE(ios, tvos, watchos, bridgeos) API_AVAILABLE(macos(16.4)) extern void os_custom_x18_abi(bool custom); /*! * @function os_custom_x18_abi_get * * @abstract * * Returns whether custom x18 ABI mode is enabled. * * This can be used to determine if the custom x18 ABI needs temporary * disablement prior to calling into any macOS code, e.g. in signal handlers. * * @return `true` iff custom x18 ABI is enabled. */ API_UNAVAILABLE(ios, tvos, watchos, bridgeos) API_AVAILABLE(macos(16.4)) extern bool os_custom_x18_abi_get(void); __END_DECLS #endif // defined(__arm64__) #endif // OS_X18_H |