blob: fb4e6c798d6effe4bff731441d99ee8ccf6ac7db [file] [log] [blame]
// 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);
}