Home | History | Annotate | Line # | Download | only in rtl
      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
      9 ASM_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.
     52 ASM_HIDDEN(_Z18InitializeGuardPtrv)
     53 .global _Z18InitializeGuardPtrv
     54 ASM_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
     91 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
     92 #endif
     93 
     94 ASM_HIDDEN(__tsan_setjmp)
     95 .comm _ZN14__interception11real_setjmpE,8,8
     96 .globl ASM_SYMBOL_INTERCEPTOR(setjmp)
     97 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp))
     98 ASM_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
    153 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp))
    154 
    155 .comm _ZN14__interception12real__setjmpE,8,8
    156 .globl ASM_SYMBOL_INTERCEPTOR(_setjmp)
    157 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp))
    158 ASM_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
    213 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp))
    214 
    215 .comm _ZN14__interception14real_sigsetjmpE,8,8
    216 .globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp)
    217 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
    218 ASM_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
    277 ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
    278 
    279 #if !defined(__APPLE__)
    280 .comm _ZN14__interception16real___sigsetjmpE,8,8
    281 .globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)
    282 ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
    283 ASM_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
    335 ASM_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