This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] aarch64: Use explicit offsets in _dl_tlsdesc_dynamic
- From: Szabolcs Nagy <szabolcs dot nagy at arm dot com>
- To: Florian Weimer <fweimer at redhat dot com>, <libc-alpha at sourceware dot org>
- Cc: <nd at arm dot com>
- Date: Thu, 1 Dec 2016 15:06:49 +0000
- Subject: Re: [PATCH] aarch64: Use explicit offsets in _dl_tlsdesc_dynamic
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Szabolcs dot Nagy at arm dot com;
- Nodisclaimer: True
- References: <20161201144952.1A8AB439942E0@oldenburg.str.redhat.com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
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
>