1 /* 2 * Copyright (c) 2007 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 * @OSF_COPYRIGHT@ 30 */ 31 /* 32 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or [email protected] 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56 57 #ifndef _ARM_ASM_H_ 58 #define _ARM_ASM_H_ 59 60 #ifdef __arm64__ 61 62 #include <arm/arch.h> 63 #if XNU_KERNEL_PRIVATE 64 #include <pexpert/arm64/board_config.h> 65 #endif /* XNU_KERNEL_PRIVATE */ 66 67 /* There is another definition of ALIGN for .c sources */ 68 #ifdef __ASSEMBLER__ 69 #define ALIGN 2 70 #endif /* ASSEMBLER */ 71 72 #ifndef FALIGN 73 #define FALIGN ALIGN 74 #endif 75 76 #define LB(x,n) n 77 #if __STDC__ 78 #ifndef __NO_UNDERSCORES__ 79 #define LCL(x) L ## x 80 #define EXT(x) _ ## x 81 #define LEXT(x) _ ## x ## : 82 #else 83 #define LCL(x) .L ## x 84 #define EXT(x) x 85 #define LEXT(x) x ## : 86 #endif 87 #define LBc(x,n) n ## : 88 #define LBb(x,n) n ## b 89 #define LBf(x,n) n ## f 90 #else /* __STDC__ */ 91 #ifndef __NO_UNDERSCORES__ 92 #define LCL(x) L/**/x 93 #define EXT(x) _/**/x 94 #define LEXT(x) _/**/x/**/: 95 #else /* __NO_UNDERSCORES__ */ 96 #define LCL(x) .L/**/x 97 #define EXT(x) x 98 #define LEXT(x) x/**/: 99 #endif /* __NO_UNDERSCORES__ */ 100 #define LBc(x,n) n/**/: 101 #define LBb(x,n) n/**/b 102 #define LBf(x,n) n/**/f 103 #endif /* __STDC__ */ 104 105 #define String .asciz 106 #define Value .word 107 #define Times(a,b) (a*b) 108 #define Divide(a,b) (a/b) 109 110 #ifdef __ASSEMBLER__ 111 #if MACH_KDB 112 #include <ddb/stab.h> 113 /* 114 * This pseudo-assembler line is added so that there will be at least 115 * one N_SO entry in the symbol stable to define the current file name. 116 */ 117 #endif /* MACH_KDB */ 118 119 /* 120 * Multiline macros must use .macro syntax for now, 121 * as there is no ARM64 statement separator. 122 */ 123 .macro ENTRY 124 .align FALIGN 125 .globl _$0 126 _$0 : 127 .endmacro 128 129 .macro ENTRY2 130 .align FALIGN 131 .globl _$0 132 .globl _$1 133 _$0 : 134 _$1 : 135 .endmacro 136 137 .macro READ_THREAD 138 mrs $0, TPIDR_EL1 139 .endmacro 140 141 .macro BRANCH_EXTERN 142 b _$0 143 .endmacro 144 145 .macro CALL_EXTERN 146 bl _$0 147 .endmacro 148 149 .macro MOV64 150 movk $0, #((($1) >> 48) & 0x000000000000FFFF), lsl #48 151 movk $0, #((($1) >> 32) & 0x000000000000FFFF), lsl #32 152 movk $0, #((($1) >> 16) & 0x000000000000FFFF), lsl #16 153 movk $0, #((($1) >> 00) & 0x000000000000FFFF), lsl #00 154 .endmacro 155 156 .macro MOV32 157 movz $0, #((($1) >> 16) & 0x000000000000FFFF), lsl #16 158 movk $0, #((($1) >> 00) & 0x000000000000FFFF), lsl #00 159 .endmacro 160 161 .macro ARM64_STACK_PROLOG 162 #if __has_feature(ptrauth_returns) 163 pacibsp 164 #endif 165 .endmacro 166 167 .macro ARM64_STACK_EPILOG 168 #if __has_feature(ptrauth_returns) 169 retab 170 #else 171 ret 172 #endif 173 .endmacro 174 175 /** 176 * Push a stack frame. 177 * 178 * Most callers should invoke ARM64_STACK_PROLOG first, since otherwise this will 179 * push an unsigned return address onto the stack. 180 */ 181 #define PUSH_FRAME \ 182 stp fp, lr, [sp, #-16]! %% \ 183 mov fp, sp %% 184 185 /** 186 * Pop the most recent stack frame. 187 * 188 * Note: if the complementary PUSH_FRAME was not preceded by ARM64_STACK_PROLOG, 189 * then this operation could load an attacker-controlled return address from 190 * memory! Either add ARM64_STACK_PROLOG, or use POP_FRAME_WITHOUT_LR if there 191 * are no plans to ever use the popped LR. 192 */ 193 #define POP_FRAME \ 194 mov sp, fp %% \ 195 ldp fp, lr, [sp], #16 %% 196 197 /** 198 * Pop the most recent stack frame, but do not update LR. 199 * 200 * This macro is intended for situations like kernel entry, where the caller 201 * doesn't actually need to preserve LR, but wants to push a stack frame 202 * anyway for the benefit of unwinders. 203 */ 204 #define POP_FRAME_WITHOUT_LR \ 205 mov sp, fp %% \ 206 ldp fp, xzr, [sp], #16 %% 207 208 #define EXT(x) _ ## x 209 210 #ifdef XNU_KERNEL_PRIVATE 211 .macro PANIC_UNIMPLEMENTED 212 bl EXT(panic_unimplemented) 213 .endmacro 214 215 /** 216 * Marks the first instruction of an externally callable assembly routine. 217 * 218 * Callable functions which might be executed via indirect branches (i.e. any 219 * function which could be invoked from C/C++) MUST use either this macro or 220 * ARM64_STACK_PROLOG, depending on whether LR will be spilled to the stack. 221 * Failure to use one of these macros may cause unexpected runtime BTI 222 * exceptions when invoking a function. 223 */ 224 .macro ARM64_PROLOG 225 #if BTI_ENFORCED 226 bti c 227 #endif /* BTI_ENFORCED */ 228 .endmacro 229 230 /** 231 * Marks the first instruction of an indirect branch target. 232 * 233 * This macro is not required if the location is only ever branched to by direct 234 * branches (as is most common). This macro is necessary for computed 235 * branches (i.e. switch cases) and other forms of dynamic dispatch. 236 */ 237 .macro ARM64_JUMP_TARGET 238 #if BTI_ENFORCED 239 bti j 240 #endif /* BTI_ENFORCED */ 241 .endmacro 242 #endif /* XNU_KERNEL_PRIVATE */ 243 #else /* NOT __ASSEMBLER__ */ 244 245 /* These defines are here for .c files that wish to reference global symbols 246 * within __asm__ statements. 247 */ 248 #ifndef __NO_UNDERSCORES__ 249 #define CC_SYM_PREFIX "_" 250 #else 251 #define CC_SYM_PREFIX "" 252 #endif /* __NO_UNDERSCORES__ */ 253 #endif /* __ASSEMBLER__ */ 254 255 #ifdef __ASSEMBLER__ 256 257 # define BRANCH_EXTERN(x) b EXT(x) 258 259 #endif /* __ASSEMBLER__ */ 260 261 #endif /* __arm64__ */ 262 263 #endif /* _ARM_ASM_H_ */ 264