Path: blob/main/contrib/llvm-project/compiler-rt/lib/tsan/go/test.c
35266 views
//===-- test.c ------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Test for Go runtime.9//10//===----------------------------------------------------------------------===//1112#include <sys/mman.h>13#include <errno.h>14#include <stdio.h>15#include <stdlib.h>1617void __tsan_init(void **thr, void **proc, void (*cb)(long, void*));18void __tsan_fini();19void __tsan_map_shadow(void *addr, unsigned long size);20void __tsan_go_start(void *thr, void **chthr, void *pc);21void __tsan_go_end(void *thr);22void __tsan_proc_create(void **pproc);23void __tsan_proc_destroy(void *proc);24void __tsan_proc_wire(void *proc, void *thr);25void __tsan_proc_unwire(void *proc, void *thr);26void __tsan_read(void *thr, void *addr, void *pc);27void __tsan_write(void *thr, void *addr, void *pc);28void __tsan_func_enter(void *thr, void *pc);29void __tsan_func_exit(void *thr);30void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz);31void __tsan_free(void *p, unsigned long sz);32void __tsan_acquire(void *thr, void *addr);33void __tsan_release(void *thr, void *addr);34void __tsan_release_acquire(void *thr, void *addr);35void __tsan_release_merge(void *thr, void *addr);3637void *current_proc;3839void symbolize_cb(long cmd, void *ctx) {40switch (cmd) {41case 0:42if (current_proc == 0)43abort();44*(void**)ctx = current_proc;45}46}4748/*49* See lib/tsan/rtl/tsan_platform.h for details of what the memory layout50* of Go programs looks like. To prevent running over existing mappings,51* we pick an address slightly inside the Go heap region.52*/53void *go_heap = (void *)0xC011110000;54char *buf0;5556void foobar() {}57void barfoo() {}5859int main(void) {60void *thr0 = 0;61void *proc0 = 0;62__tsan_init(&thr0, &proc0, symbolize_cb);63current_proc = proc0;6465// Allocate something resembling a heap in Go.66buf0 = mmap(go_heap, 16384, PROT_READ | PROT_WRITE,67MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);68if (buf0 == MAP_FAILED) {69fprintf(stderr, "failed to allocate Go-like heap at %p; errno %d\n",70go_heap, errno);71return 1;72}73char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));74__tsan_map_shadow(buf, 4096);75__tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);76__tsan_free(buf, 10);77__tsan_func_enter(thr0, (char*)&main + 1);78__tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);79__tsan_release(thr0, buf);80__tsan_release_acquire(thr0, buf);81__tsan_release_merge(thr0, buf);82void *thr1 = 0;83__tsan_go_start(thr0, &thr1, (char*)&barfoo + 1);84void *thr2 = 0;85__tsan_go_start(thr0, &thr2, (char*)&barfoo + 1);86__tsan_func_exit(thr0);87__tsan_func_enter(thr1, (char*)&foobar + 1);88__tsan_func_enter(thr1, (char*)&foobar + 1);89__tsan_write(thr1, buf, (char*)&barfoo + 1);90__tsan_acquire(thr1, buf);91__tsan_func_exit(thr1);92__tsan_func_exit(thr1);93__tsan_go_end(thr1);94void *proc1 = 0;95__tsan_proc_create(&proc1);96current_proc = proc1;97__tsan_func_enter(thr2, (char*)&foobar + 1);98__tsan_read(thr2, buf, (char*)&barfoo + 1);99__tsan_free(buf, 10);100__tsan_func_exit(thr2);101__tsan_go_end(thr2);102__tsan_proc_destroy(proc1);103current_proc = proc0;104__tsan_fini();105return 0;106}107108109