17ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===-- tsan_platform.h -----------------------------------------*- C++ -*-===//
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// Platform-specific code.
137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===//
147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1545bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov/*
1645bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry VyukovC++ linux memory layout:
1745bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0000 0000 0000 - 03c0 0000 0000: protected
1845bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov03c0 0000 0000 - 1000 0000 0000: shadow
195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines1000 0000 0000 - 3000 0000 0000: protected
205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines4000 0000 0000 - 6000 0000 0000: protected
22385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov6000 0000 0000 - 6200 0000 0000: traces
23385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov6200 0000 0000 - 7d00 0000 0000: -
2445bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov7d00 0000 0000 - 7e00 0000 0000: heap
2545bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov7e00 0000 0000 - 7fff ffff ffff: modules and main thread stack
2645bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov
2745bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry VyukovC++ COMPAT linux memory layout:
2845bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0000 0000 0000 - 0400 0000 0000: protected
2945bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0400 0000 0000 - 1000 0000 0000: shadow
3045bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov1000 0000 0000 - 2900 0000 0000: protected
3145bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov2900 0000 0000 - 2c00 0000 0000: modules
325d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines2c00 0000 0000 - 3000 0000 0000: -
335d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines4000 0000 0000 - 6000 0000 0000: -
35385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov6000 0000 0000 - 6200 0000 0000: traces
36385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov6200 0000 0000 - 7d00 0000 0000: -
3745bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov7d00 0000 0000 - 7e00 0000 0000: heap
3845bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov7e00 0000 0000 - 7f00 0000 0000: -
3945bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov7f00 0000 0000 - 7fff ffff ffff: main thread stack
4045bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov
4145bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry VyukovGo linux and darwin memory layout:
4245bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0000 0000 0000 - 0000 1000 0000: executable
4345bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0000 1000 0000 - 00f8 0000 0000: -
444860c68bafe61e02a84ce8bc76095f5e5e5539e1Dmitry Vyukov00c0 0000 0000 - 00e0 0000 0000: heap
454860c68bafe61e02a84ce8bc76095f5e5e5539e1Dmitry Vyukov00e0 0000 0000 - 1000 0000 0000: -
464860c68bafe61e02a84ce8bc76095f5e5e5539e1Dmitry Vyukov1000 0000 0000 - 1380 0000 0000: shadow
475d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines1460 0000 0000 - 2000 0000 0000: -
485d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
495d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines4000 0000 0000 - 6000 0000 0000: -
50385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov6000 0000 0000 - 6200 0000 0000: traces
51385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov6200 0000 0000 - 7fff ffff ffff: -
5245bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov
5345bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry VyukovGo windows memory layout:
5445bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0000 0000 0000 - 0000 1000 0000: executable
5545bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0000 1000 0000 - 00f8 0000 0000: -
564860c68bafe61e02a84ce8bc76095f5e5e5539e1Dmitry Vyukov00c0 0000 0000 - 00e0 0000 0000: heap
574860c68bafe61e02a84ce8bc76095f5e5e5539e1Dmitry Vyukov00e0 0000 0000 - 0100 0000 0000: -
5845bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov0100 0000 0000 - 0560 0000 0000: shadow
59385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov0560 0000 0000 - 0760 0000 0000: traces
605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines0760 0000 0000 - 07d0 0000 0000: metainfo (memory blocks and sync objects)
615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines07d0 0000 0000 - 07ff ffff ffff: -
6245bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov*/
6345bdb2ffb2878a6c22493af76256d5950dc0a6a2Dmitry Vyukov
645b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#ifndef TSAN_PLATFORM_H
655b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#define TSAN_PLATFORM_H
667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
67385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov#include "tsan_defs.h"
68385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov#include "tsan_trace.h"
697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
706da4354df86f535b479d45a4adbba31af4634f46Dmitry Vyukov#if defined(__LP64__) || defined(_WIN64)
717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanynamespace __tsan {
727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
73b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#if defined(TSAN_GO)
74b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovstatic const uptr kLinuxAppMemBeg = 0x000000000000ULL;
75d36f07c7f2a915616c3f784c5f77f21f1b86817fDmitry Vyukovstatic const uptr kLinuxAppMemEnd = 0x04dfffffffffULL;
7624e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov# if SANITIZER_WINDOWS
776da4354df86f535b479d45a4adbba31af4634f46Dmitry Vyukovstatic const uptr kLinuxShadowMsk = 0x010000000000ULL;
785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const uptr kMetaShadow     = 0x076000000000ULL;
795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const uptr kMetaSize       = 0x007000000000ULL;
805d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# else  // if SANITIZER_WINDOWS
81d36f07c7f2a915616c3f784c5f77f21f1b86817fDmitry Vyukovstatic const uptr kLinuxShadowMsk = 0x200000000000ULL;
825d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const uptr kMetaShadow     = 0x300000000000ULL;
835d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const uptr kMetaSize       = 0x100000000000ULL;
845d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# endif  // if SANITIZER_WINDOWS
855d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else  // defined(TSAN_GO)
865d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const uptr kMetaShadow     = 0x300000000000ULL;
875d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const uptr kMetaSize       = 0x100000000000ULL;
887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout,
897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// when memory addresses are of the 0x2axxxxxxxxxx form.
907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// The option is enabled with 'setarch x86_64 -L'.
915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
92eee7f733f047bbd58b0787e6c492fd1bed375cc0Dmitry Vyukovstatic const uptr kLinuxAppMemBeg = 0x290000000000ULL;
937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const uptr kAppMemGapBeg   = 0x2c0000000000ULL;
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const uptr kAppMemGapEnd   = 0x7d0000000000ULL;
965d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# else
972e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukovstatic const uptr kLinuxAppMemBeg = 0x7cf000000000ULL;
987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
995d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines# endif
1007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif
1017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
10424e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if SANITIZER_WINDOWS
105385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukovconst uptr kTraceMemBegin = 0x056000000000ULL;
106385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov#else
107385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukovconst uptr kTraceMemBegin = 0x600000000000ULL;
108385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov#endif
109385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukovconst uptr kTraceMemSize = 0x020000000000ULL;
110385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov
1117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This has to be a macro to allow constant initialization of constants below.
112b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#ifndef TSAN_GO
1137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#define MemToShadow(addr) \
1145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    ((((uptr)addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
1155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define MemToMeta(addr) \
1165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    (u32*)(((((uptr)addr) & ~(kLinuxAppMemMsk | (kMetaShadowCell - 1))) \
1175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    / kMetaShadowCell * kMetaShadowSize) | kMetaShadow)
118b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#else
119cb3a6b82ae406613f8870519d2acda1ee1c8f2b5Dmitry Vyukov#define MemToShadow(addr) \
1205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    (((((uptr)addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk)
1215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#define MemToMeta(addr) \
1225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    (u32*)(((((uptr)addr) & ~(kMetaShadowCell - 1)) \
1235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines    / kMetaShadowCell * kMetaShadowSize) | kMetaShadow)
124b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#endif
1257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
1277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxShadowEnd =
128e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany    MemToShadow(kLinuxAppMemEnd) | 0xff;
1297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic inline bool IsAppMem(uptr mem) {
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  return (mem >= kLinuxAppMemBeg && mem < kAppMemGapBeg) ||
1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines         (mem >= kAppMemGapEnd   && mem <= kLinuxAppMemEnd);
1345d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#elif defined(TSAN_GO)
1355d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines  return mem <= kLinuxAppMemEnd;
1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
1377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;
1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic inline bool IsShadowMem(uptr mem) {
1427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;
1437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic inline uptr ShadowToMem(uptr shadow) {
1467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  CHECK(IsShadowMem(shadow));
147b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#ifdef TSAN_GO
148b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  return (shadow & ~kLinuxShadowMsk) / kShadowCnt;
1497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#else
1507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return (shadow / kShadowCnt) | kLinuxAppMemMsk;
1517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif
1527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1543fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov// For COMPAT mapping returns an alternative address
1553fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov// that mapped to the same shadow address.
156eee7f733f047bbd58b0787e6c492fd1bed375cc0Dmitry Vyukov// COMPAT mapping is not quite one-to-one.
1573fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukovstatic inline uptr AlternativeAddress(uptr addr) {
1583fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
159539121b7be56780045ba1e9c0aea826626cb638aDmitry Vyukov  return (addr & ~kLinuxAppMemMsk) | 0x280000000000ULL;
1603fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov#else
1613fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov  return 0;
1623fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov#endif
1633fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov}
1643fb44411ae1b9c2a277c04b3f379554290832009Dmitry Vyukov
165adfb65039646774f0f063b538f8fb0aec021f42bDmitry Vyukovvoid FlushShadowMemory();
1665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
16792b54796149a8b5995fa49c43f43b709b83c5644Dmitry Vyukovuptr GetRSS();
16826127735454fddae3495794f38189d57dde6510fDmitry Vyukov
1697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst char *InitializePlatform();
1707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid FinalizePlatform();
17101a7ce809bf7cc627d73c045c70bcca9891f632cDmitry Vyukov
17201a7ce809bf7cc627d73c045c70bcca9891f632cDmitry Vyukov// The additional page is to catch shadow stack overflow as paging fault.
1732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Windows wants 64K alignment for mmaps.
1742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesconst uptr kTotalTraceSize = (kTraceSize * sizeof(Event) + sizeof(Trace)
1752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    + (64 << 10) + (64 << 10) - 1) & ~((64 << 10) - 1);
17601a7ce809bf7cc627d73c045c70bcca9891f632cDmitry Vyukov
177abfdbdf5bc7e9d202652fe061acd20c14a4d22f4Timur Iskhodzhanovuptr ALWAYS_INLINE GetThreadTrace(int tid) {
17801a7ce809bf7cc627d73c045c70bcca9891f632cDmitry Vyukov  uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize;
1799743d74426ae43898e4da55e591b09be18f8aa6eDmitry Vyukov  DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
1809743d74426ae43898e4da55e591b09be18f8aa6eDmitry Vyukov  return p;
1819743d74426ae43898e4da55e591b09be18f8aa6eDmitry Vyukov}
1829743d74426ae43898e4da55e591b09be18f8aa6eDmitry Vyukov
183abfdbdf5bc7e9d202652fe061acd20c14a4d22f4Timur Iskhodzhanovuptr ALWAYS_INLINE GetThreadTraceHeader(int tid) {
18401a7ce809bf7cc627d73c045c70bcca9891f632cDmitry Vyukov  uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize
18501a7ce809bf7cc627d73c045c70bcca9891f632cDmitry Vyukov      + kTraceSize * sizeof(Event);
186385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov  DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
187385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov  return p;
188385542a2e83a4f37de4232d6c72097c1b7d6d44bDmitry Vyukov}
1897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *internal_start_thread(void(*func)(void*), void *arg);
1912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid internal_join_thread(void *th);
1927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1930c2feef1067818db0ede4531a2e71c9b5595d57aDmitry Vyukov// Says whether the addr relates to a global var.
1940c2feef1067818db0ede4531a2e71c9b5595d57aDmitry Vyukov// Guesses with high probability, may yield both false positives and negatives.
1950c2feef1067818db0ede4531a2e71c9b5595d57aDmitry Vyukovbool IsGlobalVar(uptr addr);
19603f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukovint ExtractResolvFDs(void *state, int *fds, int nfd);
1972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
2002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void *abstime), void *c, void *m, void *abstime,
2012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    void(*cleanup)(void *arg), void *arg);
2027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}  // namespace __tsan
2047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2056da4354df86f535b479d45a4adbba31af4634f46Dmitry Vyukov#else  // defined(__LP64__) || defined(_WIN64)
2067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany# error "Only 64-bit is supported"
2077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif
2087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2095b266cb19c9c18ab5da77441de5cb45f0f4abac1Dmitry Vyukov#endif  // TSAN_PLATFORM_H
210