1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov//===-- tsan_mman.cc ------------------------------------------------------===//
27ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
37ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//                     The LLVM Compiler Infrastructure
47ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
57ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is distributed under the University of Illinois Open Source
67ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// License. See LICENSE.TXT for details.
77ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
87ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
97ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector.
117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//
127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "sanitizer_common/sanitizer_allocator_interface.h"
14f7667cc84cdd8923c0b6c7cfc92b7bd5692ce18cAlexey Samsonov#include "sanitizer_common/sanitizer_common.h"
152e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov#include "sanitizer_common/sanitizer_placement_new.h"
167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h"
177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_rtl.h"
187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_report.h"
197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_flags.h"
207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
214f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov// May be overriden by front-end.
224f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovextern "C" void WEAK __tsan_malloc_hook(void *ptr, uptr size) {
234f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  (void)ptr;
244f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  (void)size;
254f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov}
265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesextern "C" void WEAK __sanitizer_malloc_hook(void *ptr, uptr size) {
275d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  (void)ptr;
285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  (void)size;
295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
304f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov
314f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovextern "C" void WEAK __tsan_free_hook(void *ptr) {
324f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  (void)ptr;
334f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov}
345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesextern "C" void WEAK __sanitizer_free_hook(void *ptr) {
355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  (void)ptr;
36f51c3860ce0a1ae81d0dc9da27db0693718db18eDmitry Vyukov}
37f51c3860ce0a1ae81d0dc9da27db0693718db18eDmitry Vyukov
385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesnamespace __tsan {
39f51c3860ce0a1ae81d0dc9da27db0693718db18eDmitry Vyukov
40e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukovstruct MapUnmapCallback {
41e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov  void OnMap(uptr p, uptr size) const { }
42e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov  void OnUnmap(uptr p, uptr size) const {
43e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov    // We are about to unmap a chunk of user memory.
44e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov    // Mark the corresponding shadow memory as not needed.
457ac33ac529ff93a57419f5ddf71b1fde68428577Dmitry Vyukov    DontNeedShadowFor(p, size);
46e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov  }
47e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov};
48e93e5057023de89f1bad5de609efac39efc5da73Dmitry Vyukov
49ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukovstatic char allocator_placeholder[sizeof(Allocator)] ALIGNED(64);
50ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry VyukovAllocator *allocator() {
512e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov  return reinterpret_cast<Allocator*>(&allocator_placeholder);
522e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov}
532e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov
542e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukovvoid InitializeAllocator() {
552e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov  allocator()->Init();
562e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov}
572e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov
58bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovvoid AllocatorThreadStart(ThreadState *thr) {
59bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov  allocator()->InitCache(&thr->alloc_cache);
601f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov  internal_allocator()->InitCache(&thr->internal_alloc_cache);
61bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov}
62bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov
63bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovvoid AllocatorThreadFinish(ThreadState *thr) {
64bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov  allocator()->DestroyCache(&thr->alloc_cache);
651f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov  internal_allocator()->DestroyCache(&thr->internal_alloc_cache);
66bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov}
67bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov
68bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukovvoid AllocatorPrintStats() {
69bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov  allocator()->PrintStats();
702e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov}
712e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov
727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void SignalUnsafeCall(ThreadState *thr, uptr pc) {
737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  if (!thr->in_signal_handler || !flags()->report_signal_unsafe)
747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    return;
757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  StackTrace stack;
767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  stack.ObtainCurrent(thr, pc);
772bbd8bec77c2fdb41c5f5b6cb0d83d22bc576650Alexey Samsonov  ThreadRegistryLock l(ctx->thread_registry);
787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  ScopedReport rep(ReportTypeSignalUnsafe);
79158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov  if (!IsFiredSuppression(ctx, rep, stack)) {
805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    rep.AddStack(&stack, true);
815d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    OutputReport(thr, rep);
82158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov  }
837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
852e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukovvoid *user_alloc(ThreadState *thr, uptr pc, uptr sz, uptr align) {
867423c7821ff30043def78c6cbb257bd2f4d9eef6Dmitry Vyukov  if ((sz >= (1ull << 40)) || (align >= (1ull << 40)))
87bd33d3ab168fcbcfe09a3fd6a971994b481e89d0Kostya Serebryany    return AllocatorReturnNull();
882e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov  void *p = allocator()->Allocate(&thr->alloc_cache, sz, align);
892e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov  if (p == 0)
90efd958213d70188ae6f79afd79fe2c84956d24ffDmitry Vyukov    return 0;
915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (ctx && ctx->initialized)
925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    OnUserAlloc(thr, pc, (uptr)p, sz, true);
937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  SignalUnsafeCall(thr, pc);
947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return p;
957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid user_free(ThreadState *thr, uptr pc, void *p) {
985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (ctx && ctx->initialized)
995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    OnUserFree(thr, pc, (uptr)p, true);
1002e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov  allocator()->Deallocate(&thr->alloc_cache, p);
1017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  SignalUnsafeCall(thr, pc);
1027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) {
1055d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p);
1065d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  ctx->metamap.AllocBlock(thr, pc, p, sz);
1075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (write && thr->ignore_reads_and_writes == 0)
1085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    MemoryRangeImitateWrite(thr, pc, (uptr)p, sz);
1095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  else
1105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    MemoryResetRange(thr, pc, (uptr)p, sz);
1115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
1125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid OnUserFree(ThreadState *thr, uptr pc, uptr p, bool write) {
1145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  CHECK_NE(p, (void*)0);
1155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  uptr sz = ctx->metamap.FreeBlock(thr, pc, p);
1165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  DPrintf("#%d: free(%p, %zu)\n", thr->tid, p, sz);
1175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  if (write && thr->ignore_reads_and_writes == 0)
1185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    MemoryRangeFreed(thr, pc, (uptr)p, sz);
1195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
1205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines
1217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz) {
1227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  void *p2 = 0;
1237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  // FIXME: Handle "shrinking" more efficiently,
1247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  // it seems that some software actually does this.
1257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  if (sz) {
1267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    p2 = user_alloc(thr, pc, sz);
127efd958213d70188ae6f79afd79fe2c84956d24ffDmitry Vyukov    if (p2 == 0)
128efd958213d70188ae6f79afd79fe2c84956d24ffDmitry Vyukov      return 0;
1297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    if (p) {
1305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      uptr oldsz = user_alloc_usable_size(p);
1315d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines      internal_memcpy(p2, p, min(oldsz, sz));
1327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
1337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  }
134f51c3860ce0a1ae81d0dc9da27db0693718db18eDmitry Vyukov  if (p)
1357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    user_free(thr, pc, p);
1367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return p2;
1377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr user_alloc_usable_size(const void *p) {
1408a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov  if (p == 0)
1418a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov    return 0;
1425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  MBlock *b = ctx->metamap.GetBlock((uptr)p);
1435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return b ? b->siz : 0;
1447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1464f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovvoid invoke_malloc_hook(void *ptr, uptr size) {
1474f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  ThreadState *thr = cur_thread();
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)
1494f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov    return;
1504f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  __tsan_malloc_hook(ptr, size);
1515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  __sanitizer_malloc_hook(ptr, size);
1524f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov}
1534f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov
1544f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonovvoid invoke_free_hook(void *ptr) {
1554f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  ThreadState *thr = cur_thread();
1562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)
1574f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov    return;
1584f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov  __tsan_free_hook(ptr);
1595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  __sanitizer_free_hook(ptr);
1604f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov}
1614f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov
1627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid *internal_alloc(MBlockType typ, uptr sz) {
1637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  ThreadState *thr = cur_thread();
1641f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov  CHECK_LE(sz, InternalSizeClassMap::kMaxSize);
1659ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov  if (thr->nomalloc) {
1669ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov    thr->nomalloc = 0;  // CHECK calls internal_malloc().
1679ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov    CHECK(0);
1689ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov  }
1691f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov  return InternalAlloc(sz, &thr->internal_alloc_cache);
1707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid internal_free(void *p) {
1737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  ThreadState *thr = cur_thread();
1749ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov  if (thr->nomalloc) {
1759ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov    thr->nomalloc = 0;  // CHECK calls internal_malloc().
1769ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov    CHECK(0);
1779ad7c32720dfa1287f8cfd481e5d583435178caeDmitry Vyukov  }
1781f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov  InternalFree(p, &thr->internal_alloc_cache);
1797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}  // namespace __tsan
18212530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
18312530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovusing namespace __tsan;
18412530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
18512530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukovextern "C" {
1865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __sanitizer_get_current_allocated_bytes() {
1875d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  uptr stats[AllocatorStatCount];
188bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov  allocator()->GetStats(stats);
1895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return stats[AllocatorStatAllocated];
1905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
1915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __tsan_get_current_allocated_bytes() {
1925d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_current_allocated_bytes();
19312530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
19412530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
1955d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __sanitizer_get_heap_size() {
1965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  uptr stats[AllocatorStatCount];
197bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov  allocator()->GetStats(stats);
1985d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return stats[AllocatorStatMapped];
1995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
2005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __tsan_get_heap_size() {
2015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_heap_size();
20212530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
20312530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
2045d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __sanitizer_get_free_bytes() {
2051acfa02e08e6d3316c80f52255cbb7d9e3164128Dmitry Vyukov  return 1;
20612530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
2075d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __tsan_get_free_bytes() {
2085d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_free_bytes();
2095d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
21012530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
2115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __sanitizer_get_unmapped_bytes() {
2121acfa02e08e6d3316c80f52255cbb7d9e3164128Dmitry Vyukov  return 1;
21312530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
2145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __tsan_get_unmapped_bytes() {
2155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_unmapped_bytes();
2165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
21712530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
2185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __sanitizer_get_estimated_allocated_size(uptr size) {
21912530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov  return size;
22012530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
2215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __tsan_get_estimated_allocated_size(uptr size) {
2225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_estimated_allocated_size(size);
2235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
22412530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
2255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesint __sanitizer_get_ownership(const void *p) {
226bdd844cb41718c27ef727a99a236191bc29a3df8Dmitry Vyukov  return allocator()->GetBlockBegin(p) != 0;
22712530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
2285d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesint __tsan_get_ownership(const void *p) {
2295d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_ownership(p);
2305d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
23112530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov
2325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __sanitizer_get_allocated_size(const void *p) {
2335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return user_alloc_usable_size(p);
2345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines}
2355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesuptr __tsan_get_allocated_size(const void *p) {
2365d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return __sanitizer_get_allocated_size(p);
23712530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}
2383ce21701b4e1026a4f5157ff9771c533f4e3ef55Dmitry Vyukov
2393ce21701b4e1026a4f5157ff9771c533f4e3ef55Dmitry Vyukovvoid __tsan_on_thread_idle() {
2403ce21701b4e1026a4f5157ff9771c533f4e3ef55Dmitry Vyukov  ThreadState *thr = cur_thread();
2413ce21701b4e1026a4f5157ff9771c533f4e3ef55Dmitry Vyukov  allocator()->SwallowCache(&thr->alloc_cache);
2421f3c2fee395abc36230c445e9ebdba55c4729d35Alexey Samsonov  internal_allocator()->SwallowCache(&thr->internal_alloc_cache);
2435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  ctx->metamap.OnThreadIdle(thr);
2443ce21701b4e1026a4f5157ff9771c533f4e3ef55Dmitry Vyukov}
24512530820a4d45e799cdbb83e7b3b1e8ef111650cDmitry Vyukov}  // extern "C"
246