tsan_platform.h revision 26127735454fddae3495794f38189d57dde6510f
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
157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#ifndef TSAN_LINUX_H
167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#define TSAN_LINUX_H
177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#ifdef __linux__
187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_rtl.h"
207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#if __LP64__
227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanynamespace __tsan {
237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout,
257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// when memory addresses are of the 0x2axxxxxxxxxx form.
267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// The option is enabled with 'setarch x86_64 -L'.
277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemBeg = 0x2a0000000000ULL;
307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#else
337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemBeg = 0x7ef000000000ULL;
357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif
387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This has to be a macro to allow constant initialization of constants below.
427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#define MemToShadow(addr) \
437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic const uptr kLinuxShadowEnd =
477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  MemToShadow(kLinuxAppMemEnd) | (kPageSize - 1);
487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic inline bool IsAppMem(uptr mem) {
507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;
517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic inline bool IsShadowMem(uptr mem) {
547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;
557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic inline uptr ShadowToMem(uptr shadow) {
587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  CHECK(IsShadowMem(shadow));
597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  // COMPAT mapping is not quite one-to-one.
617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return (shadow / kShadowCnt) | 0x280000000000ULL;
627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#else
637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany  return (shadow / kShadowCnt) | kLinuxAppMemMsk;
647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif
657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
6726127735454fddae3495794f38189d57dde6510fDmitry Vyukovuptr GetShadowMemoryConsumption();
6826127735454fddae3495794f38189d57dde6510fDmitry Vyukov
697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst char *InitializePlatform();
707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid FinalizePlatform();
717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyint GetPid();
727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
7326127735454fddae3495794f38189d57dde6510fDmitry Vyukovvoid internal_yield();
7426127735454fddae3495794f38189d57dde6510fDmitry Vyukovvoid internal_sleep_ms(u32 ms);
7526127735454fddae3495794f38189d57dde6510fDmitry Vyukov
7626127735454fddae3495794f38189d57dde6510fDmitry Vyukovvoid internal_start_thread(void(*func)(void*), void *arg);
777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanytypedef int fd_t;
797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst fd_t kInvalidFd = -1;
807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyfd_t internal_open(const char *name, bool write);
817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid internal_close(fd_t fd);
827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyuptr internal_filesize(fd_t fd);  // -1 on error.
837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyuptr internal_read(fd_t fd, void *p, uptr size);
847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyuptr internal_write(fd_t fd, const void *p, uptr size);
857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst char *internal_getpwd();
867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyuptr GetTlsSize();
887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid GetThreadStackAndTls(uptr *stk_addr, uptr *stk_size,
897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                          uptr *tls_addr, uptr *tls_size);
907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}  // namespace __tsan
927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#else  // __LP64__
947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany# error "Only 64-bit is supported"
957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif
967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif  // __linux__
987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#endif  // TSAN_LINUX_H
99