HomePhabricator

[sanitizer] Simplify GetTls with dl_iterate_phdr on Linux

Authored by MaskRay on Sun, Apr 4, 3:35 PM.

Description

[sanitizer] Simplify GetTls with dl_iterate_phdr on Linux

This was reverted by f176803ef1f4050a350e01868d64fe09a674d3bf due to
Ubuntu 16.04 x86-64 glibc 2.23 problems.
This commit additionally calls __tls_get_addr({modid,0}) to work around the
dlpi_tls_data==NULL issues for glibc<2.25
(https://sourceware.org/bugzilla/show_bug.cgi?id=19826)

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 entirely. 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 simplification enables D99566 for TLS Variant I architectures.

See https://reviews.llvm.org/D93972#2480556 for analysis on GetTls usage
across various sanitizers.

Differential Revision: https://reviews.llvm.org/D98926