123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- //===-- sanitizer_libignore.cpp -------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "sanitizer_platform.h"
- #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
- SANITIZER_NETBSD
- #include "sanitizer_libignore.h"
- #include "sanitizer_flags.h"
- #include "sanitizer_posix.h"
- #include "sanitizer_procmaps.h"
- namespace __sanitizer {
- LibIgnore::LibIgnore(LinkerInitialized) {
- }
- void LibIgnore::AddIgnoredLibrary(const char *name_templ) {
- Lock lock(&mutex_);
- if (count_ >= kMaxLibs) {
- Report("%s: too many ignored libraries (max: %zu)\n", SanitizerToolName,
- kMaxLibs);
- Die();
- }
- Lib *lib = &libs_[count_++];
- lib->templ = internal_strdup(name_templ);
- lib->name = nullptr;
- lib->real_name = nullptr;
- lib->loaded = false;
- }
- void LibIgnore::OnLibraryLoaded(const char *name) {
- Lock lock(&mutex_);
- // Try to match suppressions with symlink target.
- InternalMmapVector<char> buf(kMaxPathLength);
- if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 &&
- buf[0]) {
- for (uptr i = 0; i < count_; i++) {
- Lib *lib = &libs_[i];
- if (!lib->loaded && (!lib->real_name) &&
- TemplateMatch(lib->templ, name))
- lib->real_name = internal_strdup(buf.data());
- }
- }
- // Scan suppressions list and find newly loaded and unloaded libraries.
- ListOfModules modules;
- modules.init();
- for (uptr i = 0; i < count_; i++) {
- Lib *lib = &libs_[i];
- bool loaded = false;
- for (const auto &mod : modules) {
- for (const auto &range : mod.ranges()) {
- if (!range.executable)
- continue;
- if (!TemplateMatch(lib->templ, mod.full_name()) &&
- !(lib->real_name &&
- internal_strcmp(lib->real_name, mod.full_name()) == 0))
- continue;
- if (loaded) {
- Report("%s: called_from_lib suppression '%s' is matched against"
- " 2 libraries: '%s' and '%s'\n",
- SanitizerToolName, lib->templ, lib->name, mod.full_name());
- Die();
- }
- loaded = true;
- if (lib->loaded)
- continue;
- VReport(1,
- "Matched called_from_lib suppression '%s' against library"
- " '%s'\n",
- lib->templ, mod.full_name());
- lib->loaded = true;
- lib->name = internal_strdup(mod.full_name());
- const uptr idx =
- atomic_load(&ignored_ranges_count_, memory_order_relaxed);
- CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));
- ignored_code_ranges_[idx].begin = range.beg;
- ignored_code_ranges_[idx].end = range.end;
- atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
- break;
- }
- }
- if (lib->loaded && !loaded) {
- Report("%s: library '%s' that was matched against called_from_lib"
- " suppression '%s' is unloaded\n",
- SanitizerToolName, lib->name, lib->templ);
- Die();
- }
- }
- // Track instrumented ranges.
- if (track_instrumented_libs_) {
- for (const auto &mod : modules) {
- if (!mod.instrumented())
- continue;
- for (const auto &range : mod.ranges()) {
- if (!range.executable)
- continue;
- if (IsPcInstrumented(range.beg) && IsPcInstrumented(range.end - 1))
- continue;
- VReport(1, "Adding instrumented range 0x%zx-0x%zx from library '%s'\n",
- range.beg, range.end, mod.full_name());
- const uptr idx =
- atomic_load(&instrumented_ranges_count_, memory_order_relaxed);
- CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_));
- instrumented_code_ranges_[idx].begin = range.beg;
- instrumented_code_ranges_[idx].end = range.end;
- atomic_store(&instrumented_ranges_count_, idx + 1,
- memory_order_release);
- }
- }
- }
- }
- void LibIgnore::OnLibraryUnloaded() {
- OnLibraryLoaded(nullptr);
- }
- } // namespace __sanitizer
- #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC ||
- // SANITIZER_NETBSD
|