1 1.1 kamil //===-- test.c ------------------------------------------------------------===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // 10 1.1 kamil // Sanity test for Go runtime. 11 1.1 kamil // 12 1.1 kamil //===----------------------------------------------------------------------===// 13 1.1 kamil 14 1.1 kamil #include <sys/mman.h> 15 1.1 kamil #include <errno.h> 16 1.1 kamil #include <stdio.h> 17 1.1 kamil #include <stdlib.h> 18 1.1 kamil 19 1.1 kamil void __tsan_init(void **thr, void **proc, void (*cb)(long, void*)); 20 1.1 kamil void __tsan_fini(); 21 1.1 kamil void __tsan_map_shadow(void *addr, unsigned long size); 22 1.1 kamil void __tsan_go_start(void *thr, void **chthr, void *pc); 23 1.1 kamil void __tsan_go_end(void *thr); 24 1.1 kamil void __tsan_proc_create(void **pproc); 25 1.1 kamil void __tsan_proc_destroy(void *proc); 26 1.1 kamil void __tsan_proc_wire(void *proc, void *thr); 27 1.1 kamil void __tsan_proc_unwire(void *proc, void *thr); 28 1.1 kamil void __tsan_read(void *thr, void *addr, void *pc); 29 1.1 kamil void __tsan_write(void *thr, void *addr, void *pc); 30 1.1 kamil void __tsan_func_enter(void *thr, void *pc); 31 1.1 kamil void __tsan_func_exit(void *thr); 32 1.1 kamil void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz); 33 1.1 kamil void __tsan_free(void *p, unsigned long sz); 34 1.1 kamil void __tsan_acquire(void *thr, void *addr); 35 1.1 kamil void __tsan_release(void *thr, void *addr); 36 1.1 kamil void __tsan_release_merge(void *thr, void *addr); 37 1.1 kamil 38 1.1 kamil void *current_proc; 39 1.1 kamil 40 1.1 kamil void symbolize_cb(long cmd, void *ctx) { 41 1.1 kamil switch (cmd) { 42 1.1 kamil case 0: 43 1.1 kamil if (current_proc == 0) 44 1.1 kamil abort(); 45 1.1 kamil *(void**)ctx = current_proc; 46 1.1 kamil } 47 1.1 kamil } 48 1.1 kamil 49 1.1 kamil /* 50 1.1 kamil * See lib/tsan/rtl/tsan_platform.h for details of what the memory layout 51 1.1 kamil * of Go programs looks like. To prevent running over existing mappings, 52 1.1 kamil * we pick an address slightly inside the Go heap region. 53 1.1 kamil */ 54 1.1 kamil void *go_heap = (void *)0xC011110000; 55 1.1 kamil char *buf0; 56 1.1 kamil 57 1.1 kamil void foobar() {} 58 1.1 kamil void barfoo() {} 59 1.1 kamil 60 1.1 kamil int main(void) { 61 1.1 kamil void *thr0 = 0; 62 1.1 kamil void *proc0 = 0; 63 1.1 kamil __tsan_init(&thr0, &proc0, symbolize_cb); 64 1.1 kamil current_proc = proc0; 65 1.1 kamil 66 1.1 kamil // Allocate something resembling a heap in Go. 67 1.1 kamil buf0 = mmap(go_heap, 16384, PROT_READ | PROT_WRITE, 68 1.1 kamil MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0); 69 1.1 kamil if (buf0 == MAP_FAILED) { 70 1.1 kamil fprintf(stderr, "failed to allocate Go-like heap at %p; errno %d\n", 71 1.1 kamil go_heap, errno); 72 1.1 kamil return 1; 73 1.1 kamil } 74 1.1 kamil char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1)); 75 1.1 kamil __tsan_map_shadow(buf, 4096); 76 1.1 kamil __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10); 77 1.1 kamil __tsan_free(buf, 10); 78 1.1 kamil __tsan_func_enter(thr0, (char*)&main + 1); 79 1.1 kamil __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10); 80 1.1 kamil __tsan_release(thr0, buf); 81 1.1 kamil __tsan_release_merge(thr0, buf); 82 1.1 kamil void *thr1 = 0; 83 1.1 kamil __tsan_go_start(thr0, &thr1, (char*)&barfoo + 1); 84 1.1 kamil void *thr2 = 0; 85 1.1 kamil __tsan_go_start(thr0, &thr2, (char*)&barfoo + 1); 86 1.1 kamil __tsan_func_exit(thr0); 87 1.1 kamil __tsan_func_enter(thr1, (char*)&foobar + 1); 88 1.1 kamil __tsan_func_enter(thr1, (char*)&foobar + 1); 89 1.1 kamil __tsan_write(thr1, buf, (char*)&barfoo + 1); 90 1.1 kamil __tsan_acquire(thr1, buf); 91 1.1 kamil __tsan_func_exit(thr1); 92 1.1 kamil __tsan_func_exit(thr1); 93 1.1 kamil __tsan_go_end(thr1); 94 1.1 kamil void *proc1 = 0; 95 1.1 kamil __tsan_proc_create(&proc1); 96 1.1 kamil current_proc = proc1; 97 1.1 kamil __tsan_func_enter(thr2, (char*)&foobar + 1); 98 1.1 kamil __tsan_read(thr2, buf, (char*)&barfoo + 1); 99 1.1 kamil __tsan_free(buf, 10); 100 1.1 kamil __tsan_func_exit(thr2); 101 1.1 kamil __tsan_go_end(thr2); 102 1.1 kamil __tsan_proc_destroy(proc1); 103 1.1 kamil current_proc = proc0; 104 1.1 kamil __tsan_fini(); 105 1.1 kamil return 0; 106 1.1 kamil } 107