summaryrefslogtreecommitdiff
path: root/gnu/llvm/compiler-rt
diff options
context:
space:
mode:
authorRobert Nagy <robert@cvs.openbsd.org>2021-11-12 10:08:36 +0000
committerRobert Nagy <robert@cvs.openbsd.org>2021-11-12 10:08:36 +0000
commit2cf182e58430457230d4fe3042e29d50082478bf (patch)
treec159bd3ef2111aeea14e124a5341107b8d2230ce /gnu/llvm/compiler-rt
parent4fbd3e11caf31cd3bc6e893f332752b395d80542 (diff)
backport https://reviews.llvm.org/D107127 to fix shared libraries using emutls
Our emulated TLS implementation relies on local state (e.g. for the pthread key), and if we duplicate this state across different shared libraries, accesses to the same TLS variable from different shared libraries will yield different results (see https://github.com/android/ndk/issues/1551 for an example). __emutls_get_address is the only external entry point for emulated TLS, and by making it default visibility and weak, we can rely on the dynamic linker to coalesce multiple copies at runtime and ensure a single unique copy of TLS state. This is a best effort; Also bump the libc++abi minor because now it picks up the __emutls_get_address symbol. ok kettenis@
Diffstat (limited to 'gnu/llvm/compiler-rt')
-rw-r--r--gnu/llvm/compiler-rt/lib/builtins/emutls.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/gnu/llvm/compiler-rt/lib/builtins/emutls.c b/gnu/llvm/compiler-rt/lib/builtins/emutls.c
index e0aa19155f7..b546273d6d3 100644
--- a/gnu/llvm/compiler-rt/lib/builtins/emutls.c
+++ b/gnu/llvm/compiler-rt/lib/builtins/emutls.c
@@ -375,6 +375,21 @@ emutls_get_address_array(uintptr_t index) {
return array;
}
+#ifndef _WIN32
+// Our emulated TLS implementation relies on local state (e.g. for the pthread
+// key), and if we duplicate this state across different shared libraries,
+// accesses to the same TLS variable from different shared libraries will yield
+// different results (see https://github.com/android/ndk/issues/1551 for an
+// example). __emutls_get_address is the only external entry point for emulated
+// TLS, and by making it default visibility and weak, we can rely on the dynamic
+// linker to coalesce multiple copies at runtime and ensure a single unique copy
+// of TLS state. This is a best effort; it won't work if the user is linking
+// with -Bsymbolic or -Bsymbolic-functions, and it also won't work on Windows,
+// where the dynamic linker has no notion of coalescing weak symbols at runtime.
+// A more robust solution would be to create a separate shared library for
+// emulated TLS, to ensure a single copy of its state.
+__attribute__((visibility("default"), weak))
+#endif
void *__emutls_get_address(__emutls_control *control) {
uintptr_t index = emutls_get_index(control);
emutls_address_array *array = emutls_get_address_array(index--);