xref: /freebsd/contrib/llvm-project/compiler-rt/lib/nsan/nsan_stats.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- nsan_stats.h --------------------------------------------*- C++- *-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of NumericalStabilitySanitizer.
10 //
11 // NSan statistics. This class counts the number of checks per code location,
12 // and is used to output statistics (typically when using
13 // `disable_warnings=1,enable_check_stats=1,enable_warning_stats=1`).
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef NSAN_STATS_H
17 #define NSAN_STATS_H
18 
19 #include "sanitizer_common/sanitizer_addrhashmap.h"
20 #include "sanitizer_common/sanitizer_internal_defs.h"
21 #include "sanitizer_common/sanitizer_mutex.h"
22 
23 namespace __nsan {
24 
25 enum class CheckTypeT {
26   kUnknown = 0,
27   kRet,
28   kArg,
29   kLoad,
30   kStore,
31   kInsert,
32   kUser, // User initiated.
33   kFcmp,
34   kMaxCheckType,
35 };
36 
37 class Stats {
38 public:
39   Stats();
40   ~Stats();
41 
42   // Signal that we checked the instruction at the given address.
43   void AddCheck(CheckTypeT check_ty, __sanitizer::uptr pc, __sanitizer::uptr bp,
44                 double rel_err);
45   // Signal that we warned for the instruction at the given address.
46   void AddWarning(CheckTypeT check_ty, __sanitizer::uptr pc,
47                   __sanitizer::uptr bp, double rel_err);
48 
49   // Signal that we detected a floating-point load where the shadow type was
50   // invalid.
51   void AddInvalidLoadTrackingEvent(__sanitizer::uptr pc, __sanitizer::uptr bp);
52   // Signal that we detected a floating-point load where the shadow type was
53   // unknown but the value was nonzero.
54   void AddUnknownLoadTrackingEvent(__sanitizer::uptr pc, __sanitizer::uptr bp);
55 
56   void Print() const;
57 
58 private:
59   using IndexMap = __sanitizer::AddrHashMap<__sanitizer::uptr, 11>;
60 
61   struct CheckAndWarningsValue {
62     CheckTypeT check_ty;
63     __sanitizer::u32 stack_id = 0;
64     __sanitizer::u64 num_checks = 0;
65     __sanitizer::u64 num_warnings = 0;
66     // This is a bitcasted double. Doubles have the nice idea to be ordered as
67     // ints.
68     double max_relative_err = 0;
69   };
70   // Map Key(check_ty, StackId) to indices in CheckAndWarnings.
71   IndexMap CheckAndWarningsMap;
72   __sanitizer::InternalMmapVectorNoCtor<CheckAndWarningsValue>
73       check_and_warnings;
74   mutable __sanitizer::Mutex check_and_warning_mutex;
75 
76   struct LoadTrackingValue {
77     CheckTypeT check_ty;
78     __sanitizer::u32 stack_id = 0;
79     __sanitizer::u64 num_invalid = 0;
80     __sanitizer::u64 num_unknown = 0;
81   };
82   // Map Key(CheckTypeT::kLoad, StackId) to indices in TrackedLoads.
83   IndexMap LoadTrackingMap;
84   __sanitizer::InternalMmapVectorNoCtor<LoadTrackingValue> TrackedLoads;
85   mutable __sanitizer::Mutex TrackedLoadsMutex;
86 };
87 
88 extern Stats *nsan_stats;
89 void InitializeStats();
90 
91 } // namespace __nsan
92 
93 #endif // NSAN_STATS_H
94