Dmitry Vyukov | 5ba7364 | 2013-10-03 13:37:17 +0000 | [diff] [blame] | 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 |
Alexey Samsonov | 1ec3c5b | 2015-02-19 22:56:49 +0000 | [diff] [blame] | 11 | // of dynamic libraries. LibIgnore can be initialized with several templates |
| 12 | // of names of libraries to be ignored. It finds code ranges for the libraries; |
Dmitry Vyukov | 5ba7364 | 2013-10-03 13:37:17 +0000 | [diff] [blame] | 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" |
Dmitry Vyukov | 5ba7364 | 2013-10-03 13:37:17 +0000 | [diff] [blame] | 22 | #include "sanitizer_atomic.h" |
| 23 | #include "sanitizer_mutex.h" |
| 24 | |
| 25 | namespace __sanitizer { |
| 26 | |
| 27 | class LibIgnore { |
| 28 | public: |
| 29 | explicit LibIgnore(LinkerInitialized); |
| 30 | |
Alexey Samsonov | 1ec3c5b | 2015-02-19 22:56:49 +0000 | [diff] [blame] | 31 | // Must be called during initialization. |
| 32 | void AddIgnoredLibrary(const char *name_templ); |
Dmitry Vyukov | 5ba7364 | 2013-10-03 13:37:17 +0000 | [diff] [blame] | 33 | |
| 34 | // Must be called after a new dynamic library is loaded. |
Dmitry Vyukov | 6f61206 | 2013-10-15 11:34:59 +0000 | [diff] [blame] | 35 | void OnLibraryLoaded(const char *name); |
Dmitry Vyukov | 5ba7364 | 2013-10-03 13:37:17 +0000 | [diff] [blame] | 36 | |
| 37 | // Must be called after a dynamic library is unloaded. |
| 38 | void OnLibraryUnloaded(); |
| 39 | |
| 40 | // Checks whether the provided PC belongs to one of the ignored libraries. |
| 41 | bool IsIgnored(uptr pc) const; |
| 42 | |
| 43 | private: |
| 44 | struct Lib { |
| 45 | char *templ; |
| 46 | char *name; |
Dmitry Vyukov | 6f61206 | 2013-10-15 11:34:59 +0000 | [diff] [blame] | 47 | char *real_name; // target of symlink |
Dmitry Vyukov | 5ba7364 | 2013-10-03 13:37:17 +0000 | [diff] [blame] | 48 | bool loaded; |
| 49 | }; |
| 50 | |
| 51 | struct LibCodeRange { |
| 52 | uptr begin; |
| 53 | uptr end; |
| 54 | }; |
| 55 | |
| 56 | static const uptr kMaxLibs = 128; |
| 57 | |
| 58 | // Hot part: |
| 59 | atomic_uintptr_t loaded_count_; |
| 60 | LibCodeRange code_ranges_[kMaxLibs]; |
| 61 | |
| 62 | // Cold part: |
| 63 | BlockingMutex mutex_; |
| 64 | uptr count_; |
| 65 | Lib libs_[kMaxLibs]; |
| 66 | |
| 67 | // Disallow copying of LibIgnore objects. |
| 68 | LibIgnore(const LibIgnore&); // not implemented |
| 69 | void operator = (const LibIgnore&); // not implemented |
| 70 | }; |
| 71 | |
| 72 | inline bool LibIgnore::IsIgnored(uptr pc) const { |
| 73 | const uptr n = atomic_load(&loaded_count_, memory_order_acquire); |
| 74 | for (uptr i = 0; i < n; i++) { |
| 75 | if (pc >= code_ranges_[i].begin && pc < code_ranges_[i].end) |
| 76 | return true; |
| 77 | } |
| 78 | return false; |
| 79 | } |
| 80 | |
| 81 | } // namespace __sanitizer |
| 82 | |
| 83 | #endif // SANITIZER_LIBIGNORE_H |