diff options
author | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2017-10-20 17:35:12 +0100 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2017-11-03 14:47:35 +0000 |
commit | 0ca3d1d6d096e222346c74601d50e9013c8bb25d (patch) | |
tree | 02b9894345e53b26c42029f8147a360811bf29fc | |
parent | [BZ #17078] arm: remove prelinker support for R_ARM_TLS_DESC (diff) | |
download | glibc-0ca3d1d6d096e222346c74601d50e9013c8bb25d.tar.gz glibc-0ca3d1d6d096e222346c74601d50e9013c8bb25d.tar.bz2 glibc-0ca3d1d6d096e222346c74601d50e9013c8bb25d.zip |
[BZ #18572] arm: Disable lazy initialization of tlsdesc entries
Follow up to
https://sourceware.org/ml/libc-alpha/2015-11/msg00272.html
Always do tls descriptor initialization at load time during relocation
processing (as if DF_BIND_NOW were set for the binary) to avoid barriers
at every tls access. This patch mimics bind-now semantics in the lazy
relocation code of the arm target (elf_machine_lazy_rel).
Ideally the static linker should be updated too to not emit tlsdesc
relocs in DT_REL*, so elf_machine_lazy_rel is not called on them at all.
[BZ #18572]
* sysdeps/arm/dl-machine.h (elf_machine_lazy_rel): Do symbol binding
non-lazily for R_ARM_TLS_DESC.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/arm/dl-machine.h | 24 |
2 files changed, 21 insertions, 9 deletions
@@ -1,5 +1,11 @@ 2017-11-03 Szabolcs Nagy <szabolcs.nagy@arm.com> + [BZ #18572] + * sysdeps/arm/dl-machine.h (elf_machine_lazy_rel): Do symbol binding + non-lazily for R_ARM_TLS_DESC. + +2017-11-03 Szabolcs Nagy <szabolcs.nagy@arm.com> + [BZ #17078] * sysdeps/arm/dl-machine.h (elf_machine_rela): Remove the R_ARM_TLS_DESC case. diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index bf5f5d205c..c59386f515 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -669,15 +669,21 @@ elf_machine_lazy_rel (struct link_map *map, } else if (__builtin_expect (r_type == R_ARM_TLS_DESC, 1)) { - struct tlsdesc volatile *td = - (struct tlsdesc volatile *)reloc_addr; - - /* The linker must have given us the parameter we need in the - first GOT entry, and left the second one empty. We fill the - latter with the resolver address. */ - assert (td->entry == 0); - td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)]) - + map->l_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; + + 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_rel (map, reloc, sym, version, reloc_addr, skip_ifunc); } else _dl_reloc_bad_type (map, r_type, 1); |