//===-- nsan_suppressions.cc ----------------------------------------------===// // // 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 "nsan_suppressions.h" #include "nsan_flags.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" using namespace __sanitizer; using namespace __nsan; SANITIZER_INTERFACE_WEAK_DEF(const char *, __nsan_default_suppressions, void) { return 0; } const char kSuppressionFcmp[] = "fcmp"; const char kSuppressionConsistency[] = "consistency"; alignas(64) static char suppression_placeholder[sizeof(SuppressionContext)]; static SuppressionContext *suppression_ctx; // The order should match the enum CheckKind. static const char *kSuppressionTypes[] = {kSuppressionFcmp, kSuppressionConsistency}; void __nsan::InitializeSuppressions() { CHECK_EQ(nullptr, suppression_ctx); suppression_ctx = new (suppression_placeholder) SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); suppression_ctx->ParseFromFile(flags().suppressions); suppression_ctx->Parse(__nsan_default_suppressions()); } static Suppression *GetSuppressionForAddr(uptr addr, const char *suppr_type) { Suppression *s = nullptr; // Suppress by module name. SuppressionContext *suppressions = suppression_ctx; if (const char *moduleName = Symbolizer::GetOrInit()->GetModuleNameForPc(addr)) { if (suppressions->Match(moduleName, suppr_type, &s)) return s; } // Suppress by file or function name. SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr); for (SymbolizedStack *cur = frames; cur; cur = cur->next) { if (suppressions->Match(cur->info.function, suppr_type, &s) || suppressions->Match(cur->info.file, suppr_type, &s)) { break; } } frames->ClearAll(); return s; } Suppression *__nsan::GetSuppressionForStack(const StackTrace *stack, CheckKind k) { for (uptr i = 0, e = stack->size; i < e; i++) { Suppression *s = GetSuppressionForAddr( StackTrace::GetPreviousInstructionPc(stack->trace[i]), kSuppressionTypes[static_cast(k)]); if (s) return s; } return nullptr; }