1276789Sdim//===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===// 2276789Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6276789Sdim// 7276789Sdim//===----------------------------------------------------------------------===// 8276789Sdim// 9276789Sdim// Handle the __tls_get_addr call. 10276789Sdim// 11276789Sdim// All this magic is specific to glibc and is required to workaround 12276789Sdim// the lack of interface that would tell us about the Dynamic TLS (DTLS). 13276789Sdim// https://sourceware.org/bugzilla/show_bug.cgi?id=16291 14276789Sdim// 15276789Sdim// The matters get worse because the glibc implementation changed between 16276789Sdim// 2.18 and 2.19: 17276789Sdim// https://groups.google.com/forum/#!topic/address-sanitizer/BfwYD8HMxTM 18276789Sdim// 19276789Sdim// Before 2.19, every DTLS chunk is allocated with __libc_memalign, 20276789Sdim// which we intercept and thus know where is the DTLS. 21276789Sdim// Since 2.19, DTLS chunks are allocated with __signal_safe_memalign, 22276789Sdim// which is an internal function that wraps a mmap call, neither of which 23276789Sdim// we can intercept. Luckily, __signal_safe_memalign has a simple parseable 24276789Sdim// header which we can use. 25276789Sdim// 26276789Sdim//===----------------------------------------------------------------------===// 27276789Sdim 28276789Sdim#ifndef SANITIZER_TLS_GET_ADDR_H 29276789Sdim#define SANITIZER_TLS_GET_ADDR_H 30276789Sdim 31276789Sdim#include "sanitizer_common.h" 32276789Sdim 33276789Sdimnamespace __sanitizer { 34276789Sdim 35276789Sdimstruct DTLS { 36276789Sdim // Array of DTLS chunks for the current Thread. 37276789Sdim // If beg == 0, the chunk is unused. 38276789Sdim struct DTV { 39276789Sdim uptr beg, size; 40276789Sdim }; 41276789Sdim 42276789Sdim uptr dtv_size; 43276789Sdim DTV *dtv; // dtv_size elements, allocated by MmapOrDie. 44276789Sdim 45360784Sdim // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cpp 46276789Sdim uptr last_memalign_size; 47276789Sdim uptr last_memalign_ptr; 48276789Sdim}; 49276789Sdim 50276789Sdim// Returns pointer and size of a linker-allocated TLS block. 51276789Sdim// Each block is returned exactly once. 52288943SdimDTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res, uptr static_tls_begin, 53288943Sdim uptr static_tls_end); 54276789Sdimvoid DTLS_on_libc_memalign(void *ptr, uptr size); 55276789SdimDTLS *DTLS_Get(); 56276789Sdimvoid DTLS_Destroy(); // Make sure to call this before the thread is destroyed. 57321369Sdim// Returns true if DTLS of suspended thread is in destruction process. 58321369Sdimbool DTLSInDestruction(DTLS *dtls); 59276789Sdim 60276789Sdim} // namespace __sanitizer 61276789Sdim 62276789Sdim#endif // SANITIZER_TLS_GET_ADDR_H 63