brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · 63b63d3 Raw
87 lines · cpp
1// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s2// REQUIRES: x86_64-target-arch3// UNSUPPORTED: tvos, watchos4#include "test.h"5 6struct ucontext {7  void *sp;8  void *fiber;9};10 11extern "C" {12  void ucontext_do_switch(void **save, void **load);13  void ucontext_trampoline();14}15 16__asm__(".global " ASM_SYMBOL(ucontext_do_switch) "\n"17        ASM_SYMBOL(ucontext_do_switch) ":\n\t"18        "pushq %rbp\n\t"19        "pushq %r15\n\t"20        "pushq %r14\n\t"21        "pushq %r13\n\t"22        "pushq %r12\n\t"23        "pushq %rbx\n\t"24        "movq %rsp, (%rdi)\n\t"25        "movq (%rsi), %rsp\n\t"26        "popq %rbx\n\t"27        "popq %r12\n\t"28        "popq %r13\n\t"29        "popq %r14\n\t"30        "popq %r15\n\t"31        "popq %rbp\n\t"32        "retq");33 34__asm__(".global " ASM_SYMBOL(ucontext_trampoline) "\n"35        ASM_SYMBOL(ucontext_trampoline) ":\n\t"36        ".cfi_startproc\n\t"37        ".cfi_undefined rip\n\t"38        "movq %r12, %rdi\n\t"39        "jmpq *%rbx\n\t"40        ".cfi_endproc");41 42void ucontext_init(ucontext *context, void *stack, unsigned stack_sz,43                   void (*func)(void*), void *arg) {44  void **sp = reinterpret_cast<void **>(static_cast<char *>(stack) + stack_sz);45  *(--sp) = 0;46  *(--sp) = reinterpret_cast<void *>(ucontext_trampoline);47  *(--sp) = 0;   // rbp48  *(--sp) = 0;   // r1549  *(--sp) = 0;   // r1450  *(--sp) = 0;   // r1351  *(--sp) = arg; // r1252  *(--sp) = reinterpret_cast<void *>(func); // rbx53  context->sp = sp;54  context->fiber = __tsan_create_fiber(0);55}56 57void ucontext_free(ucontext *context) {58  __tsan_destroy_fiber(context->fiber);59}60 61__attribute__((no_sanitize_thread))62void ucontext_switch(ucontext *save, ucontext *load) {63  save->fiber = __tsan_get_current_fiber();64  __tsan_switch_to_fiber(load->fiber, 0);65  ucontext_do_switch(&save->sp, &load->sp);66}67 68char stack[64 * 1024] __attribute__((aligned(16)));69 70ucontext uc, orig_uc;71 72void func(void *arg) {73  __asm__ __volatile__(".cfi_undefined rip");74  ucontext_switch(&uc, &orig_uc);75}76 77int main() {78  ucontext_init(&uc, stack, sizeof(stack), func, 0);79  ucontext_switch(&orig_uc, &uc);80  ucontext_free(&uc);81  fprintf(stderr, "PASS\n");82  return 0;83}84 85// CHECK-NOT: WARNING: ThreadSanitizer:86// CHECK: PASS87