tsan: refactor overly-complex logical condition
[blocksruntime.git] / lib / sanitizer_common / sanitizer_libignore.cc
blob9e17819965f61edf1ae1a89a6ffb24ce52aaeb95
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 //===----------------------------------------------------------------------===//
10 #include "sanitizer_platform.h"
11 #if SANITIZER_LINUX
13 #include "sanitizer_libignore.h"
14 #include "sanitizer_procmaps.h"
16 namespace __sanitizer {
18 LibIgnore::LibIgnore(LinkerInitialized) {
21 void 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();
34 Lib *lib = &libs_[count_++];
35 lib->templ = internal_strdup(s->templ);
36 lib->name = 0;
37 lib->loaded = false;
41 void LibIgnore::OnLibraryLoaded(const char *name) {
42 const char *real_name = 0;
43 InternalScopedBuffer<char> buf(4096);
44 if (name != 0 && internal_readlink(name, buf.data(), buf.size() - 1) > 0)
45 real_name = buf.data();
47 BlockingMutexLock lock(&mutex_);
48 MemoryMappingLayout proc_maps(/*cache_enabled*/false);
49 InternalScopedBuffer<char> module(4096);
50 for (uptr i = 0; i < count_; i++) {
51 Lib *lib = &libs_[i];
52 bool loaded = false;
53 proc_maps.Reset();
54 uptr b, e, off, prot;
55 while (proc_maps.Next(&b, &e, &off, module.data(), module.size(), &prot)) {
56 if ((prot & MemoryMappingLayout::kProtectionExecute) == 0)
57 continue;
58 bool matched = false;
59 bool symlink = false;
60 if (TemplateMatch(lib->templ, module.data()))
61 matched = true;
62 // Resolve symlinks.
63 if (real_name != 0 && real_name[0] != 0 &&
64 TemplateMatch(lib->templ, name) &&
65 internal_strcmp(real_name, module.data()) == 0) {
66 matched = true;
67 symlink = true;
69 if (!matched)
70 continue;
71 if (loaded) {
72 Report("%s: called_from_lib suppression '%s' is matched against"
73 " 2 libraries: '%s' and '%s'\n",
74 SanitizerToolName, lib->templ, lib->name, module.data());
75 Die();
77 loaded = true;
78 if (lib->loaded)
79 continue;
80 lib->loaded = true;
81 lib->name = internal_strdup(module.data());
82 if (symlink)
83 lib->real_name = internal_strdup(real_name);
84 const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed);
85 code_ranges_[idx].begin = b;
86 code_ranges_[idx].end = e;
87 atomic_store(&loaded_count_, idx + 1, memory_order_release);
89 if (lib->loaded && !loaded) {
90 Report("%s: library '%s' that was matched against called_from_lib"
91 " suppression '%s' is unloaded\n",
92 SanitizerToolName, lib->name, lib->templ);
93 Die();
98 void LibIgnore::OnLibraryUnloaded() {
99 OnLibraryLoaded(0);
102 } // namespace __sanitizer
104 #endif // #if SANITIZER_LINUX