brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · d328ab1 Raw
115 lines · c
1//===-- test.c ------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Test for Go runtime.10//11//===----------------------------------------------------------------------===//12 13#include <sys/mman.h>14#include <errno.h>15#include <stdio.h>16#include <stdlib.h>17 18void __tsan_init(void **thr, void **proc, void (*cb)(long, void*));19void __tsan_fini();20void __tsan_map_shadow(void *addr, unsigned long size);21void __tsan_go_start(void *thr, void **chthr, void *pc);22void __tsan_go_end(void *thr);23void __tsan_proc_create(void **pproc);24void __tsan_proc_destroy(void *proc);25void __tsan_proc_wire(void *proc, void *thr);26void __tsan_proc_unwire(void *proc, void *thr);27void __tsan_read(void *thr, void *addr, void *pc);28void __tsan_write(void *thr, void *addr, void *pc);29void __tsan_func_enter(void *thr, void *pc);30void __tsan_func_exit(void *thr);31void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz);32void __tsan_free(void *p, unsigned long sz);33void __tsan_acquire(void *thr, void *addr);34void __tsan_release(void *thr, void *addr);35void __tsan_release_acquire(void *thr, void *addr);36void __tsan_release_merge(void *thr, void *addr);37 38void *current_proc;39 40void symbolize_cb(long cmd, void *ctx) {41  switch (cmd) {42  case 0:43    if (current_proc == 0)44      abort();45    *(void**)ctx = current_proc;46  }47}48 49/*50 * See lib/tsan/rtl/tsan_platform.h for details of what the memory layout51 * of Go programs looks like.  To prevent running over existing mappings,52 * we pick an address slightly inside the Go heap region.53 */54void *go_heap = (void *)0xC011110000;55char *buf0;56 57void foobar() {}58void barfoo() {}59 60int main(void) {61  void *thr0 = 0;62  void *proc0 = 0;63  __tsan_init(&thr0, &proc0, symbolize_cb);64  current_proc = proc0;65 66#if defined(__riscv) && (__riscv_xlen == 64) && defined(__linux__)67  // Use correct go_heap for riscv64 sv39.68  if (65 - __builtin_clzl((unsigned long)__builtin_frame_address(0)) == 39) {69    go_heap = (void *)0x511100000;70  }71#endif72 73  // Allocate something resembling a heap in Go.74  buf0 = mmap(go_heap, 16384, PROT_READ | PROT_WRITE,75              MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);76  if (buf0 == MAP_FAILED) {77    fprintf(stderr, "failed to allocate Go-like heap at %p; errno %d\n",78            go_heap, errno);79    return 1;80  }81  char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));82  __tsan_map_shadow(buf, 4096);83  __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);84  __tsan_free(buf, 10);85  __tsan_func_enter(thr0, (char*)&main + 1);86  __tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);87  __tsan_release(thr0, buf);88  __tsan_release_acquire(thr0, buf);89  __tsan_release_merge(thr0, buf);90  void *thr1 = 0;91  __tsan_go_start(thr0, &thr1, (char*)&barfoo + 1);92  void *thr2 = 0;93  __tsan_go_start(thr0, &thr2, (char*)&barfoo + 1);94  __tsan_func_exit(thr0);95  __tsan_func_enter(thr1, (char*)&foobar + 1);96  __tsan_func_enter(thr1, (char*)&foobar + 1);97  __tsan_write(thr1, buf, (char*)&barfoo + 1);98  __tsan_acquire(thr1, buf);99  __tsan_func_exit(thr1);100  __tsan_func_exit(thr1);101  __tsan_go_end(thr1);102  void *proc1 = 0;103  __tsan_proc_create(&proc1);104  current_proc = proc1;105  __tsan_func_enter(thr2, (char*)&foobar + 1);106  __tsan_read(thr2, buf, (char*)&barfoo + 1);107  __tsan_free(buf, 10);108  __tsan_func_exit(thr2);109  __tsan_go_end(thr2);110  __tsan_proc_destroy(proc1);111  current_proc = proc0;112  __tsan_fini();113  return 0;114}115