1 // Test indirect call wrapping in MemorySanitizer runtime.
3 // RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t && %run %t
12 extern "C" void __msan_set_indirect_call_wrapper(uintptr_t);
14 bool pthread_create_done
;
16 void *ThreadFn(void *) {
17 printf("bad threadfn\n");
21 void *ThreadFn2(void *) {
22 printf("good threadfn\n");
23 pthread_create_done
= true;
30 int my_gettimeofday(struct timeval
*p
, void *q
) {
36 double my_lgamma(double x
) {
40 extern "C" uintptr_t my_wrapper(uintptr_t f
) {
41 if (f
== (uintptr_t)ThreadFn
)
42 return (uintptr_t)&ThreadFn2
;
44 return (uintptr_t)my_gettimeofday
;
46 return (uintptr_t)my_lgamma
;
51 __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper
);
53 // ThreadFn is called indirectly from a wrapper function in MSan rtl and
54 // is subject to indirect call wrapping (it could be an native-to-translated
57 pthread_create(&t
, 0, ThreadFn
, 0);
59 assert(pthread_create_done
);
61 // gettimeofday is intercepted in msan_interceptors.cc and the real one (from
62 // libc) is called indirectly.
64 in_gettimeofday
= true;
65 int res
= gettimeofday(&tv
, NULL
);
66 in_gettimeofday
= false;
67 assert(tv
.tv_sec
== 1);
68 assert(tv
.tv_usec
== 2);
71 // lgamma is intercepted in sanitizer_common_interceptors.inc and is also
74 double dres
= lgamma(1.1);