brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 0e26ff4 Raw
127 lines · c
1//===-- sanitizer_libignore.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// LibIgnore allows to ignore all interceptors called from a particular set10// of dynamic libraries. LibIgnore can be initialized with several templates11// of names of libraries to be ignored. It finds code ranges for the libraries;12// and checks whether the provided PC value belongs to the code ranges.13//14//===----------------------------------------------------------------------===//15 16#ifndef SANITIZER_LIBIGNORE_H17#define SANITIZER_LIBIGNORE_H18 19#include "sanitizer_internal_defs.h"20#include "sanitizer_common.h"21#include "sanitizer_atomic.h"22#include "sanitizer_mutex.h"23 24namespace __sanitizer {25 26class LibIgnore {27 public:28  explicit LibIgnore(LinkerInitialized);29 30  // Must be called during initialization.31  void AddIgnoredLibrary(const char *name_templ);32  void IgnoreNoninstrumentedModules(bool enable) {33    track_instrumented_libs_ = enable;34  }35 36  // Must be called after a new dynamic library is loaded.37  void OnLibraryLoaded(const char *name);38 39  // Must be called after a dynamic library is unloaded.40  void OnLibraryUnloaded();41 42  // Checks whether the provided PC belongs to one of the ignored libraries or43  // the PC should be ignored because it belongs to an non-instrumented module44  // (when ignore_noninstrumented_modules=1). Also returns true via45  // "pc_in_ignored_lib" if the PC is in an ignored library, false otherwise.46  bool IsIgnored(uptr pc, bool *pc_in_ignored_lib) const;47 48  // Checks whether the provided PC belongs to an instrumented module.49  bool IsPcInstrumented(uptr pc) const;50 51 private:52  static const uptr kMaxIgnoredRanges = 128;53  static const uptr kMaxInstrumentedRanges = 1024;54  static const uptr kMaxLibs = 1024;55  static const uptr kInvalidCodeRangeId = -1;56 57  struct Lib {58    char *templ;59    char *name;60    char *real_name;  // target of symlink61    uptr range_id;62    bool loaded() const { return range_id != kInvalidCodeRangeId; };63  };64 65  struct LibCodeRange {66    bool IsInRange(uptr pc) const {67      return (pc >= begin && pc < atomic_load(&end, memory_order_acquire));68    }69 70    void OnLoad(uptr b, uptr e) {71      begin = b;72      atomic_store(&end, e, memory_order_release);73    }74 75    void OnUnload() { atomic_store(&end, 0, memory_order_release); }76 77   private:78    uptr begin;79    // A value of 0 means the associated module was unloaded.80    atomic_uintptr_t end;81  };82 83  // Hot part:84  atomic_uintptr_t ignored_ranges_count_;85  LibCodeRange ignored_code_ranges_[kMaxIgnoredRanges];86 87  atomic_uintptr_t instrumented_ranges_count_;88  LibCodeRange instrumented_code_ranges_[kMaxInstrumentedRanges];89 90  // Cold part:91  Mutex mutex_;92  uptr count_;93  Lib libs_[kMaxLibs];94  bool track_instrumented_libs_;95 96  // Disallow copying of LibIgnore objects.97  LibIgnore(const LibIgnore&);  // not implemented98  void operator = (const LibIgnore&);  // not implemented99};100 101inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const {102  const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire);103  for (uptr i = 0; i < n; i++) {104    if (ignored_code_ranges_[i].IsInRange(pc)) {105      *pc_in_ignored_lib = true;106      return true;107    }108  }109  *pc_in_ignored_lib = false;110  if (track_instrumented_libs_ && !IsPcInstrumented(pc))111    return true;112  return false;113}114 115inline bool LibIgnore::IsPcInstrumented(uptr pc) const {116  const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire);117  for (uptr i = 0; i < n; i++) {118    if (instrumented_code_ranges_[i].IsInRange(pc))119      return true;120  }121  return false;122}123 124}  // namespace __sanitizer125 126#endif  // SANITIZER_LIBIGNORE_H127