brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 271c92e Raw
132 lines · cpp
1//===-- sanitizer_libignore.cpp -------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "sanitizer_platform.h"10 11#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \12    SANITIZER_NETBSD13 14#include "sanitizer_libignore.h"15#include "sanitizer_flags.h"16#include "sanitizer_posix.h"17#include "sanitizer_procmaps.h"18 19namespace __sanitizer {20 21LibIgnore::LibIgnore(LinkerInitialized) {22}23 24void LibIgnore::AddIgnoredLibrary(const char *name_templ) {25  Lock lock(&mutex_);26  if (count_ >= kMaxLibs) {27    Report("%s: too many ignored libraries (max: %zu)\n", SanitizerToolName,28           kMaxLibs);29    Die();30  }31  Lib *lib = &libs_[count_++];32  lib->templ = internal_strdup(name_templ);33  lib->name = nullptr;34  lib->real_name = nullptr;35  lib->range_id = kInvalidCodeRangeId;36}37 38void LibIgnore::OnLibraryLoaded(const char *name) {39  Lock lock(&mutex_);40  // Try to match suppressions with symlink target.41  InternalMmapVector<char> buf(kMaxPathLength);42  if (name && internal_readlink(name, buf.data(), buf.size() - 1) > 0 &&43      buf[0]) {44    for (uptr i = 0; i < count_; i++) {45      Lib *lib = &libs_[i];46      if (!lib->loaded() && (!lib->real_name) &&47          TemplateMatch(lib->templ, name))48        lib->real_name = internal_strdup(buf.data());49    }50  }51 52  // Scan suppressions list and find newly loaded and unloaded libraries.53  ListOfModules modules;54  modules.init();55  for (uptr i = 0; i < count_; i++) {56    Lib *lib = &libs_[i];57    bool loaded = false;58    for (const auto &mod : modules) {59      for (const auto &range : mod.ranges()) {60        if (!range.executable)61          continue;62        if (!TemplateMatch(lib->templ, mod.full_name()) &&63            !(lib->real_name &&64            internal_strcmp(lib->real_name, mod.full_name()) == 0))65          continue;66        if (loaded) {67          Report("%s: called_from_lib suppression '%s' is matched against"68                 " 2 libraries: '%s' and '%s'\n",69                 SanitizerToolName, lib->templ, lib->name, mod.full_name());70          Die();71        }72        loaded = true;73        if (lib->loaded())74          continue;75        VReport(1,76                "Matched called_from_lib suppression '%s' against library"77                " '%s'\n",78                lib->templ, mod.full_name());79        lib->name = internal_strdup(mod.full_name());80        const uptr idx =81            atomic_load(&ignored_ranges_count_, memory_order_relaxed);82        CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_));83        ignored_code_ranges_[idx].OnLoad(range.beg, range.end);84        // Record the index of the ignored range.85        lib->range_id = idx;86        atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);87        break;88      }89    }90    if (lib->loaded() && !loaded) {91      VReport(1,92              "%s: library '%s' that was matched against called_from_lib"93              " suppression '%s' is unloaded\n",94              SanitizerToolName, lib->name, lib->templ);95      // The library is unloaded so mark the ignored code range as unloaded.96      ignored_code_ranges_[lib->range_id].OnUnload();97      lib->range_id = kInvalidCodeRangeId;98    }99  }100 101  // Track instrumented ranges.102  if (track_instrumented_libs_) {103    for (const auto &mod : modules) {104      if (!mod.instrumented())105        continue;106      for (const auto &range : mod.ranges()) {107        if (!range.executable)108          continue;109        if (IsPcInstrumented(range.beg) && IsPcInstrumented(range.end - 1))110          continue;111        VReport(1, "Adding instrumented range %p-%p from library '%s'\n",112                (void *)range.beg, (void *)range.end, mod.full_name());113        const uptr idx =114            atomic_load(&instrumented_ranges_count_, memory_order_relaxed);115        CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_));116        instrumented_code_ranges_[idx].OnLoad(range.beg, range.end);117        atomic_store(&instrumented_ranges_count_, idx + 1,118                     memory_order_release);119      }120    }121  }122}123 124void LibIgnore::OnLibraryUnloaded() {125  OnLibraryLoaded(nullptr);126}127 128} // namespace __sanitizer129 130#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE ||131        // SANITIZER_NETBSD132