Home | History | Annotate | Download | only in sanitizer_common
      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 can be initialized with several templates
     12 // of names of libraries to be ignored. It 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_atomic.h"
     23 #include "sanitizer_mutex.h"
     24 
     25 namespace __sanitizer {
     26 
     27 class LibIgnore {
     28  public:
     29   explicit LibIgnore(LinkerInitialized);
     30 
     31   // Must be called during initialization.
     32   void AddIgnoredLibrary(const char *name_templ);
     33 
     34   // Must be called after a new dynamic library is loaded.
     35   void OnLibraryLoaded(const char *name);
     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;
     47     char *real_name;  // target of symlink
     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
     84