Home | History | Annotate | Download | only in msan
      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