1*7c3d14c8STreehugger Robot //===-- tsan_interface.cc -------------------------------------------------===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of ThreadSanitizer (TSan), a race detector.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
13*7c3d14c8STreehugger Robot
14*7c3d14c8STreehugger Robot #include "tsan_interface.h"
15*7c3d14c8STreehugger Robot #include "tsan_interface_ann.h"
16*7c3d14c8STreehugger Robot #include "tsan_rtl.h"
17*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_internal_defs.h"
18*7c3d14c8STreehugger Robot
19*7c3d14c8STreehugger Robot #define CALLERPC ((uptr)__builtin_return_address(0))
20*7c3d14c8STreehugger Robot
21*7c3d14c8STreehugger Robot using namespace __tsan; // NOLINT
22*7c3d14c8STreehugger Robot
23*7c3d14c8STreehugger Robot typedef u16 uint16_t;
24*7c3d14c8STreehugger Robot typedef u32 uint32_t;
25*7c3d14c8STreehugger Robot typedef u64 uint64_t;
26*7c3d14c8STreehugger Robot
__tsan_init()27*7c3d14c8STreehugger Robot void __tsan_init() {
28*7c3d14c8STreehugger Robot Initialize(cur_thread());
29*7c3d14c8STreehugger Robot }
30*7c3d14c8STreehugger Robot
__tsan_read16(void * addr)31*7c3d14c8STreehugger Robot void __tsan_read16(void *addr) {
32*7c3d14c8STreehugger Robot MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);
33*7c3d14c8STreehugger Robot MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8);
34*7c3d14c8STreehugger Robot }
35*7c3d14c8STreehugger Robot
__tsan_write16(void * addr)36*7c3d14c8STreehugger Robot void __tsan_write16(void *addr) {
37*7c3d14c8STreehugger Robot MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);
38*7c3d14c8STreehugger Robot MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8);
39*7c3d14c8STreehugger Robot }
40*7c3d14c8STreehugger Robot
__tsan_read16_pc(void * addr,void * pc)41*7c3d14c8STreehugger Robot void __tsan_read16_pc(void *addr, void *pc) {
42*7c3d14c8STreehugger Robot MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
43*7c3d14c8STreehugger Robot MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);
44*7c3d14c8STreehugger Robot }
45*7c3d14c8STreehugger Robot
__tsan_write16_pc(void * addr,void * pc)46*7c3d14c8STreehugger Robot void __tsan_write16_pc(void *addr, void *pc) {
47*7c3d14c8STreehugger Robot MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
48*7c3d14c8STreehugger Robot MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8);
49*7c3d14c8STreehugger Robot }
50*7c3d14c8STreehugger Robot
51*7c3d14c8STreehugger Robot // __tsan_unaligned_read/write calls are emitted by compiler.
52*7c3d14c8STreehugger Robot
__tsan_unaligned_read2(const void * addr)53*7c3d14c8STreehugger Robot void __tsan_unaligned_read2(const void *addr) {
54*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, false, false);
55*7c3d14c8STreehugger Robot }
56*7c3d14c8STreehugger Robot
__tsan_unaligned_read4(const void * addr)57*7c3d14c8STreehugger Robot void __tsan_unaligned_read4(const void *addr) {
58*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, false, false);
59*7c3d14c8STreehugger Robot }
60*7c3d14c8STreehugger Robot
__tsan_unaligned_read8(const void * addr)61*7c3d14c8STreehugger Robot void __tsan_unaligned_read8(const void *addr) {
62*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, false, false);
63*7c3d14c8STreehugger Robot }
64*7c3d14c8STreehugger Robot
__tsan_unaligned_read16(const void * addr)65*7c3d14c8STreehugger Robot void __tsan_unaligned_read16(const void *addr) {
66*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, false, false);
67*7c3d14c8STreehugger Robot }
68*7c3d14c8STreehugger Robot
__tsan_unaligned_write2(void * addr)69*7c3d14c8STreehugger Robot void __tsan_unaligned_write2(void *addr) {
70*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, true, false);
71*7c3d14c8STreehugger Robot }
72*7c3d14c8STreehugger Robot
__tsan_unaligned_write4(void * addr)73*7c3d14c8STreehugger Robot void __tsan_unaligned_write4(void *addr) {
74*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, true, false);
75*7c3d14c8STreehugger Robot }
76*7c3d14c8STreehugger Robot
__tsan_unaligned_write8(void * addr)77*7c3d14c8STreehugger Robot void __tsan_unaligned_write8(void *addr) {
78*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, true, false);
79*7c3d14c8STreehugger Robot }
80*7c3d14c8STreehugger Robot
__tsan_unaligned_write16(void * addr)81*7c3d14c8STreehugger Robot void __tsan_unaligned_write16(void *addr) {
82*7c3d14c8STreehugger Robot UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, true, false);
83*7c3d14c8STreehugger Robot }
84*7c3d14c8STreehugger Robot
85*7c3d14c8STreehugger Robot // __sanitizer_unaligned_load/store are for user instrumentation.
86*7c3d14c8STreehugger Robot
87*7c3d14c8STreehugger Robot extern "C" {
88*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_unaligned_load16(const uu16 * addr)89*7c3d14c8STreehugger Robot u16 __sanitizer_unaligned_load16(const uu16 *addr) {
90*7c3d14c8STreehugger Robot __tsan_unaligned_read2(addr);
91*7c3d14c8STreehugger Robot return *addr;
92*7c3d14c8STreehugger Robot }
93*7c3d14c8STreehugger Robot
94*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_unaligned_load32(const uu32 * addr)95*7c3d14c8STreehugger Robot u32 __sanitizer_unaligned_load32(const uu32 *addr) {
96*7c3d14c8STreehugger Robot __tsan_unaligned_read4(addr);
97*7c3d14c8STreehugger Robot return *addr;
98*7c3d14c8STreehugger Robot }
99*7c3d14c8STreehugger Robot
100*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_unaligned_load64(const uu64 * addr)101*7c3d14c8STreehugger Robot u64 __sanitizer_unaligned_load64(const uu64 *addr) {
102*7c3d14c8STreehugger Robot __tsan_unaligned_read8(addr);
103*7c3d14c8STreehugger Robot return *addr;
104*7c3d14c8STreehugger Robot }
105*7c3d14c8STreehugger Robot
106*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_unaligned_store16(uu16 * addr,u16 v)107*7c3d14c8STreehugger Robot void __sanitizer_unaligned_store16(uu16 *addr, u16 v) {
108*7c3d14c8STreehugger Robot __tsan_unaligned_write2(addr);
109*7c3d14c8STreehugger Robot *addr = v;
110*7c3d14c8STreehugger Robot }
111*7c3d14c8STreehugger Robot
112*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_unaligned_store32(uu32 * addr,u32 v)113*7c3d14c8STreehugger Robot void __sanitizer_unaligned_store32(uu32 *addr, u32 v) {
114*7c3d14c8STreehugger Robot __tsan_unaligned_write4(addr);
115*7c3d14c8STreehugger Robot *addr = v;
116*7c3d14c8STreehugger Robot }
117*7c3d14c8STreehugger Robot
118*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_unaligned_store64(uu64 * addr,u64 v)119*7c3d14c8STreehugger Robot void __sanitizer_unaligned_store64(uu64 *addr, u64 v) {
120*7c3d14c8STreehugger Robot __tsan_unaligned_write8(addr);
121*7c3d14c8STreehugger Robot *addr = v;
122*7c3d14c8STreehugger Robot }
123*7c3d14c8STreehugger Robot } // extern "C"
124*7c3d14c8STreehugger Robot
__tsan_acquire(void * addr)125*7c3d14c8STreehugger Robot void __tsan_acquire(void *addr) {
126*7c3d14c8STreehugger Robot Acquire(cur_thread(), CALLERPC, (uptr)addr);
127*7c3d14c8STreehugger Robot }
128*7c3d14c8STreehugger Robot
__tsan_release(void * addr)129*7c3d14c8STreehugger Robot void __tsan_release(void *addr) {
130*7c3d14c8STreehugger Robot Release(cur_thread(), CALLERPC, (uptr)addr);
131*7c3d14c8STreehugger Robot }
132