sanitizer_libignore.cc revision 4af0f21c0c98950df1136dbec8824a029ed5bb8e
1//===-- sanitizer_libignore.cc --------------------------------------------===// 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#include "sanitizer_platform.h" 11#if SANITIZER_LINUX 12 13#include "sanitizer_libignore.h" 14#include "sanitizer_procmaps.h" 15 16namespace __sanitizer { 17 18LibIgnore::LibIgnore(LinkerInitialized) { 19} 20 21void LibIgnore::Init(const SuppressionContext &supp) { 22 BlockingMutexLock lock(&mutex_); 23 CHECK_EQ(count_, 0); 24 const uptr n = supp.SuppressionCount(); 25 for (uptr i = 0; i < n; i++) { 26 const Suppression *s = supp.SuppressionAt(i); 27 if (s->type != SuppressionLib) 28 continue; 29 if (count_ >= kMaxLibs) { 30 Report("%s: too many called_from_lib suppressions (max: %d)\n", 31 SanitizerToolName, kMaxLibs); 32 Die(); 33 } 34 Lib *lib = &libs_[count_++]; 35 lib->templ = internal_strdup(s->templ); 36 lib->name = 0; 37 lib->loaded = false; 38 } 39} 40 41void LibIgnore::OnLibraryLoaded() { 42 BlockingMutexLock lock(&mutex_); 43 MemoryMappingLayout proc_maps(/*cache_enabled*/false); 44 InternalScopedBuffer<char> fn(4096); 45 for (uptr i = 0; i < count_; i++) { 46 Lib *lib = &libs_[i]; 47 bool loaded = false; 48 proc_maps.Reset(); 49 uptr b, e, off, prot; 50 while (proc_maps.Next(&b, &e, &off, fn.data(), fn.size(), &prot)) { 51 if ((prot & MemoryMappingLayout::kProtectionExecute) != 0 && 52 TemplateMatch(lib->templ, fn.data())) { 53 if (loaded) { 54 Report("%s: called_from_lib suppression '%s' is matched against" 55 " 2 libraries: '%s' and '%s'\n", 56 SanitizerToolName, lib->templ, lib->name, fn.data()); 57 Die(); 58 } 59 loaded = true; 60 if (!lib->loaded) { 61 lib->loaded = true; 62 lib->name = internal_strdup(fn.data()); 63 const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed); 64 code_ranges_[idx].begin = b; 65 code_ranges_[idx].end = e; 66 atomic_store(&loaded_count_, idx + 1, memory_order_release); 67 } 68 } 69 } 70 if (lib->loaded && !loaded) { 71 Report("%s: library '%s' that was matched against called_from_lib" 72 " suppression '%s' is unloaded\n", 73 SanitizerToolName, lib->name, lib->templ); 74 Die(); 75 } 76 } 77} 78 79void LibIgnore::OnLibraryUnloaded() { 80 OnLibraryLoaded(); 81} 82 83} // namespace __sanitizer 84 85#endif // #if SANITIZER_LINUX 86