sanitizer_tls_get_addr.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===//
  2. //
  3. // This file is distributed under the University of Illinois Open Source
  4. // License. See LICENSE.TXT for details.
  5. //
  6. //===----------------------------------------------------------------------===//
  7. //
  8. // Handle the __tls_get_addr call.
  9. //
  10. // All this magic is specific to glibc and is required to workaround
  11. // the lack of interface that would tell us about the Dynamic TLS (DTLS).
  12. // https://sourceware.org/bugzilla/show_bug.cgi?id=16291
  13. //
  14. // The matters get worse because the glibc implementation changed between
  15. // 2.18 and 2.19:
  16. // https://groups.google.com/forum/#!topic/address-sanitizer/BfwYD8HMxTM
  17. //
  18. // Before 2.19, every DTLS chunk is allocated with __libc_memalign,
  19. // which we intercept and thus know where is the DTLS.
  20. // Since 2.19, DTLS chunks are allocated with __signal_safe_memalign,
  21. // which is an internal function that wraps a mmap call, neither of which
  22. // we can intercept. Luckily, __signal_safe_memalign has a simple parseable
  23. // header which we can use.
  24. //
  25. //===----------------------------------------------------------------------===//
  26. #ifndef SANITIZER_TLS_GET_ADDR_H
  27. #define SANITIZER_TLS_GET_ADDR_H
  28. #include "sanitizer_common.h"
  29. namespace __sanitizer {
  30. struct DTLS {
  31. // Array of DTLS chunks for the current Thread.
  32. // If beg == 0, the chunk is unused.
  33. struct DTV {
  34. uptr beg, size;
  35. };
  36. uptr dtv_size;
  37. DTV *dtv; // dtv_size elements, allocated by MmapOrDie.
  38. // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cc
  39. uptr last_memalign_size;
  40. uptr last_memalign_ptr;
  41. };
  42. // Returns pointer and size of a linker-allocated TLS block.
  43. // Each block is returned exactly once.
  44. DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res);
  45. void DTLS_on_libc_memalign(void *ptr, uptr size);
  46. DTLS *DTLS_Get();
  47. void DTLS_Destroy(); // Make sure to call this before the thread is destroyed.
  48. } // namespace __sanitizer
  49. #endif // SANITIZER_TLS_GET_ADDR_H