diff options
author | Sergey Matveev <earthdok@google.com> | 2014-01-23 15:10:35 +0000 |
---|---|---|
committer | Sergey Matveev <earthdok@google.com> | 2014-01-23 15:10:35 +0000 |
commit | f17f4176b74547e6f629f3b3879f20aa465a2138 (patch) | |
tree | 5eeee65668bac832f6ea2cec6e5bd74c731e35ce /lib/lsan/lsan_common_linux.cc | |
parent | 4c37ee69d9ecf1d0e820e3ebe19b18792b2e9124 (diff) |
[lsan] Expand a comment to document our dynamic TLS hack.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@199900 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/lsan/lsan_common_linux.cc')
-rw-r--r-- | lib/lsan/lsan_common_linux.cc | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cc index 2daee3fdf..49329826c 100644 --- a/lib/lsan/lsan_common_linux.cc +++ b/lib/lsan/lsan_common_linux.cc @@ -130,6 +130,21 @@ static void ProcessPlatformSpecificAllocationsCb(uptr chunk, void *arg) { // Handles dynamically allocated TLS blocks by treating all chunks allocated // from ld-linux.so as reachable. +// Dynamic TLS blocks contain the TLS variables of dynamically loaded modules. +// They are allocated with a __libc_memalign() call in allocate_and_init() +// (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those +// blocks, but we can make sure they come from our own allocator by intercepting +// __libc_memalign(). On top of that, there is no easy way to reach them. Their +// addresses are stored in a dynamically allocated array (the DTV) which is +// referenced from the static TLS. Unfortunately, we can't just rely on the DTV +// being reachable from the static TLS, and the dynamic TLS being reachable from +// the DTV. This is because the initial DTV is allocated before our interception +// mechanism kicks in, and thus we don't recognize it as allocated memory. We +// can't special-case it either, since we don't know its size. +// Our solution is to include in the root set all allocations made from +// ld-linux.so (which is where allocate_and_init() is implemented). This is +// guaranteed to include all dynamic TLS blocks (and possibly other allocations +// which we don't care about). void ProcessPlatformSpecificAllocations(Frontier *frontier) { if (!flags()->use_tls) return; if (!linker) return; |