r360707 - [NewPM] Port HWASan and Kernel HWASan

Leonard Chan via cfe-commits cfe-commits at lists.llvm.org
Tue May 14 14:17:22 PDT 2019


Author: leonardchan
Date: Tue May 14 14:17:21 2019
New Revision: 360707

URL: http://llvm.org/viewvc/llvm-project?rev=360707&view=rev
Log:
[NewPM] Port HWASan and Kernel HWASan

Port hardware assisted address sanitizer to new PM following the same guidelines as msan and tsan.

Changes:
- Separate HWAddressSanitizer into a pass class and a sanitizer class.
- Create new PM wrapper pass for the sanitizer class.
- Use the getOrINsert pattern for some module level initialization declarations.
- Also enable kernel-kwasan in new PM
- Update llvm tests and add clang test.

Differential Revision: https://reviews.llvm.org/D61709

Added:
    cfe/trunk/test/CodeGen/hwasan-new-pm.c
Modified:
    cfe/trunk/lib/CodeGen/BackendUtil.cpp

Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=360707&r1=360706&r2=360707&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Tue May 14 14:17:21 2019
@@ -57,6 +57,7 @@
 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/BoundsChecking.h"
 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
+#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
@@ -265,12 +266,13 @@ static void addHWAddressSanitizerPasses(
       static_cast<const PassManagerBuilderWrapper &>(Builder);
   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
   bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
-  PM.add(createHWAddressSanitizerPass(/*CompileKernel*/ false, Recover));
+  PM.add(
+      createHWAddressSanitizerLegacyPassPass(/*CompileKernel*/ false, Recover));
 }
 
 static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
                                             legacy::PassManagerBase &PM) {
-  PM.add(createHWAddressSanitizerPass(
+  PM.add(createHWAddressSanitizerLegacyPassPass(
       /*CompileKernel*/ true, /*Recover*/ true));
 }
 
@@ -962,6 +964,17 @@ static void addSanitizersAtO0(ModulePass
   if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
     MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
   }
+
+  if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) {
+    bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
+    MPM.addPass(createModuleToFunctionPassAdaptor(
+        HWAddressSanitizerPass(/*CompileKernel=*/false, Recover)));
+  }
+
+  if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) {
+    MPM.addPass(createModuleToFunctionPassAdaptor(
+        HWAddressSanitizerPass(/*CompileKernel=*/true, /*Recover=*/true)));
+  }
 }
 
 /// A clean version of `EmitAssembly` that uses the new pass manager.
@@ -1145,6 +1158,23 @@ void EmitAssemblyHelper::EmitAssemblyWit
                   UseOdrIndicator));
             });
       }
+      if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) {
+        bool Recover =
+            CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
+        PB.registerOptimizerLastEPCallback(
+            [Recover](FunctionPassManager &FPM,
+                      PassBuilder::OptimizationLevel Level) {
+              FPM.addPass(HWAddressSanitizerPass(
+                  /*CompileKernel=*/false, Recover));
+            });
+      }
+      if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) {
+        PB.registerOptimizerLastEPCallback(
+            [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
+              FPM.addPass(HWAddressSanitizerPass(
+                  /*CompileKernel=*/true, /*Recover=*/true));
+            });
+      }
       if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts))
         PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) {
           MPM.addPass(GCOVProfilerPass(*Options));

Added: cfe/trunk/test/CodeGen/hwasan-new-pm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/hwasan-new-pm.c?rev=360707&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/hwasan-new-pm.c (added)
+++ cfe/trunk/test/CodeGen/hwasan-new-pm.c Tue May 14 14:17:21 2019
@@ -0,0 +1,34 @@
+// Test that HWASan and KHWASan runs with the new pass manager.
+// We run them under different optimizations and LTOs to ensure the IR is still
+// being instrumented properly.
+
+// RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=hwaddress %s | FileCheck %s --check-prefixes=CHECK,HWASAN,HWASAN-NOOPT
+// RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=hwaddress -flto %s | FileCheck %s --check-prefixes=CHECK,HWASAN,HWASAN-NOOPT
+// RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=hwaddress -flto=thin %s | FileCheck %s --check-prefixes=CHECK,HWASAN,HWASAN-NOOPT
+// RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=hwaddress %s | FileCheck %s --check-prefixes=CHECK,HWASAN
+// RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=hwaddress -flto %s | FileCheck %s --check-prefixes=CHECK,HWASAN
+// RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=hwaddress -flto=thin %s | FileCheck %s
+
+// RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=kernel-hwaddress %s | FileCheck %s --check-prefixes=CHECK,KHWASAN,KHWASAN-NOOPT
+// RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=kernel-hwaddress -flto %s | FileCheck %s --check-prefixes=CHECK,KHWASAN,KHWASAN-NOOPT
+// RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=kernel-hwaddress -flto=thin %s | FileCheck %s --check-prefixes=CHECK,KHWASAN,KHWASAN-NOOPT
+// RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=kernel-hwaddress %s | FileCheck %s --check-prefixes=CHECK,KHWASAN
+// RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=kernel-hwaddress -flto %s | FileCheck %s --check-prefixes=CHECK,KHWASAN
+// RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=kernel-hwaddress -flto=thin %s | FileCheck %s
+
+int foo(int *a) { return *a; }
+
+// All the cases above mark the function with sanitize_hwaddress.
+// CHECK-DAG: sanitize_hwaddress
+
+// Both sanitizers produce %hwasan.shadow without both thinlto and optimizations.
+// HWASAN-DAG: %hwasan.shadow
+// KHWASAN-DAG: %hwasan.shadow
+
+// Both sanitizers produce __hwasan_tls without both thinlto and optimizations.
+// HWASAN-DAG: __hwasan_tls
+// KHWASAN-DAG: __hwasan_tls
+
+// For unoptimized cases, both sanitizers produce different load functions.
+// HWASAN-NOOPT-DAG: __hwasan_loadN
+// KHWASAN-NOOPT-DAG: __hwasan_loadN_noabort




More information about the cfe-commits mailing list