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 26 namespace __sanitizer { 27 28 class 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 73 inline 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