... so that FreeBSD specific GetTls/glibc specific pthread_self code can be
removed. This also helps FreeBSD arm64/powerpc64 which don't have GetTls
implementation yet.
GetTls is the range of
* thread control block and optional TLS_PRE_TCB_SIZE
* static TLS blocks plus static TLS surplus
On glibc, lsan requires the range to include
`pthread::{specific_1stblock,specific}` so that allocations only referenced by
`pthread_setspecific` can be scanned.
This patch uses `dl_iterate_phdr` to collect TLS blocks. Find the one
with `dlpi_tls_modid==1` as one of the initially loaded module, then find
consecutive ranges. The boundaries give us addr and size.
This allows us to drop the glibc internal `_dl_get_tls_static_info` and
`InitTlsSize`. However, huge glibc x86-64 binaries with numerous shared objects
may observe time complexity penalty, so exclude them for now. Use the simplified
method with non-Android Linux for now, but in theory this can be used with *BSD
and potentially other ELF OSes.
This removal of RISC-V `__builtin_thread_pointer` makes the code compilable with
more compiler versions (added in Clang in 2020-03, added in GCC in 2020-07).
This simplification enables D99566 for TLS Variant I architectures.
Note: as of musl 1.2.2 and FreeBSD 12.2, dlpi_tls_data returned by
dl_iterate_phdr is not desired: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=254774
This can be worked around by using `__tls_get_addr({modid,0})` instead
of `dlpi_tls_data`. The workaround can be shared with the workaround for glibc<2.25.
This fixes some tests on Alpine Linux x86-64 (musl)
```
test/lsan/Linux/cleanup_in_tsd_destructor.c
test/lsan/Linux/fork.cpp
test/lsan/Linux/fork_threaded.cpp
test/lsan/Linux/use_tls_static.cpp
test/lsan/many_tls_keys_thread.cpp
test/msan/tls_reuse.cpp
```
and `test/lsan/TestCases/many_tls_keys_pthread.cpp` on glibc aarch64.
The number of sanitizer test failures does not change on FreeBSD/amd64 12.2.
Differential Revision: https://reviews.llvm.org/D98926
36 lines
884 B
C++
36 lines
884 B
C++
// REQUIRES: asan-64-bits
|
|
// Regression test: __tls_get_addr interceptor must recognize static TLS.
|
|
//
|
|
// RUN: %clangxx_asan -DSHARED %s -shared -o %t-so.so -fPIC
|
|
// RUN: %clangxx_asan %s -ldl -pthread -o %t %t-so.so
|
|
// RUN: %env_asan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s
|
|
|
|
// CHECK: before
|
|
// CHECK: __tls_get_addr: static tls
|
|
// CHECK: after
|
|
|
|
// XFAIL: aarch64
|
|
// binutils 2.26 has a change that causes this test to fail on powerpc64.
|
|
// UNSUPPORTED: powerpc64
|
|
|
|
/// We call __tls_get_addr early in GetTls to work around an issue for glibc<2.25,
|
|
/// so we don't get a log for f().
|
|
// REQUIRES: glibc-2.27
|
|
|
|
#ifndef SHARED
|
|
#include <stdio.h>
|
|
|
|
unsigned *f();
|
|
int main(int argc, char *argv[]) {
|
|
fprintf(stderr, "before\n");
|
|
f();
|
|
fprintf(stderr, "after\n");
|
|
return 0;
|
|
}
|
|
#else // SHARED
|
|
static __thread unsigned ThreadLocal;
|
|
unsigned *f() {
|
|
return &ThreadLocal;
|
|
}
|
|
#endif
|