xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- sanitizer_libignore.cpp -------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick 
93cab2bb3Spatrick #include "sanitizer_platform.h"
103cab2bb3Spatrick 
11*810390e3Srobert #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \
12d89ec533Spatrick     SANITIZER_NETBSD
133cab2bb3Spatrick 
143cab2bb3Spatrick #include "sanitizer_libignore.h"
153cab2bb3Spatrick #include "sanitizer_flags.h"
163cab2bb3Spatrick #include "sanitizer_posix.h"
173cab2bb3Spatrick #include "sanitizer_procmaps.h"
183cab2bb3Spatrick 
193cab2bb3Spatrick namespace __sanitizer {
203cab2bb3Spatrick 
LibIgnore(LinkerInitialized)213cab2bb3Spatrick LibIgnore::LibIgnore(LinkerInitialized) {
223cab2bb3Spatrick }
233cab2bb3Spatrick 
AddIgnoredLibrary(const char * name_templ)243cab2bb3Spatrick void LibIgnore::AddIgnoredLibrary(const char *name_templ) {
25*810390e3Srobert   Lock lock(&mutex_);
263cab2bb3Spatrick   if (count_ >= kMaxLibs) {
27*810390e3Srobert     Report("%s: too many ignored libraries (max: %zu)\n", SanitizerToolName,
283cab2bb3Spatrick            kMaxLibs);
293cab2bb3Spatrick     Die();
303cab2bb3Spatrick   }
313cab2bb3Spatrick   Lib *lib = &libs_[count_++];
323cab2bb3Spatrick   lib->templ = internal_strdup(name_templ);
333cab2bb3Spatrick   lib->name = nullptr;
343cab2bb3Spatrick   lib->real_name = nullptr;
353cab2bb3Spatrick   lib->loaded = false;
363cab2bb3Spatrick }
373cab2bb3Spatrick 
OnLibraryLoaded(const char * name)383cab2bb3Spatrick void LibIgnore::OnLibraryLoaded(const char *name) {
39*810390e3Srobert   Lock lock(&mutex_);
403cab2bb3Spatrick   // Try to match suppressions with symlink target.
41d89ec533Spatrick   InternalMmapVector<char> buf(kMaxPathLength);
423cab2bb3Spatrick   if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 &&
433cab2bb3Spatrick       buf[0]) {
443cab2bb3Spatrick     for (uptr i = 0; i < count_; i++) {
453cab2bb3Spatrick       Lib *lib = &libs_[i];
463cab2bb3Spatrick       if (!lib->loaded && (!lib->real_name) &&
473cab2bb3Spatrick           TemplateMatch(lib->templ, name))
483cab2bb3Spatrick         lib->real_name = internal_strdup(buf.data());
493cab2bb3Spatrick     }
503cab2bb3Spatrick   }
513cab2bb3Spatrick 
523cab2bb3Spatrick   // Scan suppressions list and find newly loaded and unloaded libraries.
533cab2bb3Spatrick   ListOfModules modules;
543cab2bb3Spatrick   modules.init();
553cab2bb3Spatrick   for (uptr i = 0; i < count_; i++) {
563cab2bb3Spatrick     Lib *lib = &libs_[i];
573cab2bb3Spatrick     bool loaded = false;
583cab2bb3Spatrick     for (const auto &mod : modules) {
593cab2bb3Spatrick       for (const auto &range : mod.ranges()) {
603cab2bb3Spatrick         if (!range.executable)
613cab2bb3Spatrick           continue;
623cab2bb3Spatrick         if (!TemplateMatch(lib->templ, mod.full_name()) &&
633cab2bb3Spatrick             !(lib->real_name &&
643cab2bb3Spatrick             internal_strcmp(lib->real_name, mod.full_name()) == 0))
653cab2bb3Spatrick           continue;
663cab2bb3Spatrick         if (loaded) {
673cab2bb3Spatrick           Report("%s: called_from_lib suppression '%s' is matched against"
683cab2bb3Spatrick                  " 2 libraries: '%s' and '%s'\n",
693cab2bb3Spatrick                  SanitizerToolName, lib->templ, lib->name, mod.full_name());
703cab2bb3Spatrick           Die();
713cab2bb3Spatrick         }
723cab2bb3Spatrick         loaded = true;
733cab2bb3Spatrick         if (lib->loaded)
743cab2bb3Spatrick           continue;
753cab2bb3Spatrick         VReport(1,
763cab2bb3Spatrick                 "Matched called_from_lib suppression '%s' against library"
773cab2bb3Spatrick                 " '%s'\n",
783cab2bb3Spatrick                 lib->templ, mod.full_name());
793cab2bb3Spatrick         lib->loaded = true;
803cab2bb3Spatrick         lib->name = internal_strdup(mod.full_name());
813cab2bb3Spatrick         const uptr idx =
823cab2bb3Spatrick             atomic_load(&ignored_ranges_count_, memory_order_relaxed);
833cab2bb3Spatrick         CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
843cab2bb3Spatrick         ignored_code_ranges_[idx].begin = range.beg;
853cab2bb3Spatrick         ignored_code_ranges_[idx].end = range.end;
863cab2bb3Spatrick         atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
873cab2bb3Spatrick         break;
883cab2bb3Spatrick       }
893cab2bb3Spatrick     }
903cab2bb3Spatrick     if (lib->loaded && !loaded) {
913cab2bb3Spatrick       Report("%s: library '%s' that was matched against called_from_lib"
923cab2bb3Spatrick              " suppression '%s' is unloaded\n",
933cab2bb3Spatrick              SanitizerToolName, lib->name, lib->templ);
943cab2bb3Spatrick       Die();
953cab2bb3Spatrick     }
963cab2bb3Spatrick   }
973cab2bb3Spatrick 
983cab2bb3Spatrick   // Track instrumented ranges.
993cab2bb3Spatrick   if (track_instrumented_libs_) {
1003cab2bb3Spatrick     for (const auto &mod : modules) {
1013cab2bb3Spatrick       if (!mod.instrumented())
1023cab2bb3Spatrick         continue;
1033cab2bb3Spatrick       for (const auto &range : mod.ranges()) {
1043cab2bb3Spatrick         if (!range.executable)
1053cab2bb3Spatrick           continue;
1063cab2bb3Spatrick         if (IsPcInstrumented(range.beg) && IsPcInstrumented(range.end - 1))
1073cab2bb3Spatrick           continue;
108*810390e3Srobert         VReport(1, "Adding instrumented range 0x%zx-0x%zx from library '%s'\n",
1093cab2bb3Spatrick                 range.beg, range.end, mod.full_name());
1103cab2bb3Spatrick         const uptr idx =
1113cab2bb3Spatrick             atomic_load(&instrumented_ranges_count_, memory_order_relaxed);
1123cab2bb3Spatrick         CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_));
1133cab2bb3Spatrick         instrumented_code_ranges_[idx].begin = range.beg;
1143cab2bb3Spatrick         instrumented_code_ranges_[idx].end = range.end;
1153cab2bb3Spatrick         atomic_store(&instrumented_ranges_count_, idx + 1,
1163cab2bb3Spatrick                      memory_order_release);
1173cab2bb3Spatrick       }
1183cab2bb3Spatrick     }
1193cab2bb3Spatrick   }
1203cab2bb3Spatrick }
1213cab2bb3Spatrick 
OnLibraryUnloaded()1223cab2bb3Spatrick void LibIgnore::OnLibraryUnloaded() {
1233cab2bb3Spatrick   OnLibraryLoaded(nullptr);
1243cab2bb3Spatrick }
1253cab2bb3Spatrick 
1263cab2bb3Spatrick } // namespace __sanitizer
1273cab2bb3Spatrick 
128*810390e3Srobert #endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE ||
1293cab2bb3Spatrick         // SANITIZER_NETBSD
130