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 15 extern "C" void __msan_set_indirect_call_wrapper(uintptr_t); 16 17 bool done_f, done_g; 18 19 void f(void) { 20 assert(!done_g); 21 done_f = true; 22 } 23 24 void g(void) { 25 assert(done_f); 26 done_g = true; 27 } 28 29 typedef void (*Fn)(void); 30 extern "C" Fn my_wrapper(Fn target) { 31 if (target == f) return g; 32 return target; 33 } 34 35 int 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