diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sysdeps/aarch64/dl-machine.h | 19 |
2 files changed, 19 insertions, 5 deletions
@@ -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))) { |