aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/arm
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2017-10-20 17:35:12 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2017-11-03 14:47:35 +0000
commit0ca3d1d6d096e222346c74601d50e9013c8bb25d (patch)
tree02b9894345e53b26c42029f8147a360811bf29fc /sysdeps/arm
parent2c1d4e5fe4e722e0b747d6bddd7ce3a6b1766c52 (diff)
downloadglibc-0ca3d1d6d096e222346c74601d50e9013c8bb25d.tar
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.
Diffstat (limited to 'sysdeps/arm')
-rw-r--r--sysdeps/arm/dl-machine.h24
1 files changed, 15 insertions, 9 deletions
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);