14af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov//===-- sanitizer_libignore.h -----------------------------------*- C++ -*-===// 24af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// 34af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// The LLVM Compiler Infrastructure 44af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// 54af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// This file is distributed under the University of Illinois Open Source 64af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// License. See LICENSE.TXT for details. 74af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// 84af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov//===----------------------------------------------------------------------===// 94af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// 104af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// LibIgnore allows to ignore all interceptors called from a particular set 1186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// of dynamic libraries. LibIgnore can be initialized with several templates 1286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// of names of libraries to be ignored. It finds code ranges for the libraries; 134af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// and checks whether the provided PC value belongs to the code ranges. 144af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov// 154af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov//===----------------------------------------------------------------------===// 164af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 174af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#ifndef SANITIZER_LIBIGNORE_H 184af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#define SANITIZER_LIBIGNORE_H 194af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 204af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#include "sanitizer_internal_defs.h" 214af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#include "sanitizer_common.h" 224af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#include "sanitizer_atomic.h" 234af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#include "sanitizer_mutex.h" 244af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 254af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukovnamespace __sanitizer { 264af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 274af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukovclass LibIgnore { 284af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov public: 294af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov explicit LibIgnore(LinkerInitialized); 304af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 3186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Must be called during initialization. 3286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void AddIgnoredLibrary(const char *name_templ); 334af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 344af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov // Must be called after a new dynamic library is loaded. 353dbbd850cde5728c35aa4c15a279d858604fc6eeDmitry Vyukov void OnLibraryLoaded(const char *name); 364af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 374af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov // Must be called after a dynamic library is unloaded. 384af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov void OnLibraryUnloaded(); 394af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 404af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov // Checks whether the provided PC belongs to one of the ignored libraries. 414af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov bool IsIgnored(uptr pc) const; 424af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 434af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov private: 444af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov struct Lib { 454af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov char *templ; 464af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov char *name; 473dbbd850cde5728c35aa4c15a279d858604fc6eeDmitry Vyukov char *real_name; // target of symlink 484af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov bool loaded; 494af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov }; 504af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 514af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov struct LibCodeRange { 524af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov uptr begin; 534af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov uptr end; 544af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov }; 554af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 564af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov static const uptr kMaxLibs = 128; 574af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 584af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov // Hot part: 594af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov atomic_uintptr_t loaded_count_; 604af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov LibCodeRange code_ranges_[kMaxLibs]; 614af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 624af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov // Cold part: 634af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov BlockingMutex mutex_; 644af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov uptr count_; 654af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov Lib libs_[kMaxLibs]; 664af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 674af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov // Disallow copying of LibIgnore objects. 684af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov LibIgnore(const LibIgnore&); // not implemented 694af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov void operator = (const LibIgnore&); // not implemented 704af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov}; 714af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 724af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukovinline bool LibIgnore::IsIgnored(uptr pc) const { 734af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov const uptr n = atomic_load(&loaded_count_, memory_order_acquire); 744af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov for (uptr i = 0; i < n; i++) { 754af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov if (pc >= code_ranges_[i].begin && pc < code_ranges_[i].end) 764af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov return true; 774af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov } 784af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov return false; 794af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov} 804af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 814af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov} // namespace __sanitizer 824af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov 834af0f21c0c98950df1136dbec8824a029ed5bb8eDmitry Vyukov#endif // SANITIZER_LIBIGNORE_H 84