summaryrefslogtreecommitdiff
path: root/test/msan/wrap_indirect_calls2.cc
blob: fb4e6c798d6effe4bff731441d99ee8ccf6ac7db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Test __msan_set_indirect_call_wrapper.

// RUN: %clangxx_msan -mllvm -msan-wrap-indirect-calls=__msan_wrap_indirect_call \
// RUN:     -mllvm -msan-wrap-indirect-calls-fast=0 \
// RUN:     -O0 -g -rdynamic -Wl,--defsym=__executable_start=0 %s -o %t && %run %t

// This test disables -msan-wrap-indirect-calls-fast, otherwise indirect calls
// inside the same module are short-circuited and are never seen by the wrapper.

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>

extern "C" void __msan_set_indirect_call_wrapper(uintptr_t);

bool done_f, done_g;

void f(void) {
  assert(!done_g);
  done_f = true;
}

void g(void) {
  assert(done_f);
  done_g = true;
}

typedef void (*Fn)(void);
extern "C" Fn my_wrapper(Fn target) {
  if (target == f) return g;
  return target;
}

int main(void) {
  volatile Fn fp;
  fp = &f;
  fp();
  __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper);
  fp();
  return !(done_f && done_g);
}