1// Test __msan_set_indirect_call_wrapper. 2 3// RUN: %clangxx_msan -mllvm -msan-wrap-indirect-calls=__msan_wrap_indirect_call \ 4// RUN: -mllvm -msan-wrap-indirect-calls-fast=0 \ 5// RUN: -O0 -g -rdynamic -Wl,--defsym=__executable_start=0 %s -o %t && %run %t 6 7// This test disables -msan-wrap-indirect-calls-fast, otherwise indirect calls 8// inside the same module are short-circuited and are never seen by the wrapper. 9 10#include <assert.h> 11#include <pthread.h> 12#include <stdio.h> 13#include <stdint.h> 14 15extern "C" void __msan_set_indirect_call_wrapper(uintptr_t); 16 17bool done_f, done_g; 18 19void f(void) { 20 assert(!done_g); 21 done_f = true; 22} 23 24void g(void) { 25 assert(done_f); 26 done_g = true; 27} 28 29typedef void (*Fn)(void); 30extern "C" Fn my_wrapper(Fn target) { 31 if (target == f) return g; 32 return target; 33} 34 35int main(void) { 36 volatile Fn fp; 37 fp = &f; 38 fp(); 39 __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper); 40 fp(); 41 return !(done_f && done_g); 42} 43