1*0fca6ea1SDimitry Andric //===-- nsan_suppressions.cc ----------------------------------------------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #include "nsan_suppressions.h" 10*0fca6ea1SDimitry Andric #include "nsan_flags.h" 11*0fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_placement_new.h" 12*0fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_stacktrace.h" 13*0fca6ea1SDimitry Andric #include "sanitizer_common/sanitizer_symbolizer.h" 14*0fca6ea1SDimitry Andric 15*0fca6ea1SDimitry Andric using namespace __sanitizer; 16*0fca6ea1SDimitry Andric using namespace __nsan; 17*0fca6ea1SDimitry Andric 18*0fca6ea1SDimitry Andric SANITIZER_INTERFACE_WEAK_DEF(const char *, __nsan_default_suppressions, void) { 19*0fca6ea1SDimitry Andric return 0; 20*0fca6ea1SDimitry Andric } 21*0fca6ea1SDimitry Andric 22*0fca6ea1SDimitry Andric const char kSuppressionFcmp[] = "fcmp"; 23*0fca6ea1SDimitry Andric const char kSuppressionConsistency[] = "consistency"; 24*0fca6ea1SDimitry Andric 25*0fca6ea1SDimitry Andric alignas(64) static char suppression_placeholder[sizeof(SuppressionContext)]; 26*0fca6ea1SDimitry Andric static SuppressionContext *suppression_ctx; 27*0fca6ea1SDimitry Andric 28*0fca6ea1SDimitry Andric // The order should match the enum CheckKind. 29*0fca6ea1SDimitry Andric static const char *kSuppressionTypes[] = {kSuppressionFcmp, 30*0fca6ea1SDimitry Andric kSuppressionConsistency}; 31*0fca6ea1SDimitry Andric 32*0fca6ea1SDimitry Andric void __nsan::InitializeSuppressions() { 33*0fca6ea1SDimitry Andric CHECK_EQ(nullptr, suppression_ctx); 34*0fca6ea1SDimitry Andric suppression_ctx = new (suppression_placeholder) 35*0fca6ea1SDimitry Andric SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); 36*0fca6ea1SDimitry Andric suppression_ctx->ParseFromFile(flags().suppressions); 37*0fca6ea1SDimitry Andric suppression_ctx->Parse(__nsan_default_suppressions()); 38*0fca6ea1SDimitry Andric } 39*0fca6ea1SDimitry Andric 40*0fca6ea1SDimitry Andric static Suppression *GetSuppressionForAddr(uptr addr, const char *suppr_type) { 41*0fca6ea1SDimitry Andric Suppression *s = nullptr; 42*0fca6ea1SDimitry Andric 43*0fca6ea1SDimitry Andric // Suppress by module name. 44*0fca6ea1SDimitry Andric SuppressionContext *suppressions = suppression_ctx; 45*0fca6ea1SDimitry Andric if (const char *moduleName = 46*0fca6ea1SDimitry Andric Symbolizer::GetOrInit()->GetModuleNameForPc(addr)) { 47*0fca6ea1SDimitry Andric if (suppressions->Match(moduleName, suppr_type, &s)) 48*0fca6ea1SDimitry Andric return s; 49*0fca6ea1SDimitry Andric } 50*0fca6ea1SDimitry Andric 51*0fca6ea1SDimitry Andric // Suppress by file or function name. 52*0fca6ea1SDimitry Andric SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr); 53*0fca6ea1SDimitry Andric for (SymbolizedStack *cur = frames; cur; cur = cur->next) { 54*0fca6ea1SDimitry Andric if (suppressions->Match(cur->info.function, suppr_type, &s) || 55*0fca6ea1SDimitry Andric suppressions->Match(cur->info.file, suppr_type, &s)) { 56*0fca6ea1SDimitry Andric break; 57*0fca6ea1SDimitry Andric } 58*0fca6ea1SDimitry Andric } 59*0fca6ea1SDimitry Andric frames->ClearAll(); 60*0fca6ea1SDimitry Andric return s; 61*0fca6ea1SDimitry Andric } 62*0fca6ea1SDimitry Andric 63*0fca6ea1SDimitry Andric Suppression *__nsan::GetSuppressionForStack(const StackTrace *stack, 64*0fca6ea1SDimitry Andric CheckKind k) { 65*0fca6ea1SDimitry Andric for (uptr i = 0, e = stack->size; i < e; i++) { 66*0fca6ea1SDimitry Andric Suppression *s = GetSuppressionForAddr( 67*0fca6ea1SDimitry Andric StackTrace::GetPreviousInstructionPc(stack->trace[i]), 68*0fca6ea1SDimitry Andric kSuppressionTypes[static_cast<int>(k)]); 69*0fca6ea1SDimitry Andric if (s) 70*0fca6ea1SDimitry Andric return s; 71*0fca6ea1SDimitry Andric } 72*0fca6ea1SDimitry Andric return nullptr; 73*0fca6ea1SDimitry Andric } 74