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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | /* * Copyright (c) 2000-2024 Apple Inc. All rights reserved. */ /* * Copyright (C) 1990, NeXT, Inc. * * File: next/kern_machdep.c * Author: John Seamons * * Machine-specific kernel routines. */ #include <sys/types.h> #include <mach/machine.h> #include <kern/cpu_number.h> #include <libkern/libkern.h> #include <machine/exec.h> #include <pexpert/arm64/board_config.h> int ml_grade_binary(cpu_type_t, cpu_subtype_t, cpu_subtype_t, bool); #if __arm64__ static cpu_subtype_t cpu_subtype32(void); #endif /* __arm64__ */ #if __arm64__ /* * When an arm64 CPU is executing an arm32 binary, we need to map from the * host's 64-bit subtype to the appropriate 32-bit subtype. */ static cpu_subtype_t cpu_subtype32() { switch (cpu_subtype()) { case CPU_SUBTYPE_ARM64_V8: return CPU_SUBTYPE_ARM_V8; default: return 0; } } static int grade_arm64e_binary(cpu_subtype_t execfeatures) { #if XNU_TARGET_OS_IOS || XNU_TARGET_OS_XR /* * iOS 13 toolchains produced unversioned arm64e slices which are not * ABI compatible with this release. */ if ((execfeatures & CPU_SUBTYPE_PTRAUTH_ABI) == 0) { return 0; } #endif /* XNU_TARGET_OS_IOS || XNU_TARGET_OS_XR */ /* The current ABI version is preferred over arm64 */ if (CPU_SUBTYPE_ARM64_PTR_AUTH_VERSION(execfeatures) <= CPU_SUBTYPE_ARM64_PTR_AUTH_MAX_PREFERRED_VERSION) { return 12; } /* Non-preferred future and older ABIs are allowed, but exec_mach_imgact may treat them like an arm64 slice */ return 11; } #endif /* __arm64__ */ /********************************************************************** * Routine: ml_grade_binary() * * Function: Return a relative preference for exectypes and * execsubtypes in fat executable files. The higher the * grade, the higher the preference. A grade of 0 means * not acceptable. **********************************************************************/ int ml_grade_binary(cpu_type_t exectype, cpu_subtype_t execsubtype, cpu_subtype_t execfeatures __unused, bool allow_simulator_binary __unused) { #if __arm64__ cpu_subtype_t hostsubtype = (exectype & CPU_ARCH_ABI64) ? cpu_subtype() : cpu_subtype32(); #else cpu_subtype_t hostsubtype = cpu_subtype(); #endif /* __arm64__ */ switch (exectype) { #if __arm64__ case CPU_TYPE_ARM64: switch (hostsubtype) { case CPU_SUBTYPE_ARM64_V8: switch (execsubtype) { case CPU_SUBTYPE_ARM64_V8: return 10; case CPU_SUBTYPE_ARM64_ALL: return 9; } break; case CPU_SUBTYPE_ARM64E: switch (execsubtype) { case CPU_SUBTYPE_ARM64E: return grade_arm64e_binary(execfeatures); case CPU_SUBTYPE_ARM64_V8: return 10; case CPU_SUBTYPE_ARM64_ALL: return 9; } } /* switch (hostsubtype) */ break; #else /* __arm64__ */ case CPU_TYPE_ARM: switch (hostsubtype) { /* * For 32-bit ARMv8, try the ARMv8 slice before falling back to Swift. */ case CPU_SUBTYPE_ARM_V8: switch (execsubtype) { case CPU_SUBTYPE_ARM_V8: return 7; } goto v7s; /* * For Swift and later, we prefer to run a swift slice, but fall back * to v7 as Cortex A9 errata should not apply */ v7s: case CPU_SUBTYPE_ARM_V7S: switch (execsubtype) { case CPU_SUBTYPE_ARM_V7S: return 6; } goto v7; /* * For Cortex A7, accept v7k only due to differing ABI */ case CPU_SUBTYPE_ARM_V7K: switch (execsubtype) { case CPU_SUBTYPE_ARM_V7K: return 6; } break; /* * For Cortex A9, we prefer the A9 slice, but will run v7 albeit * under the risk of hitting the NEON load/store errata */ case CPU_SUBTYPE_ARM_V7F: switch (execsubtype) { case CPU_SUBTYPE_ARM_V7F: return 6; } goto v7; v7: case CPU_SUBTYPE_ARM_V7: switch (execsubtype) { case CPU_SUBTYPE_ARM_V7: return 5; } // fall through... case CPU_SUBTYPE_ARM_V6: switch (execsubtype) { case CPU_SUBTYPE_ARM_V6: return 4; } // fall through... case CPU_SUBTYPE_ARM_V5TEJ: switch (execsubtype) { case CPU_SUBTYPE_ARM_V5TEJ: return 3; } // fall through case CPU_SUBTYPE_ARM_V4T: switch (execsubtype) { case CPU_SUBTYPE_ARM_V4T: return 2; case CPU_SUBTYPE_ARM_ALL: return 1; } break; case CPU_SUBTYPE_ARM_XSCALE: switch (execsubtype) { case CPU_SUBTYPE_ARM_XSCALE: return 4; case CPU_SUBTYPE_ARM_V5TEJ: return 3; case CPU_SUBTYPE_ARM_V4T: return 2; case CPU_SUBTYPE_ARM_ALL: return 1; } break; } #endif /* __arm64__ */ } return 0; } |