aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/nsan/nsan_suppressions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/nsan/nsan_suppressions.cpp')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/nsan/nsan_suppressions.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/nsan/nsan_suppressions.cpp b/contrib/llvm-project/compiler-rt/lib/nsan/nsan_suppressions.cpp
new file mode 100644
index 000000000000..c4d438e090e0
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/nsan/nsan_suppressions.cpp
@@ -0,0 +1,73 @@
+//===-- 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<int>(k)]);
+ if (s)
+ return s;
+ }
+ return nullptr;
+}