File: sanitizer_coverage_control_flow.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (80 lines) | stat: -rw-r--r-- 1,926 bytes parent folder | download | duplicates (19)
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Tests -fsanitize-coverage=control-flow.

// REQUIRES: has_sancovcc,stable-runtime
// UNSUPPORTED: i386-darwin, x86_64-darwin

// RUN: %clangxx -O0 -std=c++11 -fsanitize-coverage=control-flow %s -o %t
// RUN: %run %t 2>&1 | FileCheck %s

#include <cstdint>
#include <cstdio>
#if __has_feature(ptrauth_calls)
  #include <ptrauth.h>
#else
  #define ptrauth_strip(__value, __key) (__value)
#endif

uintptr_t *CFS_BEG, *CFS_END;

extern "C" void __sanitizer_cov_cfs_init(const uintptr_t *cfs_beg,
                                         const uintptr_t *cfs_end) {
  CFS_BEG = (uintptr_t *)cfs_beg;
  CFS_END = (uintptr_t *)cfs_end;
}

__attribute__((noinline)) void foo(int x) { /* empty body */
}

void check_cfs_section(uintptr_t main_ptr, uintptr_t foo_ptr) {
  printf("Control Flow section boundaries: [%p %p)\n", CFS_BEG, CFS_END);
  uintptr_t *pt = CFS_BEG;
  uintptr_t currBB;

  while (pt < CFS_END) {
    currBB = *pt;
    pt++;

    if (currBB == main_ptr)
      printf("Saw the main().\n");
    else if (currBB == foo_ptr)
      printf("Saw the foo().\n");

    // Iterate over successors.
    while (*pt) {
      pt++;
    }
    pt++;
    // Iterate over callees.
    while (*pt) {
      if (*pt == foo_ptr && currBB != main_ptr)
        printf("Direct call matched.\n");
      if (*pt == -1 && currBB != main_ptr)
        printf("Indirect call matched.\n");
      pt++;
    }
    pt++;
  }
}

int main() {
  auto main_ptr = ptrauth_strip(&main, ptrauth_key_function_pointer);
  auto foo_ptr = ptrauth_strip(&foo, ptrauth_key_function_pointer);
  int x = 10;

  if (x > 0)
    foo(x);
  else
    (*foo_ptr)(x);

  check_cfs_section((uintptr_t)(*main_ptr), (uintptr_t)(*foo_ptr));

  printf("Finished!\n");
  return 0;
}

// CHECK: Control Flow section boundaries
// CHECK-DAG: Saw the foo().
// CHECK-DAG: Saw the main().
// CHECK-DAG: Direct call matched.
// CHECK-DAG: Indirect call matched.
// CHECK: Finished!