aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/aarch64/dl-machine.h19
2 files changed, 19 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 44e18dd..0126d77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2017-11-03 Szabolcs Nagy <szabolcs.nagy@arm.com>
+ * sysdeps/aarch64/dl-machine.h (elf_machine_lazy_rel): Do symbol
+ binding and initialization non-lazily for R_AARCH64_TLSDESC.
+
+2017-11-03 Szabolcs Nagy <szabolcs.nagy@arm.com>
+
* elf/tlsdeschtab.h (_dl_tls_resolve_early_return_p): Mark unused.
(_dl_tlsdesc_wake_up_held_fixups): Likewise.
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index e765612..837e281 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -399,12 +399,21 @@ elf_machine_lazy_rel (struct link_map *map,
}
else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1))
{
- struct tlsdesc volatile *td =
- (struct tlsdesc volatile *)reloc_addr;
+ const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info);
+ const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]);
+ const ElfW (Sym) *sym = &symtab[symndx];
+ const struct r_found_version *version = NULL;
- td->arg = (void*)reloc;
- td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
- + map->l_addr);
+ if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ {
+ const ElfW (Half) *vernum =
+ (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
+ version = &map->l_versions[vernum[symndx] & 0x7fff];
+ }
+
+ /* Always initialize TLS descriptors completely, because lazy
+ initialization requires synchronization at every TLS access. */
+ elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
}
else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE)))
{