1 // Tests -fsanitize-coverage=control-flow.
3 // REQUIRES: has_sancovcc,stable-runtime
4 // UNSUPPORTED: i386-darwin, x86_64-darwin
6 // RUN: %clangxx -O0 -std=c++11 -fsanitize-coverage=control-flow %s -o %t
7 // RUN: %run %t 2>&1 | FileCheck %s
11 #if __has_feature(ptrauth_calls)
14 #define ptrauth_strip(__value, __key) (__value)
17 uintptr_t *CFS_BEG
, *CFS_END
;
19 extern "C" void __sanitizer_cov_cfs_init(const uintptr_t *cfs_beg
,
20 const uintptr_t *cfs_end
) {
21 CFS_BEG
= (uintptr_t *)cfs_beg
;
22 CFS_END
= (uintptr_t *)cfs_end
;
25 __attribute__((noinline
)) void foo(int x
) { /* empty body */
28 void check_cfs_section(uintptr_t main_ptr
, uintptr_t foo_ptr
) {
29 printf("Control Flow section boundaries: [%p %p)\n", CFS_BEG
, CFS_END
);
30 uintptr_t *pt
= CFS_BEG
;
33 while (pt
< CFS_END
) {
37 if (currBB
== main_ptr
)
38 printf("Saw the main().\n");
39 else if (currBB
== foo_ptr
)
40 printf("Saw the foo().\n");
42 // Iterate over successors.
47 // Iterate over callees.
49 if (*pt
== foo_ptr
&& currBB
!= main_ptr
)
50 printf("Direct call matched.\n");
51 if (*pt
== -1 && currBB
!= main_ptr
)
52 printf("Indirect call matched.\n");
60 auto main_ptr
= ptrauth_strip(&main
, ptrauth_key_function_pointer
);
61 auto foo_ptr
= ptrauth_strip(&foo
, ptrauth_key_function_pointer
);
69 check_cfs_section((uintptr_t)(*main_ptr
), (uintptr_t)(*foo_ptr
));
71 printf("Finished!\n");
75 // CHECK: Control Flow section boundaries
76 // CHECK-DAG: Saw the foo().
77 // CHECK-DAG: Saw the main().
78 // CHECK-DAG: Direct call matched.
79 // CHECK-DAG: Indirect call matched.