aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2016-12-02 16:52:57 +0100
committerFlorian Weimer <fweimer@redhat.com>2016-12-02 16:52:57 +0100
commit67aae64512cb42332f76a83e84ac2bc608ad4ad2 (patch)
treef53b04d34129d9f7b60ce44dfb7c0ac06329ed12 /sysdeps
parent8068094f6e2b3d29acbed8d738deaaf5cae5e320 (diff)
downloadglibc-67aae64512cb42332f76a83e84ac2bc608ad4ad2.tar
glibc-67aae64512cb42332f76a83e84ac2bc608ad4ad2.tar.gz
glibc-67aae64512cb42332f76a83e84ac2bc608ad4ad2.tar.bz2
glibc-67aae64512cb42332f76a83e84ac2bc608ad4ad2.zip
aarch64: Use explicit offsets in _dl_tlsdesc_dynamic
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.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/aarch64/dl-tlsdesc.S18
-rw-r--r--sysdeps/aarch64/tlsdesc.sym3
2 files changed, 12 insertions, 9 deletions
diff --git a/sysdeps/aarch64/dl-tlsdesc.S b/sysdeps/aarch64/dl-tlsdesc.S
index 42fa943859..9e557dd134 100644
--- a/sysdeps/aarch64/dl-tlsdesc.S
+++ b/sysdeps/aarch64/dl-tlsdesc.S
@@ -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 63766af612..a06a719779 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