1//===-- sanitizer_libignore.h -----------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// LibIgnore allows to ignore all interceptors called from a particular set 11// of dynamic libraries. LibIgnore remembers all "called_from_lib" suppressions 12// from the provided SuppressionContext; finds code ranges for the libraries; 13// and checks whether the provided PC value belongs to the code ranges. 14// 15//===----------------------------------------------------------------------===// 16 17#ifndef SANITIZER_LIBIGNORE_H 18#define SANITIZER_LIBIGNORE_H 19 20#include "sanitizer_internal_defs.h" 21#include "sanitizer_common.h" 22#include "sanitizer_suppressions.h" 23#include "sanitizer_atomic.h" 24#include "sanitizer_mutex.h" 25 26namespace __sanitizer { 27 28class LibIgnore { 29 public: 30 explicit LibIgnore(LinkerInitialized); 31 32 // Fetches all "called_from_lib" suppressions from the SuppressionContext. 33 void Init(const SuppressionContext &supp); 34 35 // Must be called after a new dynamic library is loaded. 36 void OnLibraryLoaded(const char *name); 37 38 // Must be called after a dynamic library is unloaded. 39 void OnLibraryUnloaded(); 40 41 // Checks whether the provided PC belongs to one of the ignored libraries. 42 bool IsIgnored(uptr pc) const; 43 44 private: 45 struct Lib { 46 char *templ; 47 char *name; 48 char *real_name; // target of symlink 49 bool loaded; 50 }; 51 52 struct LibCodeRange { 53 uptr begin; 54 uptr end; 55 }; 56 57 static const uptr kMaxLibs = 128; 58 59 // Hot part: 60 atomic_uintptr_t loaded_count_; 61 LibCodeRange code_ranges_[kMaxLibs]; 62 63 // Cold part: 64 BlockingMutex mutex_; 65 uptr count_; 66 Lib libs_[kMaxLibs]; 67 68 // Disallow copying of LibIgnore objects. 69 LibIgnore(const LibIgnore&); // not implemented 70 void operator = (const LibIgnore&); // not implemented 71}; 72 73inline bool LibIgnore::IsIgnored(uptr pc) const { 74 const uptr n = atomic_load(&loaded_count_, memory_order_acquire); 75 for (uptr i = 0; i < n; i++) { 76 if (pc >= code_ranges_[i].begin && pc < code_ranges_[i].end) 77 return true; 78 } 79 return false; 80} 81 82} // namespace __sanitizer 83 84#endif // SANITIZER_LIBIGNORE_H 85