[ASan/Win] Add a comment about DCL-using-static vs threads
[blocksruntime.git] / test / msan / wrap_indirect_calls_in_rtl.cc
blob040ff13f6881eaf23670f58fe869388975d62f63
1 // Test indirect call wrapping in MemorySanitizer runtime.
3 // RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t && %run %t
5 #include <assert.h>
6 #include <math.h>
7 #include <pthread.h>
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <sys/time.h>
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");
18 return 0;
21 void *ThreadFn2(void *) {
22 printf("good threadfn\n");
23 pthread_create_done = true;
24 return 0;
27 bool in_gettimeofday;
28 bool in_lgamma;
30 int my_gettimeofday(struct timeval *p, void *q) {
31 p->tv_sec = 1;
32 p->tv_usec = 2;
33 return 42;
36 double my_lgamma(double x) {
37 return x;
40 extern "C" uintptr_t my_wrapper(uintptr_t f) {
41 if (f == (uintptr_t)ThreadFn)
42 return (uintptr_t)&ThreadFn2;
43 if (in_gettimeofday)
44 return (uintptr_t)my_gettimeofday;
45 if (in_lgamma)
46 return (uintptr_t)my_lgamma;
47 return f;
50 int main(void) {
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
55 // edge).
56 pthread_t t;
57 pthread_create(&t, 0, ThreadFn, 0);
58 pthread_join(t, 0);
59 assert(pthread_create_done);
61 // gettimeofday is intercepted in msan_interceptors.cc and the real one (from
62 // libc) is called indirectly.
63 struct timeval tv;
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);
69 assert(res == 42);
71 // lgamma is intercepted in sanitizer_common_interceptors.inc and is also
72 // called indirectly.
73 in_lgamma = true;
74 double dres = lgamma(1.1);
75 in_lgamma = false;
76 assert(dres == 1.1);
78 return 0;