12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===// 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The LLVM Compiler Infrastructure 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is distributed under the University of Illinois Open Source 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// License. See LICENSE.TXT for details. 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Handle the __tls_get_addr call. 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// All this magic is specific to glibc and is required to workaround 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// the lack of interface that would tell us about the Dynamic TLS (DTLS). 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// https://sourceware.org/bugzilla/show_bug.cgi?id=16291 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The matters get worse because the glibc implementation changed between 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 2.18 and 2.19: 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// https://groups.google.com/forum/#!topic/address-sanitizer/BfwYD8HMxTM 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Before 2.19, every DTLS chunk is allocated with __libc_memalign, 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// which we intercept and thus know where is the DTLS. 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Since 2.19, DTLS chunks are allocated with __signal_safe_memalign, 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// which is an internal function that wraps a mmap call, neither of which 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// we can intercept. Luckily, __signal_safe_memalign has a simple parseable 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// header which we can use. 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef SANITIZER_TLS_GET_ADDR_H 302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define SANITIZER_TLS_GET_ADDR_H 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common.h" 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __sanitizer { 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct DTLS { 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Array of DTLS chunks for the current Thread. 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // If beg == 0, the chunk is unused. 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines struct DTV { 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr beg, size; 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines }; 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr dtv_size; 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines DTV *dtv; // dtv_size elements, allocated by MmapOrDie. 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cc 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr last_memalign_size; 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines uptr last_memalign_ptr; 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}; 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// Returns pointer and size of a linker-allocated TLS block. 525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// Each block is returned exactly once. 535d71de26cedae3dafc17449fe0182045c0bd20e8Stephen HinesDTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res); 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid DTLS_on_libc_memalign(void *ptr, uptr size); 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDTLS *DTLS_Get(); 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid DTLS_Destroy(); // Make sure to call this before the thread is destroyed. 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} // namespace __sanitizer 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // SANITIZER_TLS_GET_ADDR_H 61