94 lines · c
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-exception6//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 using13// `disable_warnings=1,enable_check_stats=1,enable_warning_stats=1`).14//===----------------------------------------------------------------------===//15 16#ifndef NSAN_STATS_H17#define NSAN_STATS_H18 19#include "sanitizer_common/sanitizer_addrhashmap.h"20#include "sanitizer_common/sanitizer_internal_defs.h"21#include "sanitizer_common/sanitizer_mutex.h"22 23namespace __nsan {24 25enum 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 37class Stats {38public: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 was50 // invalid.51 void AddInvalidLoadTrackingEvent(__sanitizer::uptr pc, __sanitizer::uptr bp);52 // Signal that we detected a floating-point load where the shadow type was53 // unknown but the value was nonzero.54 void AddUnknownLoadTrackingEvent(__sanitizer::uptr pc, __sanitizer::uptr bp);55 56 void Print() const;57 58private: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 as67 // 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 88extern Stats *nsan_stats;89void InitializeStats();90 91} // namespace __nsan92 93#endif // NSAN_STATS_H94