1#include "sanitizer_common/sanitizer_asm.h" 2 3.section .bss 4.type __tsan_pointer_chk_guard, %object 5.size __tsan_pointer_chk_guard, 8 6__tsan_pointer_chk_guard: 7.zero 8 8 9.section .text 10 11// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp 12// functions) by XORing them with a random guard pointer. For AArch64 it is a 13// global variable rather than a TCB one (as for x86_64/powerpc) and althought 14// its value is exported by the loader, it lies within a private GLIBC 15// namespace (meaning it should be only used by GLIBC itself and the ABI is 16// not stable). So InitializeGuardPtr obtains the pointer guard value by 17// issuing a setjmp and checking the resulting pointers values against the 18// original ones. 19.hidden _Z18InitializeGuardPtrv 20.global _Z18InitializeGuardPtrv 21.type _Z18InitializeGuardPtrv, @function 22_Z18InitializeGuardPtrv: 23 CFI_STARTPROC 24 // Allocates a jmp_buf for the setjmp call. 25 stp x29, x30, [sp, -336]! 26 CFI_DEF_CFA_OFFSET (336) 27 CFI_OFFSET (29, -336) 28 CFI_OFFSET (30, -328) 29 add x29, sp, 0 30 CFI_DEF_CFA_REGISTER (29) 31 add x0, x29, 24 32 33 // Call libc setjmp that mangle the stack pointer value 34 adrp x1, :got:_ZN14__interception12real__setjmpE 35 ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE] 36 ldr x1, [x1] 37 blr x1 38 39 // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the 40 // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and 41 // SP at ((uintptr*)jmp_buf)[13]. 42 // The mangle operation is just 'value' xor 'pointer guard value' and 43 // if we know the original value (SP) and the expected one, we can derive 44 // the guard pointer value. 45 mov x0, sp 46 47 // Loads the mangled SP pointer. 48 ldr x1, [x29, 128] 49 eor x0, x0, x1 50 adrp x2, __tsan_pointer_chk_guard 51 str x0, [x2, #:lo12:__tsan_pointer_chk_guard] 52 ldp x29, x30, [sp], 336 53 CFI_RESTORE (30) 54 CFI_RESTORE (19) 55 CFI_DEF_CFA (31, 0) 56 ret 57 CFI_ENDPROC 58.size _Z18InitializeGuardPtrv, .-_Z18InitializeGuardPtrv 59 60.hidden __tsan_setjmp 61.comm _ZN14__interception11real_setjmpE,8,8 62.type setjmp, @function 63setjmp: 64 CFI_STARTPROC 65 66 // save env parameters for function call 67 stp x29, x30, [sp, -32]! 68 CFI_DEF_CFA_OFFSET (32) 69 CFI_OFFSET (29, -32) 70 CFI_OFFSET (30, -24) 71 72 // Adjust the SP for previous frame 73 add x29, sp, 0 74 CFI_DEF_CFA_REGISTER (29) 75 76 // Save jmp_buf 77 str x19, [sp, 16] 78 CFI_OFFSET (19, -16) 79 mov x19, x0 80 81 // SP pointer mangling (see glibc setjmp) 82 adrp x2, __tsan_pointer_chk_guard 83 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 84 add x0, x29, 32 85 eor x1, x2, x0 86 87 // call tsan interceptor 88 bl __tsan_setjmp 89 90 // restore env parameter 91 mov x0, x19 92 ldr x19, [sp, 16] 93 ldp x29, x30, [sp], 32 94 CFI_RESTORE (30) 95 CFI_RESTORE (19) 96 CFI_DEF_CFA (31, 0) 97 98 // tail jump to libc setjmp 99 adrp x1, :got:_ZN14__interception11real_setjmpE 100 ldr x1, [x1, #:got_lo12:_ZN14__interception11real_setjmpE] 101 ldr x1, [x1] 102 br x1 103 104 CFI_ENDPROC 105.size setjmp, .-setjmp 106 107.comm _ZN14__interception12real__setjmpE,8,8 108.globl _setjmp 109.type _setjmp, @function 110_setjmp: 111 CFI_STARTPROC 112 113 // save env parameters for function call 114 stp x29, x30, [sp, -32]! 115 CFI_DEF_CFA_OFFSET (32) 116 CFI_OFFSET (29, -32) 117 CFI_OFFSET (30, -24) 118 119 // Adjust the SP for previous frame 120 add x29, sp, 0 121 CFI_DEF_CFA_REGISTER (29) 122 123 // Save jmp_buf 124 str x19, [sp, 16] 125 CFI_OFFSET (19, -16) 126 mov x19, x0 127 128 // SP pointer mangling (see glibc setjmp) 129 adrp x2, __tsan_pointer_chk_guard 130 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 131 add x0, x29, 32 132 eor x1, x2, x0 133 134 // call tsan interceptor 135 bl __tsan_setjmp 136 137 // Restore jmp_buf parameter 138 mov x0, x19 139 ldr x19, [sp, 16] 140 ldp x29, x30, [sp], 32 141 CFI_RESTORE (30) 142 CFI_RESTORE (19) 143 CFI_DEF_CFA (31, 0) 144 145 // tail jump to libc setjmp 146 adrp x1, :got:_ZN14__interception12real__setjmpE 147 ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE] 148 ldr x1, [x1] 149 br x1 150 151 CFI_ENDPROC 152.size _setjmp, .-_setjmp 153 154.comm _ZN14__interception14real_sigsetjmpE,8,8 155.globl sigsetjmp 156.type sigsetjmp, @function 157sigsetjmp: 158 CFI_STARTPROC 159 160 // save env parameters for function call 161 stp x29, x30, [sp, -32]! 162 CFI_DEF_CFA_OFFSET (32) 163 CFI_OFFSET (29, -32) 164 CFI_OFFSET (30, -24) 165 166 // Adjust the SP for previous frame 167 add x29, sp, 0 168 CFI_DEF_CFA_REGISTER (29) 169 170 // Save jmp_buf and savesigs 171 stp x19, x20, [sp, 16] 172 CFI_OFFSET (19, -16) 173 CFI_OFFSET (20, -8) 174 mov w20, w1 175 mov x19, x0 176 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 183 // call tsan interceptor 184 bl __tsan_setjmp 185 186 // restore env parameter 187 mov w1, w20 188 mov x0, x19 189 ldp x19, x20, [sp, 16] 190 ldp x29, x30, [sp], 32 191 CFI_RESTORE (30) 192 CFI_RESTORE (29) 193 CFI_RESTORE (19) 194 CFI_RESTORE (20) 195 CFI_DEF_CFA (31, 0) 196 197 // tail jump to libc sigsetjmp 198 adrp x2, :got:_ZN14__interception14real_sigsetjmpE 199 ldr x2, [x2, #:got_lo12:_ZN14__interception14real_sigsetjmpE] 200 ldr x2, [x2] 201 br x2 202 CFI_ENDPROC 203.size sigsetjmp, .-sigsetjmp 204 205.comm _ZN14__interception16real___sigsetjmpE,8,8 206.globl __sigsetjmp 207.type __sigsetjmp, @function 208__sigsetjmp: 209 CFI_STARTPROC 210 211 // save env parameters for function call 212 stp x29, x30, [sp, -32]! 213 CFI_DEF_CFA_OFFSET (32) 214 CFI_OFFSET (29, -32) 215 CFI_OFFSET (30, -24) 216 217 // Adjust the SP for previous frame 218 add x29, sp, 0 219 CFI_DEF_CFA_REGISTER (29) 220 221 // Save jmp_buf and savesigs 222 stp x19, x20, [sp, 16] 223 CFI_OFFSET (19, -16) 224 CFI_OFFSET (20, -8) 225 mov w20, w1 226 mov x19, x0 227 228 // SP pointer mangling (see glibc setjmp) 229 adrp x2, __tsan_pointer_chk_guard 230 ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] 231 add x0, x29, 32 232 eor x1, x2, x0 233 234 // call tsan interceptor 235 bl __tsan_setjmp 236 237 mov w1, w20 238 mov x0, x19 239 ldp x19, x20, [sp, 16] 240 ldp x29, x30, [sp], 32 241 CFI_RESTORE (30) 242 CFI_RESTORE (29) 243 CFI_RESTORE (19) 244 CFI_RESTORE (20) 245 CFI_DEF_CFA (31, 0) 246 247 // tail jump to libc __sigsetjmp 248 adrp x2, :got:_ZN14__interception16real___sigsetjmpE 249 ldr x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE] 250 ldr x2, [x2] 251 br x2 252 CFI_ENDPROC 253.size __sigsetjmp, .-__sigsetjmp 254 255#if defined(__linux__) 256/* We do not need executable stack. */ 257.section .note.GNU-stack,"",@progbits 258#endif 259