1b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//===-- tsan_go.cc --------------------------------------------------------===//
2b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//
3b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//                     The LLVM Compiler Infrastructure
4b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//
5b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov// This file is distributed under the University of Illinois Open Source
6b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov// License. See LICENSE.TXT for details.
7b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//
8b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//===----------------------------------------------------------------------===//
9b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//
10b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov// ThreadSanitizer runtime for Go language.
11b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//
12b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov//===----------------------------------------------------------------------===//
13b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
14b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#include "tsan_rtl.h"
15b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#include "tsan_symbolize.h"
16b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#include "sanitizer_common/sanitizer_common.h"
17b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov#include <stdlib.h>
18b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
19b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovnamespace __tsan {
20b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
21b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovvoid InitializeInterceptors() {
22b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
23b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
24b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovvoid InitializeDynamicAnnotations() {
25b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
26b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
27b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovbool IsExpectedReport(uptr addr, uptr size) {
28b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  return false;
29b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
30b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
315a1f23310cc4a1debae8741653defe620518e612Dmitry VyukovReportLocation *SymbolizeData(uptr addr) {
32b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  return 0;
33b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
34b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
35b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovvoid *internal_alloc(MBlockType typ, uptr sz) {
36b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  return InternalAlloc(sz);
37b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
38b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
39b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovvoid internal_free(void *p) {
40b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  InternalFree(p);
41b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
42b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstruct SymbolizeContext {
442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr pc;
452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char *func;
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  char *file;
472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr line;
482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr off;
492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  uptr res;
502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines};
512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
526b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov// Callback into Go.
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void (*symbolize_cb)(SymbolizeContext *ctx);
54b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
5586277eb844c4983c81de62d7c050e92fe7155788Stephen HinesSymbolizedStack *SymbolizeCode(uptr addr) {
5686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  SymbolizedStack *s = SymbolizedStack::New(addr);
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  SymbolizeContext ctx;
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  internal_memset(&ctx, 0, sizeof(ctx));
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  ctx.pc = addr;
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  symbolize_cb(&ctx);
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (ctx.res) {
6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    AddressInfo &info = s->info;
6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    info.module_offset = ctx.off;
6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    info.function = internal_strdup(ctx.func ? ctx.func : "??");
6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    info.file = internal_strdup(ctx.file ? ctx.file : "-");
6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    info.line = ctx.line;
6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines    info.column = 0;
686b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  }
696b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  return s;
706b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
716b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
726b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukovextern "C" {
73b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
746faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovstatic ThreadState *main_thr;
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic bool inited;
766faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov
776faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovstatic ThreadState *AllocGoroutine() {
787d15f5dc87f980d7931fbc036a0b38e2eee16718Dmitry Vyukov  ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex,
79cb3a6b82ae406613f8870519d2acda1ee1c8f2b5Dmitry Vyukov      sizeof(ThreadState));
807d15f5dc87f980d7931fbc036a0b38e2eee16718Dmitry Vyukov  internal_memset(thr, 0, sizeof(*thr));
816faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  return thr;
82cb3a6b82ae406613f8870519d2acda1ee1c8f2b5Dmitry Vyukov}
83cb3a6b82ae406613f8870519d2acda1ee1c8f2b5Dmitry Vyukov
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __tsan_init(ThreadState **thrp, void (*cb)(SymbolizeContext *cb)) {
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  symbolize_cb = cb;
866faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  ThreadState *thr = AllocGoroutine();
876faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  main_thr = *thrp = thr;
88b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  Initialize(thr);
892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  inited = true;
90b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
91b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
92b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukovvoid __tsan_fini() {
93b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  // FIXME: Not necessary thread 0.
946faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  ThreadState *thr = main_thr;
95b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov  int res = Finalize(thr);
961bf56b76cf08ab19800cf5a30849277bf1e084d4Dmitry Vyukov  exit(res);
97b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
98b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
99a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9Dmitry Vyukovvoid __tsan_map_shadow(uptr addr, uptr size) {
100a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9Dmitry Vyukov  MapShadow(addr, size);
101a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9Dmitry Vyukov}
102a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9Dmitry Vyukov
1036faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_read(ThreadState *thr, void *addr, void *pc) {
104334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov  MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1);
1056b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1066b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __tsan_read_pc(ThreadState *thr, void *addr, uptr callpc, uptr pc) {
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (callpc != 0)
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FuncEntry(thr, callpc);
1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1);
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (callpc != 0)
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FuncExit(thr);
1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1156faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_write(ThreadState *thr, void *addr, void *pc) {
116334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov  MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1);
1176b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1186b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __tsan_write_pc(ThreadState *thr, void *addr, uptr callpc, uptr pc) {
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (callpc != 0)
1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FuncEntry(thr, callpc);
1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1);
1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (callpc != 0)
1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    FuncExit(thr);
1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr pc) {
12848cd12d0398914db195c1a25852b153f3345090dDmitry Vyukov  MemoryAccessRange(thr, (uptr)pc, (uptr)addr, size, false);
1291a9cd8ddea1985ab4941a8bd2f6e20822d1e9c1dDmitry Vyukov}
1301a9cd8ddea1985ab4941a8bd2f6e20822d1e9c1dDmitry Vyukov
1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr pc) {
13248cd12d0398914db195c1a25852b153f3345090dDmitry Vyukov  MemoryAccessRange(thr, (uptr)pc, (uptr)addr, size, true);
1331a9cd8ddea1985ab4941a8bd2f6e20822d1e9c1dDmitry Vyukov}
1341a9cd8ddea1985ab4941a8bd2f6e20822d1e9c1dDmitry Vyukov
1356faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_func_enter(ThreadState *thr, void *pc) {
1366b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  FuncEntry(thr, (uptr)pc);
1376b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1386b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1396faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_func_exit(ThreadState *thr) {
1406b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  FuncExit(thr);
1416b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1426b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid __tsan_malloc(void *p, uptr sz) {
1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (!inited)
1451bf56b76cf08ab19800cf5a30849277bf1e084d4Dmitry Vyukov    return;
1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  MemoryResetRange(0, 0, (uptr)p, sz);
1476b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1486b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1496faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) {
1506faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  ThreadState *thr = AllocGoroutine();
1516faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  *pthr = thr;
1526faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  int goid = ThreadCreate(parent, (uptr)pc, 0, true);
1536faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukov  ThreadStart(thr, goid, 0);
1546b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1556b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1566faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_go_end(ThreadState *thr) {
1576b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  ThreadFinish(thr);
1587d15f5dc87f980d7931fbc036a0b38e2eee16718Dmitry Vyukov  internal_free(thr);
1596b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1606b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1616faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_acquire(ThreadState *thr, void *addr) {
1626b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  Acquire(thr, 0, (uptr)addr);
1636b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1646b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1656faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_release(ThreadState *thr, void *addr) {
1669d150bdb433ddd092073dabd87ba15aa176603a1Dmitry Vyukov  ReleaseStore(thr, 0, (uptr)addr);
1676b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov}
1686b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov
1696faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_release_merge(ThreadState *thr, void *addr) {
1706b2804f4a5d8891728c030e1ac93f719eaad3171Dmitry Vyukov  Release(thr, 0, (uptr)addr);
171b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}
172b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov
1736faa20f2441cd845d98cb390ae2bacca908537eeDmitry Vyukovvoid __tsan_finalizer_goroutine(ThreadState *thr) {
174538f1ba8cb57cfa02d25f8f922feb00975e0a286Dmitry Vyukov  AcquireGlobal(thr, 0);
1758f1104cbf1af615242e14c66d1b3dd9e8437b152Dmitry Vyukov}
1768f1104cbf1af615242e14c66d1b3dd9e8437b152Dmitry Vyukov
1776a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesvoid __tsan_mutex_before_lock(ThreadState *thr, uptr addr, uptr write) {
1782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1806a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesvoid __tsan_mutex_after_lock(ThreadState *thr, uptr addr, uptr write) {
1812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (write)
1822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    MutexLock(thr, 0, addr);
1832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else
1842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    MutexReadLock(thr, 0, addr);
1852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1876a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesvoid __tsan_mutex_before_unlock(ThreadState *thr, uptr addr, uptr write) {
1882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  if (write)
1892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    MutexUnlock(thr, 0, addr);
1902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  else
1912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    MutexReadUnlock(thr, 0, addr);
1922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
1946d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __tsan_go_ignore_sync_begin(ThreadState *thr) {
1956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ThreadIgnoreSyncBegin(thr, 0);
1966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
1976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
1986d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid __tsan_go_ignore_sync_end(ThreadState *thr) {
1996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  ThreadIgnoreSyncEnd(thr, 0);
2006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
2016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
202b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}  // extern "C"
203b78caa645f70eff2f037f1f8bb43ca9129dbd8d9Dmitry Vyukov}  // namespace __tsan
2043086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenko
2053086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenkonamespace __sanitizer {
2063086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenko
2073086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenkovoid SymbolizerPrepareForSandboxing() {
2083086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenko  // Nothing to do here for Go.
2093086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenko}
2103086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenko
2113086d7bd6456e43b6695c8356db364ade826dce3Alexander Potapenko}  // namespace __sanitizer
212