1 //===-- sanitizer_libignore.cc --------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "sanitizer_platform.h"
12 #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
13 SANITIZER_NETBSD || SANITIZER_OPENBSD
15 #include "sanitizer_libignore.h"
16 #include "sanitizer_flags.h"
17 #include "sanitizer_posix.h"
18 #include "sanitizer_procmaps.h"
20 namespace __sanitizer {
22 LibIgnore::LibIgnore(LinkerInitialized) {
25 void LibIgnore::AddIgnoredLibrary(const char *name_templ) {
26 BlockingMutexLock lock(&mutex_);
27 if (count_ >= kMaxLibs) {
28 Report("%s: too many ignored libraries (max: %d)\n", SanitizerToolName,
32 Lib *lib = &libs_[count_++];
33 lib->templ = internal_strdup(name_templ);
35 lib->real_name = nullptr;
39 void LibIgnore::OnLibraryLoaded(const char *name) {
40 BlockingMutexLock lock(&mutex_);
41 // Try to match suppressions with symlink target.
42 InternalScopedString buf(kMaxPathLength);
43 if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 &&
45 for (uptr i = 0; i < count_; i++) {
47 if (!lib->loaded && (!lib->real_name) &&
48 TemplateMatch(lib->templ, name))
49 lib->real_name = internal_strdup(buf.data());
53 // Scan suppressions list and find newly loaded and unloaded libraries.
54 ListOfModules modules;
56 for (uptr i = 0; i < count_; i++) {
59 for (const auto &mod : modules) {
60 for (const auto &range : mod.ranges()) {
61 if (!range.executable)
63 if (!TemplateMatch(lib->templ, mod.full_name()) &&
65 internal_strcmp(lib->real_name, mod.full_name()) == 0))
68 Report("%s: called_from_lib suppression '%s' is matched against"
69 " 2 libraries: '%s' and '%s'\n",
70 SanitizerToolName, lib->templ, lib->name, mod.full_name());
77 "Matched called_from_lib suppression '%s' against library"
79 lib->templ, mod.full_name());
81 lib->name = internal_strdup(mod.full_name());
83 atomic_load(&ignored_ranges_count_, memory_order_relaxed);
84 CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
85 ignored_code_ranges_[idx].begin = range.beg;
86 ignored_code_ranges_[idx].end = range.end;
87 atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
91 if (lib->loaded && !loaded) {
92 Report("%s: library '%s' that was matched against called_from_lib"
93 " suppression '%s' is unloaded\n",
94 SanitizerToolName, lib->name, lib->templ);
99 // Track instrumented ranges.
100 if (track_instrumented_libs_) {
101 for (const auto &mod : modules) {
102 if (!mod.instrumented())
104 for (const auto &range : mod.ranges()) {
105 if (!range.executable)
107 if (IsPcInstrumented(range.beg) && IsPcInstrumented(range.end - 1))
109 VReport(1, "Adding instrumented range %p-%p from library '%s'\n",
110 range.beg, range.end, mod.full_name());
112 atomic_load(&instrumented_ranges_count_, memory_order_relaxed);
113 CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_));
114 instrumented_code_ranges_[idx].begin = range.beg;
115 instrumented_code_ranges_[idx].end = range.end;
116 atomic_store(&instrumented_ranges_count_, idx + 1,
117 memory_order_release);
123 void LibIgnore::OnLibraryUnloaded() {
124 OnLibraryLoaded(nullptr);
127 } // namespace __sanitizer
129 #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC ||