1 /*===- DataFlowCallbacks.cpp - a standalone DataFlow trace -------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 // Instrumentation callbacks for DataFlow.cpp.
9 // These functions should not be instrumented by DFSan, so we
10 // keep them in a separate file and compile it w/o DFSan.
11 //===----------------------------------------------------------------------===*/
18 static __thread
size_t CurrentFunc
;
19 static uint32_t *GuardsBeg
, *GuardsEnd
;
20 static inline bool BlockIsEntry(size_t BlockIdx
) {
21 return __dft
.PCsBeg
[BlockIdx
* 2 + 1] & PCFLAG_FUNC_ENTRY
;
26 void __sanitizer_cov_trace_pc_guard_init(uint32_t *start
,
28 assert(__dft
.NumFuncs
== 0 && "This tool does not support DSOs");
29 assert(start
< stop
&& "The code is not instrumented for coverage");
30 if (start
== stop
|| *start
) return; // Initialize only once.
35 void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg
,
36 const uintptr_t *pcs_end
) {
37 if (__dft
.NumGuards
) return; // Initialize only once.
38 __dft
.NumGuards
= GuardsEnd
- GuardsBeg
;
39 __dft
.PCsBeg
= pcs_beg
;
40 __dft
.PCsEnd
= pcs_end
;
41 assert(__dft
.NumGuards
== (__dft
.PCsEnd
- __dft
.PCsBeg
) / 2);
42 for (size_t i
= 0; i
< __dft
.NumGuards
; i
++) {
43 if (BlockIsEntry(i
)) {
45 GuardsBeg
[i
] = __dft
.NumFuncs
;
48 __dft
.BBExecuted
= (bool*)calloc(__dft
.NumGuards
, sizeof(bool));
49 fprintf(stderr
, "INFO: %zd instrumented function(s) observed "
50 "and %zd basic blocks\n", __dft
.NumFuncs
, __dft
.NumGuards
);
53 void __sanitizer_cov_trace_pc_indir(uint64_t x
){} // unused.
55 void __sanitizer_cov_trace_pc_guard(uint32_t *guard
) {
56 size_t GuardIdx
= guard
- GuardsBeg
;
57 // assert(GuardIdx < __dft.NumGuards);
58 __dft
.BBExecuted
[GuardIdx
] = true;
59 if (!*guard
) return; // not a function entry.
60 uint32_t FuncNum
= *guard
- 1; // Guards start from 1.
61 // assert(FuncNum < __dft.NumFuncs);
62 CurrentFunc
= FuncNum
;
65 void __dfsw___sanitizer_cov_trace_switch(uint64_t Val
, uint64_t *Cases
,
66 dfsan_label L1
, dfsan_label UnusedL
) {
67 assert(CurrentFunc
< __dft
.NumFuncs
);
68 __dft
.FuncLabels
[CurrentFunc
] |= L1
;
71 #define HOOK(Name, Type) \
72 void Name(Type Arg1, Type Arg2, dfsan_label L1, dfsan_label L2) { \
73 __dft.FuncLabels[CurrentFunc] |= L1 | L2; \
75 //assert(CurrentFunc < __dft.NumFuncs);
77 HOOK(__dfsw___sanitizer_cov_trace_const_cmp1
, uint8_t)
78 HOOK(__dfsw___sanitizer_cov_trace_const_cmp2
, uint16_t)
79 HOOK(__dfsw___sanitizer_cov_trace_const_cmp4
, uint32_t)
80 HOOK(__dfsw___sanitizer_cov_trace_const_cmp8
, uint64_t)
81 HOOK(__dfsw___sanitizer_cov_trace_cmp1
, uint8_t)
82 HOOK(__dfsw___sanitizer_cov_trace_cmp2
, uint16_t)
83 HOOK(__dfsw___sanitizer_cov_trace_cmp4
, uint32_t)
84 HOOK(__dfsw___sanitizer_cov_trace_cmp8
, uint64_t)