diff mbox

aarch64: Use explicit offsets in _dl_tlsdesc_dynamic

Message ID 20161201144952.1A8AB439942E0@oldenburg.str.redhat.com
State New
Headers show

Commit Message

Florian Weimer Dec. 1, 2016, 2:49 p.m. UTC
Commit 389d1f1b232b3d6b9d73ee2c50e543ace6675621 (“Partial ILP32
support for aarch64”) broke dynamic TLS support because a load
offset changed:

 0000000000000030 <_dl_tlsdesc_dynamic>:
   30:  a9bc7bfd        stp     x29, x30, [sp,#-64]!
   34:  910003fd        mov     x29, sp
   38:  a9020be1        stp     x1, x2, [sp,#32]
   3c:  a90313e3        stp     x3, x4, [sp,#48]
   40:  d53bd044        mrs     x4, tpidr_el0
   44:  c8dffc1f        ldar    xzr, [x0]
   48:  f9400401        ldr     x1, [x0,#8]
   4c:  f9400080        ldr     x0, [x4]
   50:  f9400823        ldr     x3, [x1,#16]
   54:  f9400002        ldr     x2, [x0]
   58:  eb02007f        cmp     x3, x2
   5c:  540001a8        b.hi    90 <_dl_tlsdesc_dynamic+0x60>
   60:  f9400022        ldr     x2, [x1]
   64:  8b021000        add     x0, x0, x2, lsl #4
   68:  f9400000        ldr     x0, [x0]
   6c:  b100041f        cmn     x0, #0x1
   70:  54000100        b.eq    90 <_dl_tlsdesc_dynamic+0x60>
-  74:  f9400421        ldr     x1, [x1,#8]
+  74:  f9400821        ldr     x1, [x1,#16]
   78:  8b010000        add     x0, x0, x1
…

This commit introduces explicit struct offsets, generated
from the C headers, fixing the regression.

2016-12-01  Florian Weimer  <fweimer@redhat.com>

	* sysdeps/aarch64/tlsdesc.sym (TCBHEAD_DTV, DTV_COUNTER)
	(TLS_DTV_UNALLOCATED): Add.
	* sysdeps/aarch64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Use explicit
	offsets.

Comments

Szabolcs Nagy Dec. 1, 2016, 3:06 p.m. UTC | #1
On 01/12/16 14:49, Florian Weimer wrote:
> Commit 389d1f1b232b3d6b9d73ee2c50e543ace6675621 (“Partial ILP32
> support for aarch64”) broke dynamic TLS support because a load
> offset changed:
> 
>  0000000000000030 <_dl_tlsdesc_dynamic>:
>    30:  a9bc7bfd        stp     x29, x30, [sp,#-64]!
>    34:  910003fd        mov     x29, sp
>    38:  a9020be1        stp     x1, x2, [sp,#32]
>    3c:  a90313e3        stp     x3, x4, [sp,#48]
>    40:  d53bd044        mrs     x4, tpidr_el0
>    44:  c8dffc1f        ldar    xzr, [x0]
>    48:  f9400401        ldr     x1, [x0,#8]
>    4c:  f9400080        ldr     x0, [x4]
>    50:  f9400823        ldr     x3, [x1,#16]
>    54:  f9400002        ldr     x2, [x0]
>    58:  eb02007f        cmp     x3, x2
>    5c:  540001a8        b.hi    90 <_dl_tlsdesc_dynamic+0x60>
>    60:  f9400022        ldr     x2, [x1]
>    64:  8b021000        add     x0, x0, x2, lsl #4
>    68:  f9400000        ldr     x0, [x0]
>    6c:  b100041f        cmn     x0, #0x1
>    70:  54000100        b.eq    90 <_dl_tlsdesc_dynamic+0x60>
> -  74:  f9400421        ldr     x1, [x1,#8]
> +  74:  f9400821        ldr     x1, [x1,#16]
>    78:  8b010000        add     x0, x0, x1
> …
> 

nice catch.

> This commit introduces explicit struct offsets, generated
> from the C headers, fixing the regression.
> 
> 2016-12-01  Florian Weimer  <fweimer@redhat.com>
> 
> 	* sysdeps/aarch64/tlsdesc.sym (TCBHEAD_DTV, DTV_COUNTER)
> 	(TLS_DTV_UNALLOCATED): Add.
> 	* sysdeps/aarch64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Use explicit
> 	offsets.
> 
> diff --git a/sysdeps/aarch64/dl-tlsdesc.S b/sysdeps/aarch64/dl-tlsdesc.S
> index 42fa943..37a0211 100644
> --- a/sysdeps/aarch64/dl-tlsdesc.S
> +++ b/sysdeps/aarch64/dl-tlsdesc.S
> @@ -21,7 +21,7 @@
>  #include <sysdep.h>
>  #include <tls.h>
>  #include "tlsdesc.h"
> -
> +	

whitespace change

the rest looks ok to me (but i cannot approve).

>  #define NSAVEDQREGPAIRS	16
>  #define SAVE_Q_REGISTERS				\
>  	stp	q0, q1,	[sp, #-32*NSAVEDQREGPAIRS]!;	\
> @@ -154,7 +154,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),
> @@ -193,18 +193,18 @@ _dl_tlsdesc_dynamic:
>  	   td->entry in _dl_tlsdesc_resolve_rela_fixup ensuring that the load
>  	   from [x0,#PTR_SIZE] here happens after the initialization of td->arg.  */
>  	ldar	PTR_REG (zr), [x0]
> -	ldr	PTR_REG (1), [x0,#PTR_SIZE]
> -	ldr	PTR_REG (0), [x4]
> -	ldr	PTR_REG (3), [x1,#(PTR_SIZE * 2)]
> -	ldr	PTR_REG (2), [x0]
> +	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	PTR_REG (2), [x1]
> +	ldr	PTR_REG (2), [x1,#TLSDESC_MODID]
>  	add	PTR_REG (0), PTR_REG (0), PTR_REG (2), lsl #(PTR_LOG_SIZE + 1)
> -	ldr	PTR_REG (0), [x0]
> -	cmn	x0, #0x1
> +	ldr	PTR_REG (0), [x0] /* Load val member of DTV entry.  */
> +	cmp	x0, #TLS_DTV_UNALLOCATED
>  	b.eq	2f
> -	ldr	PTR_REG (1), [x1,#(PTR_SIZE * 2)]
> +	ldr	PTR_REG (1), [x1,#TLSDESC_MODOFF]
>  	add	PTR_REG (0), PTR_REG (0), PTR_REG (1)
>  	sub	PTR_REG (0), PTR_REG (0), PTR_REG (4)
>  1:
> diff --git a/sysdeps/aarch64/tlsdesc.sym b/sysdeps/aarch64/tlsdesc.sym
> index 63766af..a06a719 100644
> --- a/sysdeps/aarch64/tlsdesc.sym
> +++ b/sysdeps/aarch64/tlsdesc.sym
> @@ -13,3 +13,6 @@ TLSDESC_ARG			offsetof(struct tlsdesc, arg)
>  TLSDESC_GEN_COUNT	offsetof(struct tlsdesc_dynamic_arg, gen_count)
>  TLSDESC_MODID		offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module)
>  TLSDESC_MODOFF		offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset)
> +TCBHEAD_DTV		offsetof(tcbhead_t, dtv)
> +DTV_COUNTER		offsetof(dtv_t, counter)
> +TLS_DTV_UNALLOCATED	TLS_DTV_UNALLOCATED
>
diff mbox

Patch

diff --git a/sysdeps/aarch64/dl-tlsdesc.S b/sysdeps/aarch64/dl-tlsdesc.S
index 42fa943..37a0211 100644
--- a/sysdeps/aarch64/dl-tlsdesc.S
+++ b/sysdeps/aarch64/dl-tlsdesc.S
@@ -21,7 +21,7 @@ 
 #include <sysdep.h>
 #include <tls.h>
 #include "tlsdesc.h"
-
+	
 #define NSAVEDQREGPAIRS	16
 #define SAVE_Q_REGISTERS				\
 	stp	q0, q1,	[sp, #-32*NSAVEDQREGPAIRS]!;	\
@@ -154,7 +154,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),
@@ -193,18 +193,18 @@  _dl_tlsdesc_dynamic:
 	   td->entry in _dl_tlsdesc_resolve_rela_fixup ensuring that the load
 	   from [x0,#PTR_SIZE] here happens after the initialization of td->arg.  */
 	ldar	PTR_REG (zr), [x0]
-	ldr	PTR_REG (1), [x0,#PTR_SIZE]
-	ldr	PTR_REG (0), [x4]
-	ldr	PTR_REG (3), [x1,#(PTR_SIZE * 2)]
-	ldr	PTR_REG (2), [x0]
+	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	PTR_REG (2), [x1]
+	ldr	PTR_REG (2), [x1,#TLSDESC_MODID]
 	add	PTR_REG (0), PTR_REG (0), PTR_REG (2), lsl #(PTR_LOG_SIZE + 1)
-	ldr	PTR_REG (0), [x0]
-	cmn	x0, #0x1
+	ldr	PTR_REG (0), [x0] /* Load val member of DTV entry.  */
+	cmp	x0, #TLS_DTV_UNALLOCATED
 	b.eq	2f
-	ldr	PTR_REG (1), [x1,#(PTR_SIZE * 2)]
+	ldr	PTR_REG (1), [x1,#TLSDESC_MODOFF]
 	add	PTR_REG (0), PTR_REG (0), PTR_REG (1)
 	sub	PTR_REG (0), PTR_REG (0), PTR_REG (4)
 1:
diff --git a/sysdeps/aarch64/tlsdesc.sym b/sysdeps/aarch64/tlsdesc.sym
index 63766af..a06a719 100644
--- a/sysdeps/aarch64/tlsdesc.sym
+++ b/sysdeps/aarch64/tlsdesc.sym
@@ -13,3 +13,6 @@  TLSDESC_ARG			offsetof(struct tlsdesc, arg)
 TLSDESC_GEN_COUNT	offsetof(struct tlsdesc_dynamic_arg, gen_count)
 TLSDESC_MODID		offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module)
 TLSDESC_MODOFF		offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset)
+TCBHEAD_DTV		offsetof(tcbhead_t, dtv)
+DTV_COUNTER		offsetof(dtv_t, counter)
+TLS_DTV_UNALLOCATED	TLS_DTV_UNALLOCATED