[all-commits] [llvm/llvm-project] afec95: [sanitizer] Simplify GetTls with dl_iterate_phdr o...

Fangrui Song via All-commits all-commits at lists.llvm.org
Thu Apr 15 15:34:59 PDT 2021


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: afec953857ffd682cb4119e7950f3593efbaaa81
      https://github.com/llvm/llvm-project/commit/afec953857ffd682cb4119e7950f3593efbaaa81
  Author: Fangrui Song <i at maskray.me>
  Date:   2021-04-15 (Thu, 15 Apr 2021)

  Changed paths:
    M compiler-rt/lib/asan/asan_rtl.cpp
    M compiler-rt/lib/asan/asan_thread.cpp
    M compiler-rt/lib/sanitizer_common/sanitizer_linux.h
    M compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
    M compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp
    M compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
    M compiler-rt/test/asan/TestCases/Linux/static_tls.cpp
    M compiler-rt/test/lsan/TestCases/many_tls_keys_pthread.cpp

  Log Message:
  -----------
  [sanitizer] Simplify GetTls with dl_iterate_phdr on Linux and use it on musl/FreeBSD

... 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




More information about the All-commits mailing list