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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits