1// The content of this file is AArch64-only: 2#if defined(__aarch64__) 3 4#include "sanitizer_common/sanitizer_asm.h" 5 6#if !defined(__APPLE__) 7.section .bss 8.type __tsan_pointer_chk_guard, %object 9ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard)) 10__tsan_pointer_chk_guard: 11.zero 8 12#endif 13 14#if defined(__APPLE__) 15.align 2 16 17.section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers 18.long _setjmp$non_lazy_ptr 19_setjmp$non_lazy_ptr: 20.indirect_symbol _setjmp 21.long 0 22 23.section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers 24.long __setjmp$non_lazy_ptr 25__setjmp$non_lazy_ptr: 26.indirect_symbol __setjmp 27.long 0 28 29.section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers 30.long _sigsetjmp$non_lazy_ptr 31_sigsetjmp$non_lazy_ptr: 32.indirect_symbol _sigsetjmp 33.long 0 34#endif 35 36#if !defined(__APPLE__) 37.section .text 38#else 39.section __TEXT,__text 40.align 3 41#endif 42 43#if !defined(__APPLE__) 44// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp 45// functions) by XORing them with a random guard pointer. For AArch64 it is a 46// global variable rather than a TCB one (as for x86_64/powerpc) and althought 47// its value is exported by the loader, it lies within a private GLIBC 48// namespace (meaning it should be only used by GLIBC itself and the ABI is 49// not stable). So InitializeGuardPtr obtains the pointer guard value by 50// issuing a setjmp and checking the resulting pointers values against the 51// original ones. 52ASM_HIDDEN(_Z18InitializeGuardPtrv) 53.global _Z18InitializeGuardPtrv 54ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) 55_Z18InitializeGuardPtrv: 56 CFI_STARTPROC 57 // Allocates a jmp_buf for the setjmp call. 58 stp x29, x30, [sp, -336]! 59 CFI_DEF_CFA_OFFSET (336) 60 CFI_OFFSET (29, -336) 61 CFI_OFFSET (30, -328) 62 add x29, sp, 0 63 CFI_DEF_CFA_REGISTER (29) 64 add x0, x29, 24 65 66 // Call libc setjmp that mangle the stack pointer value 67 adrp x1, :got:_ZN14__interception12real__setjmpE 68 ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE] 69 ldr x1, [x1] 70 blr x1 71 72 // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the 73 // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and 74 // SP at ((uintptr*)jmp_buf)[13]. 75 // The mangle operation is just 'value' xor 'pointer guard value' and 76 // if we know the original value (SP) and the expected one, we can derive 77 // the guard pointer value. 78 mov x0, sp 79 80 // Loads the mangled SP pointer. 81 ldr x1, [x29, 128] 82 eor x0, x0, x1 83 adrp x2, __tsan_pointer_chk_guard 84 str x0, [x2, #:lo12:__tsan_pointer_chk_guard] 85 ldp x29, x30, [sp], 336 86 CFI_RESTORE (30) 87 CFI_RESTORE (19) 88 CFI_DEF_CFA (31, 0) 89 ret 90 CFI_ENDPROC 91ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) 92#endif 93 94ASM_HIDDEN(__tsan_setjmp) 95.comm _ZN14__interception11real_setjmpE,8,8 96.globl ASM_SYMBOL_INTERCEPTOR(setjmp) 97ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp)) 98ASM_SYMBOL_INTERCEPTOR(setjmp): 99 CFI_STARTPROC 100 101 // save env parameters for function call 102 stp x29, x30, [sp, -32]! 103 CFI_DEF_CFA_OFFSET (32) 104 CFI_OFFSET (29, -32) 105 CFI_OFFSET (30, -24) 106 107 // Adjust the SP for previous frame 108 add x29, sp, 0 109 CFI_DEF_CFA_REGISTER (29) 110 111 // Save jmp_buf 112 str x19, [sp, 16] 113 CFI_OFFSET (19, -16) 114 mov x19, x0 115 116#if !defined(__APPLE__) 117 // SP pointer mangling (see glibc setjmp) 118 adrp x2, __tsan_pointer_chk_guard 119 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 120 add x0, x29, 32 121 eor x1, x2, x0 122#else 123 adrp x2, ___tsan_darwin_setjmp_xor_key@page 124 ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff] 125 add x0, x29, 32 126 eor x1, x2, x0 127#endif 128 129 // call tsan interceptor 130 bl ASM_SYMBOL(__tsan_setjmp) 131 132 // restore env parameter 133 mov x0, x19 134 ldr x19, [sp, 16] 135 ldp x29, x30, [sp], 32 136 CFI_RESTORE (30) 137 CFI_RESTORE (19) 138 CFI_DEF_CFA (31, 0) 139 140 // tail jump to libc setjmp 141#if !defined(__APPLE__) 142 adrp x1, :got:_ZN14__interception11real_setjmpE 143 ldr x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE] 144 ldr x1, [x1] 145#else 146 adrp x1, _setjmp$non_lazy_ptr@page 147 add x1, x1, _setjmp$non_lazy_ptr@pageoff 148 ldr x1, [x1] 149#endif 150 br x1 151 152 CFI_ENDPROC 153ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp)) 154 155.comm _ZN14__interception12real__setjmpE,8,8 156.globl ASM_SYMBOL_INTERCEPTOR(_setjmp) 157ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) 158ASM_SYMBOL_INTERCEPTOR(_setjmp): 159 CFI_STARTPROC 160 161 // save env parameters for function call 162 stp x29, x30, [sp, -32]! 163 CFI_DEF_CFA_OFFSET (32) 164 CFI_OFFSET (29, -32) 165 CFI_OFFSET (30, -24) 166 167 // Adjust the SP for previous frame 168 add x29, sp, 0 169 CFI_DEF_CFA_REGISTER (29) 170 171 // Save jmp_buf 172 str x19, [sp, 16] 173 CFI_OFFSET (19, -16) 174 mov x19, x0 175 176#if !defined(__APPLE__) 177 // SP pointer mangling (see glibc setjmp) 178 adrp x2, __tsan_pointer_chk_guard 179 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 180 add x0, x29, 32 181 eor x1, x2, x0 182#else 183 adrp x2, ___tsan_darwin_setjmp_xor_key@page 184 ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff] 185 add x0, x29, 32 186 eor x1, x2, x0 187#endif 188 189 // call tsan interceptor 190 bl ASM_SYMBOL(__tsan_setjmp) 191 192 // Restore jmp_buf parameter 193 mov x0, x19 194 ldr x19, [sp, 16] 195 ldp x29, x30, [sp], 32 196 CFI_RESTORE (30) 197 CFI_RESTORE (19) 198 CFI_DEF_CFA (31, 0) 199 200 // tail jump to libc setjmp 201#if !defined(__APPLE__) 202 adrp x1, :got:_ZN14__interception12real__setjmpE 203 ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE] 204 ldr x1, [x1] 205#else 206 adrp x1, __setjmp$non_lazy_ptr@page 207 add x1, x1, __setjmp$non_lazy_ptr@pageoff 208 ldr x1, [x1] 209#endif 210 br x1 211 212 CFI_ENDPROC 213ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp)) 214 215.comm _ZN14__interception14real_sigsetjmpE,8,8 216.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp) 217ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) 218ASM_SYMBOL_INTERCEPTOR(sigsetjmp): 219 CFI_STARTPROC 220 221 // save env parameters for function call 222 stp x29, x30, [sp, -32]! 223 CFI_DEF_CFA_OFFSET (32) 224 CFI_OFFSET (29, -32) 225 CFI_OFFSET (30, -24) 226 227 // Adjust the SP for previous frame 228 add x29, sp, 0 229 CFI_DEF_CFA_REGISTER (29) 230 231 // Save jmp_buf and savesigs 232 stp x19, x20, [sp, 16] 233 CFI_OFFSET (19, -16) 234 CFI_OFFSET (20, -8) 235 mov w20, w1 236 mov x19, x0 237 238#if !defined(__APPLE__) 239 // SP pointer mangling (see glibc setjmp) 240 adrp x2, __tsan_pointer_chk_guard 241 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 242 add x0, x29, 32 243 eor x1, x2, x0 244#else 245 adrp x2, ___tsan_darwin_setjmp_xor_key@page 246 ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff] 247 add x0, x29, 32 248 eor x1, x2, x0 249#endif 250 251 // call tsan interceptor 252 bl ASM_SYMBOL(__tsan_setjmp) 253 254 // restore env parameter 255 mov w1, w20 256 mov x0, x19 257 ldp x19, x20, [sp, 16] 258 ldp x29, x30, [sp], 32 259 CFI_RESTORE (30) 260 CFI_RESTORE (29) 261 CFI_RESTORE (19) 262 CFI_RESTORE (20) 263 CFI_DEF_CFA (31, 0) 264 265 // tail jump to libc sigsetjmp 266#if !defined(__APPLE__) 267 adrp x2, :got:_ZN14__interception14real_sigsetjmpE 268 ldr x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE] 269 ldr x2, [x2] 270#else 271 adrp x2, _sigsetjmp$non_lazy_ptr@page 272 add x2, x2, _sigsetjmp$non_lazy_ptr@pageoff 273 ldr x2, [x2] 274#endif 275 br x2 276 CFI_ENDPROC 277ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) 278 279#if !defined(__APPLE__) 280.comm _ZN14__interception16real___sigsetjmpE,8,8 281.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp) 282ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) 283ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): 284 CFI_STARTPROC 285 286 // save env parameters for function call 287 stp x29, x30, [sp, -32]! 288 CFI_DEF_CFA_OFFSET (32) 289 CFI_OFFSET (29, -32) 290 CFI_OFFSET (30, -24) 291 292 // Adjust the SP for previous frame 293 add x29, sp, 0 294 CFI_DEF_CFA_REGISTER (29) 295 296 // Save jmp_buf and savesigs 297 stp x19, x20, [sp, 16] 298 CFI_OFFSET (19, -16) 299 CFI_OFFSET (20, -8) 300 mov w20, w1 301 mov x19, x0 302 303#if !defined(__APPLE__) 304 // SP pointer mangling (see glibc setjmp) 305 adrp x2, __tsan_pointer_chk_guard 306 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 307 add x0, x29, 32 308 eor x1, x2, x0 309#endif 310 311 // call tsan interceptor 312 bl ASM_SYMBOL(__tsan_setjmp) 313 314 mov w1, w20 315 mov x0, x19 316 ldp x19, x20, [sp, 16] 317 ldp x29, x30, [sp], 32 318 CFI_RESTORE (30) 319 CFI_RESTORE (29) 320 CFI_RESTORE (19) 321 CFI_RESTORE (20) 322 CFI_DEF_CFA (31, 0) 323 324 // tail jump to libc __sigsetjmp 325#if !defined(__APPLE__) 326 adrp x2, :got:_ZN14__interception16real___sigsetjmpE 327 ldr x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE] 328 ldr x2, [x2] 329#else 330 adrp x2, ASM_SYMBOL(__sigsetjmp)@page 331 add x2, x2, ASM_SYMBOL(__sigsetjmp)@pageoff 332#endif 333 br x2 334 CFI_ENDPROC 335ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) 336#endif 337 338#if defined(__linux__) 339/* We do not need executable stack. */ 340.section .note.GNU-stack,"",@progbits 341#endif 342 343#endif 344