]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/aarch64/dl-tlsdesc.S
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / aarch64 / dl-tlsdesc.S
index 05be370abb4c1786d928955c6dbe8a787c1ec722..2fdaa8ee776868a2c69c1053daa323bd7e715166 100644 (file)
@@ -1,6 +1,6 @@
 /* Thread-local storage handling in the ELF dynamic linker.
    AArch64 version.
-   Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   Copyright (C) 2011-2019 Free Software Foundation, Inc.
 
    This file is part of the GNU C Library.
 
@@ -16,7 +16,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   <https://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
 #include <tls.h>
        cfi_startproc
        .align 2
 _dl_tlsdesc_return:
-       ldr     x0, [x0, #8]
+       DELOUSE (0)
+       ldr     PTR_REG (0), [x0, #PTR_SIZE]
        RET
        cfi_endproc
        .size   _dl_tlsdesc_return, .-_dl_tlsdesc_return
 
-       /* Same as _dl_tlsdesc_return but with synchronization for
-          lazy relocation.
-          Prototype:
-          _dl_tlsdesc_return_lazy (tlsdesc *) ;
-        */
-       .hidden _dl_tlsdesc_return_lazy
-       .global _dl_tlsdesc_return_lazy
-       .type   _dl_tlsdesc_return_lazy,%function
-       cfi_startproc
-       .align 2
-_dl_tlsdesc_return_lazy:
-       /* The ldar here happens after the load from [x0] at the call site
-          (that is generated by the compiler as part of the TLS access ABI),
-          so it reads the same value (this function is the final value of
-          td->entry) and thus it synchronizes with the release store to
-          td->entry in _dl_tlsdesc_resolve_rela_fixup ensuring that the load
-          from [x0,#8] here happens after the initialization of td->arg.  */
-       ldar    xzr, [x0]
-       ldr     x0, [x0, #8]
-       RET
-       cfi_endproc
-       .size   _dl_tlsdesc_return_lazy, .-_dl_tlsdesc_return_lazy
-
        /* Handler for undefined weak TLS symbols.
           Prototype:
           _dl_tlsdesc_undefweak (tlsdesc *);
@@ -119,16 +97,10 @@ _dl_tlsdesc_return_lazy:
 _dl_tlsdesc_undefweak:
        str     x1, [sp, #-16]!
        cfi_adjust_cfa_offset (16)
-       /* The ldar here happens after the load from [x0] at the call site
-          (that is generated by the compiler as part of the TLS access ABI),
-          so it reads the same value (this function is the final value of
-          td->entry) and thus it synchronizes with the release store to
-          td->entry in _dl_tlsdesc_resolve_rela_fixup ensuring that the load
-          from [x0,#8] here happens after the initialization of td->arg.  */
-       ldar    xzr, [x0]
-       ldr     x0, [x0, #8]
+       DELOUSE (0)
+       ldr     PTR_REG (0), [x0, #PTR_SIZE]
        mrs     x1, tpidr_el0
-       sub     x0, x0, x1
+       sub     PTR_REG (0), PTR_REG (0), PTR_REG (1)
        ldr     x1, [sp], #16
        cfi_adjust_cfa_offset (-16)
        RET
@@ -151,7 +123,7 @@ _dl_tlsdesc_undefweak:
           _dl_tlsdesc_dynamic (struct tlsdesc *tdp)
           {
             struct tlsdesc_dynamic_arg *td = tdp->arg;
-            dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET);
+            dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + TCBHEAD_DTV);
             if (__builtin_expect (td->gen_count <= dtv[0].counter
                && (dtv[td->tlsinfo.ti_module].pointer.val
                    != TLS_DTV_UNALLOCATED),
@@ -170,46 +142,37 @@ _dl_tlsdesc_undefweak:
        cfi_startproc
        .align 2
 _dl_tlsdesc_dynamic:
-# define NSAVEXREGPAIRS 2
-       stp     x29, x30, [sp,#-(32+16*NSAVEXREGPAIRS)]!
-       cfi_adjust_cfa_offset (32+16*NSAVEXREGPAIRS)
-       mov     x29, sp
+       DELOUSE (0)
 
        /* Save just enough registers to support fast path, if we fall
           into slow path we will save additional registers.  */
-
-       stp     x1,  x2, [sp, #32+16*0]
-       stp     x3,  x4, [sp, #32+16*1]
+       stp     x1,  x2, [sp, #-32]!
+       stp     x3,  x4, [sp, #16]
+       cfi_adjust_cfa_offset (32)
+       cfi_rel_offset (x1, 0)
+       cfi_rel_offset (x2, 8)
+       cfi_rel_offset (x3, 16)
+       cfi_rel_offset (x4, 24)
 
        mrs     x4, tpidr_el0
-       /* The ldar here happens after the load from [x0] at the call site
-          (that is generated by the compiler as part of the TLS access ABI),
-          so it reads the same value (this function is the final value of
-          td->entry) and thus it synchronizes with the release store to
-          td->entry in _dl_tlsdesc_resolve_rela_fixup ensuring that the load
-          from [x0,#8] here happens after the initialization of td->arg.  */
-       ldar    xzr, [x0]
-       ldr     x1, [x0,#8]
-       ldr     x0, [x4]
-       ldr     x3, [x1,#16]
-       ldr     x2, [x0]
-       cmp     x3, x2
+       ldr     PTR_REG (1), [x0,#TLSDESC_ARG]
+       ldr     PTR_REG (0), [x4,#TCBHEAD_DTV]
+       ldr     PTR_REG (3), [x1,#TLSDESC_GEN_COUNT]
+       ldr     PTR_REG (2), [x0,#DTV_COUNTER]
+       cmp     PTR_REG (3), PTR_REG (2)
        b.hi    2f
-       ldr     x2, [x1]
-       add     x0, x0, x2, lsl #4
-       ldr     x0, [x0]
-       cmn     x0, #0x1
+       /* Load r2 = td->tlsinfo.ti_module and r3 = td->tlsinfo.ti_offset.  */
+       ldp     PTR_REG (2), PTR_REG (3), [x1,#TLSDESC_MODID]
+       add     PTR_REG (0), PTR_REG (0), PTR_REG (2), lsl #(PTR_LOG_SIZE + 1)
+       ldr     PTR_REG (0), [x0] /* Load val member of DTV entry.  */
+       cmp     PTR_REG (0), #TLS_DTV_UNALLOCATED
        b.eq    2f
-       ldr     x1, [x1,#8]
-       add     x0, x0, x1
-       sub     x0, x0, x4
+       sub     PTR_REG (3), PTR_REG (3), PTR_REG (4)
+       add     PTR_REG (0), PTR_REG (0), PTR_REG (3)
 1:
-       ldp      x1,  x2, [sp, #32+16*0]
-       ldp      x3,  x4, [sp, #32+16*1]
-
-       ldp     x29, x30, [sp], #(32+16*NSAVEXREGPAIRS)
-       cfi_adjust_cfa_offset (-32-16*NSAVEXREGPAIRS)
-# undef NSAVEXREGPAIRS
+       ldp      x3,  x4, [sp, #16]
+       ldp      x1,  x2, [sp], #32
+       cfi_adjust_cfa_offset (-32)
        RET
 2:
        /* This is the slow path. We need to call __tls_get_addr() which
@@ -217,15 +180,33 @@ _dl_tlsdesc_dynamic:
           callee will trash.  */
 
        /* Save the remaining registers that we must treat as caller save.  */
-# define NSAVEXREGPAIRS 7
-       stp      x5,  x6, [sp, #-16*NSAVEXREGPAIRS]!
+# define NSAVEXREGPAIRS 8
+       stp     x29, x30, [sp,#-16*NSAVEXREGPAIRS]!
        cfi_adjust_cfa_offset (16*NSAVEXREGPAIRS)
-       stp      x7,  x8, [sp, #16*1]
-       stp      x9, x10, [sp, #16*2]
-       stp     x11, x12, [sp, #16*3]
-       stp     x13, x14, [sp, #16*4]
-       stp     x15, x16, [sp, #16*5]
-       stp     x17, x18, [sp, #16*6]
+       cfi_rel_offset (x29, 0)
+       cfi_rel_offset (x30, 8)
+       mov     x29, sp
+       stp      x5,  x6, [sp, #16*1]
+       stp      x7,  x8, [sp, #16*2]
+       stp      x9, x10, [sp, #16*3]
+       stp     x11, x12, [sp, #16*4]
+       stp     x13, x14, [sp, #16*5]
+       stp     x15, x16, [sp, #16*6]
+       stp     x17, x18, [sp, #16*7]
+       cfi_rel_offset (x5, 16*1)
+       cfi_rel_offset (x6, 16*1+8)
+       cfi_rel_offset (x7, 16*2)
+       cfi_rel_offset (x8, 16*2+8)
+       cfi_rel_offset (x9, 16*3)
+       cfi_rel_offset (x10, 16*3+8)
+       cfi_rel_offset (x11, 16*4)
+       cfi_rel_offset (x12, 16*4+8)
+       cfi_rel_offset (x13, 16*5)
+       cfi_rel_offset (x14, 16*5+8)
+       cfi_rel_offset (x15, 16*6)
+       cfi_rel_offset (x16, 16*6+8)
+       cfi_rel_offset (x17, 16*7)
+       cfi_rel_offset (x18, 16*7+8)
 
        SAVE_Q_REGISTERS
 
@@ -233,134 +214,24 @@ _dl_tlsdesc_dynamic:
        bl      __tls_get_addr
 
        mrs     x1, tpidr_el0
-       sub     x0, x0, x1
+       sub     PTR_REG (0), PTR_REG (0), PTR_REG (1)
 
        RESTORE_Q_REGISTERS
 
-       ldp      x7,  x8, [sp, #16*1]
-       ldp      x9, x10, [sp, #16*2]
-       ldp     x11, x12, [sp, #16*3]
-       ldp     x13, x14, [sp, #16*4]
-       ldp     x15, x16, [sp, #16*5]
-       ldp     x17, x18, [sp, #16*6]
-       ldp      x5,  x6, [sp], #16*NSAVEXREGPAIRS
+       ldp      x5,  x6, [sp, #16*1]
+       ldp      x7,  x8, [sp, #16*2]
+       ldp      x9, x10, [sp, #16*3]
+       ldp     x11, x12, [sp, #16*4]
+       ldp     x13, x14, [sp, #16*5]
+       ldp     x15, x16, [sp, #16*6]
+       ldp     x17, x18, [sp, #16*7]
+
+       ldp     x29, x30, [sp], #16*NSAVEXREGPAIRS
        cfi_adjust_cfa_offset (-16*NSAVEXREGPAIRS)
+       cfi_restore (x29)
+       cfi_restore (x30)
        b       1b
        cfi_endproc
        .size   _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
 # undef NSAVEXREGPAIRS
 #endif
-
-       /* This function is a wrapper for a lazy resolver for TLS_DESC
-          RELA relocations.
-          When the actual resolver returns, it will have adjusted the
-          TLS descriptor such that we can tail-call it for it to return
-          the TP offset of the symbol.  */
-
-       .hidden _dl_tlsdesc_resolve_rela
-       .global _dl_tlsdesc_resolve_rela
-       .type   _dl_tlsdesc_resolve_rela,%function
-       cfi_startproc
-       .align 2
-_dl_tlsdesc_resolve_rela:
-#define        NSAVEXREGPAIRS 9
-       stp     x29, x30, [sp, #-(32+16*NSAVEXREGPAIRS)]!
-       cfi_adjust_cfa_offset (32+16*NSAVEXREGPAIRS)
-       mov     x29, sp
-       stp      x1,  x4, [sp, #32+16*0]
-       stp      x5,  x6, [sp, #32+16*1]
-       stp      x7,  x8, [sp, #32+16*2]
-       stp      x9, x10, [sp, #32+16*3]
-       stp     x11, x12, [sp, #32+16*4]
-       stp     x13, x14, [sp, #32+16*5]
-       stp     x15, x16, [sp, #32+16*6]
-       stp     x17, x18, [sp, #32+16*7]
-       str     x0,       [sp, #32+16*8]
-
-       SAVE_Q_REGISTERS
-
-       ldr     x1, [x3, #8]
-       bl      _dl_tlsdesc_resolve_rela_fixup
-
-       RESTORE_Q_REGISTERS
-
-       ldr     x0, [sp, #32+16*8]
-       ldr     x1, [x0]
-       blr     x1
-
-       ldp      x1,  x4, [sp, #32+16*0]
-       ldp      x5,  x6, [sp, #32+16*1]
-       ldp      x7,  x8, [sp, #32+16*2]
-       ldp      x9, x10, [sp, #32+16*3]
-       ldp     x11, x12, [sp, #32+16*4]
-       ldp     x13, x14, [sp, #32+16*5]
-       ldp     x15, x16, [sp, #32+16*6]
-       ldp     x17, x18, [sp, #32+16*7]
-       ldp     x29, x30, [sp], #(32+16*NSAVEXREGPAIRS)
-       cfi_adjust_cfa_offset (-32-16*NSAVEXREGPAIRS)
-       ldp     x2, x3, [sp], #16
-       cfi_adjust_cfa_offset (-16)
-       RET
-#undef NSAVEXREGPAIRS
-       cfi_endproc
-       .size   _dl_tlsdesc_resolve_rela, .-_dl_tlsdesc_resolve_rela
-
-       /* This function is a placeholder for lazy resolving of TLS
-       relocations.  Once some thread starts resolving a TLS
-       relocation, it sets up the TLS descriptor to use this
-       resolver, such that other threads that would attempt to
-       resolve it concurrently may skip the call to the original lazy
-       resolver and go straight to a condition wait.
-
-       When the actual resolver returns, it will have adjusted the
-       TLS descriptor such that we can tail-call it for it to return
-       the TP offset of the symbol.  */
-
-       .hidden _dl_tlsdesc_resolve_hold
-       .global _dl_tlsdesc_resolve_hold
-       .type   _dl_tlsdesc_resolve_hold,%function
-       cfi_startproc
-       .align 2
-_dl_tlsdesc_resolve_hold:
-#define        NSAVEXREGPAIRS 10
-1:
-       stp     x29, x30, [sp, #-(32+16*NSAVEXREGPAIRS)]!
-       cfi_adjust_cfa_offset (32+16*NSAVEXREGPAIRS)
-       mov     x29, sp
-       stp      x1,  x2, [sp, #32+16*0]
-       stp      x3,  x4, [sp, #32+16*1]
-       stp      x5,  x6, [sp, #32+16*2]
-       stp      x7,  x8, [sp, #32+16*3]
-       stp      x9, x10, [sp, #32+16*4]
-       stp     x11, x12, [sp, #32+16*5]
-       stp     x13, x14, [sp, #32+16*6]
-       stp     x15, x16, [sp, #32+16*7]
-       stp     x17, x18, [sp, #32+16*8]
-       str     x0,       [sp, #32+16*9]
-
-       SAVE_Q_REGISTERS
-
-       adr     x1, 1b
-       bl      _dl_tlsdesc_resolve_hold_fixup
-
-       RESTORE_Q_REGISTERS
-
-       ldr     x0, [sp, #32+16*9]
-       ldr     x1, [x0]
-       blr     x1
-
-       ldp      x1,  x2, [sp, #32+16*0]
-       ldp      x3,  x4, [sp, #32+16*1]
-       ldp      x5,  x6, [sp, #32+16*2]
-       ldp      x7,  x8, [sp, #32+16*3]
-       ldp      x9, x10, [sp, #32+16*4]
-       ldp     x11, x12, [sp, #32+16*5]
-       ldp     x13, x14, [sp, #32+16*6]
-       ldp     x15, x16, [sp, #32+16*7]
-       ldp     x17, x18, [sp, #32+16*8]
-       ldp     x29, x30, [sp], #(32+16*NSAVEXREGPAIRS)
-       cfi_adjust_cfa_offset (-32-16*NSAVEXREGPAIRS)
-       RET
-       cfi_endproc
-       .size   _dl_tlsdesc_resolve_hold, .-_dl_tlsdesc_resolve_hold
-#undef NSAVEXREGPAIRS