Message ID | 20161201144952.1A8AB439942E0@oldenburg.str.redhat.com |
---|---|
State | New |
Headers | show |
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 --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