forked from OSchip/llvm-project
[builtins] Try to ensure single copy of emulated TLS state
Multiple copies of emulated TLS state means inconsistent results when accessing the same thread-local variable from different shared objects (https://github.com/android/ndk/issues/1551). Making `__emutls_get_address` be a weak default visibility symbol should make the dynamic linker ensure only a single copy gets used at runtime. This is best-effort, but the more robust approach of putting emulated TLS into its own shared object would (a) be a much bigger change, and (b) shared objects are pretty heavyweight, and adding a new one to a space-constrained environment isn't an easy sell. Given the expected rarity of direct accesses to emulated TLS variables across different shared objects, the best-effort approach should suffice. Reviewed By: danalbert, rprichard Differential Revision: https://reviews.llvm.org/D107127
This commit is contained in:
parent
6ea2f31f3d
commit
b8f04a670f
|
@ -374,6 +374,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--);
|
||||
|
|
Loading…
Reference in New Issue