This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG5d64dd8e3c22: [Clang][ASan] Introduce `-fsanitize-address-destructor-kind=` driver & frontend… (authored by delcypher).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D96572/new/ https://reviews.llvm.org/D96572 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/Sanitizers.h clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/Basic/Sanitizers.cpp clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/asan-destructor-kind.cpp clang/test/Driver/fsanitize-address-destructor-kind.c
Index: clang/test/Driver/fsanitize-address-destructor-kind.c =================================================================== --- /dev/null +++ clang/test/Driver/fsanitize-address-destructor-kind.c @@ -0,0 +1,20 @@ +// Option should not be passed to the frontend by default. +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address %s \ +// RUN: -### 2>&1 | \ +// RUN: FileCheck %s +// CHECK-NOT: -fsanitize-address-destructor-kind + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=none %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-NONE-ARG %s +// CHECK-NONE-ARG: "-fsanitize-address-destructor-kind=none" + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=global %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-GLOBAL-ARG %s +// CHECK-GLOBAL-ARG: "-fsanitize-address-destructor-kind=global" + +// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=bad_arg %s -### 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-INVALID-ARG %s +// CHECK-INVALID-ARG: error: unsupported argument 'bad_arg' to option 'fsanitize-address-destructor-kind=' Index: clang/test/CodeGen/asan-destructor-kind.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/asan-destructor-kind.cpp @@ -0,0 +1,49 @@ +// Frontend rejects invalid option +// RUN: not %clang_cc1 -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=bad_arg -emit-llvm -o - \ +// RUN: -triple x86_64-apple-macosx10.15 %s 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=CHECK-BAD-ARG +// CHECK-BAD-ARG: unsupported argument 'bad_arg' to option 'fsanitize-address-destructor-kind=' + +// Default is global dtor +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-apple-macosx10.15 \ +// RUN: -fno-legacy-pass-manager %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-GLOBAL-DTOR +// +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-apple-macosx10.15 \ +// RUN: -flegacy-pass-manager %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-GLOBAL-DTOR + +// Explictly ask for global dtor +// RUN: %clang_cc1 -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=global -emit-llvm -o - \ +// RUN: -triple x86_64-apple-macosx10.15 -fno-legacy-pass-manager %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK-GLOBAL-DTOR +// +// RUN: %clang_cc1 -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=global -emit-llvm -o - \ +// RUN: -triple x86_64-apple-macosx10.15 -flegacy-pass-manager %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK-GLOBAL-DTOR + +// CHECK-GLOBAL-DTOR: llvm.global_dtor{{.+}}asan.module_dtor +// CHECK-GLOBAL-DTOR: define internal void @asan.module_dtor + +// Explictly ask for no dtors +// RUN: %clang_cc1 -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=none -emit-llvm -o - \ +// RUN: -triple x86_64-apple-macosx10.15 -fno-legacy-pass-manager %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK-NONE-DTOR +// +// RUN: %clang_cc1 -fsanitize=address \ +// RUN: -fsanitize-address-destructor-kind=none -emit-llvm -o - \ +// RUN: -triple x86_64-apple-macosx10.15 -flegacy-pass-manager %s | \ +// RUN: FileCheck %s --check-prefixes=CHECK-NONE-DTOR + +int global; + +int main() { + return global; +} + +// CHECK-NONE-DTOR-NOT: llvm.global_dtor{{.+}}asan.module_dtor +// CHECK-NONE-DTOR-NOT: define internal void @asan.module_dtor Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1937,6 +1937,19 @@ Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); + if (LangOptsRef.Sanitize.has(SanitizerKind::Address)) { + if (Arg *A = + Args.getLastArg(options::OPT_sanitize_address_destructor_kind_EQ)) { + auto destructorKind = AsanDtorKindFromString(A->getValue()); + if (destructorKind == llvm::AsanDtorKind::Invalid) { + Diags.Report(clang::diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << A->getValue(); + } else { + Opts.setSanitizeAddressDtorKind(destructorKind); + } + } + } + if (Args.hasArg(options::OPT_ffinite_loops)) Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always; else if (Args.hasArg(options::OPT_fno_finite_loops)) Index: clang/lib/Driver/SanitizerArgs.cpp =================================================================== --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -825,6 +825,16 @@ AsanInvalidPointerSub = true; } + if (const auto *Arg = + Args.getLastArg(options::OPT_sanitize_address_destructor_kind_EQ)) { + auto parsedAsanDtorKind = AsanDtorKindFromString(Arg->getValue()); + if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid) { + TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument) + << Arg->getOption().getName() << Arg->getValue(); + } + AsanDtorKind = parsedAsanDtorKind; + } + } else { AsanUseAfterScope = false; // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address. @@ -1079,6 +1089,13 @@ CmdArgs.push_back("-asan-detect-invalid-pointer-sub"); } + // Only pass the option to the frontend if the user requested, + // otherwise the frontend will just use the codegen default. + if (AsanDtorKind != llvm::AsanDtorKind::Invalid) { + CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-destructor-kind=" + + AsanDtorKindToString(AsanDtorKind))); + } + if (!HwasanAbi.empty()) { CmdArgs.push_back("-default-function-attr"); CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi)); Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -287,10 +287,12 @@ bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope; bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator; bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); + llvm::AsanDtorKind DestructorKind = CGOpts.getSanitizeAddressDtorKind(); PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover, UseAfterScope)); PM.add(createModuleAddressSanitizerLegacyPassPass( - /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator)); + /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator, + DestructorKind)); } static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, @@ -1111,9 +1113,12 @@ bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope; bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; + llvm::AsanDtorKind DestructorKind = + CodeGenOpts.getSanitizeAddressDtorKind(); MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); MPM.addPass(ModuleAddressSanitizerPass( - CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator)); + CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator, + DestructorKind)); MPM.addPass(createModuleToFunctionPassAdaptor( AddressSanitizerPass(CompileKernel, Recover, UseAfterScope))); } Index: clang/lib/Basic/Sanitizers.cpp =================================================================== --- clang/lib/Basic/Sanitizers.cpp +++ clang/lib/Basic/Sanitizers.cpp @@ -60,4 +60,23 @@ llvm::hash_code hash_value(const clang::SanitizerMask &Arg) { return Arg.hash_value(); } + +StringRef AsanDtorKindToString(llvm::AsanDtorKind kind) { + switch (kind) { + case llvm::AsanDtorKind::None: + return "none"; + case llvm::AsanDtorKind::Global: + return "global"; + case llvm::AsanDtorKind::Invalid: + return "invalid"; + } +} + +llvm::AsanDtorKind AsanDtorKindFromString(StringRef kindStr) { + return llvm::StringSwitch<llvm::AsanDtorKind>(kindStr) + .Case("none", llvm::AsanDtorKind::None) + .Case("global", llvm::AsanDtorKind::Global) + .Default(llvm::AsanDtorKind::Invalid); +} + } // namespace clang Index: clang/include/clang/Driver/SanitizerArgs.h =================================================================== --- clang/include/clang/Driver/SanitizerArgs.h +++ clang/include/clang/Driver/SanitizerArgs.h @@ -43,6 +43,7 @@ bool AsanUseOdrIndicator = false; bool AsanInvalidPointerCmp = false; bool AsanInvalidPointerSub = false; + llvm::AsanDtorKind AsanDtorKind = llvm::AsanDtorKind::Invalid; std::string HwasanAbi; bool LinkRuntimes = true; bool LinkCXXRuntimes = false; Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1500,6 +1500,11 @@ " reports in partially sanitized programs at the cost of an increase in binary size">, NegFlag<SetFalse, [], "Disable ODR indicator globals">>, Group<f_clang_Group>; +def sanitize_address_destructor_kind_EQ : Joined<["-"], "fsanitize-address-destructor-kind=">, + MetaVarName<"<kind>">, + Flags<[CC1Option]>, + HelpText<"Set destructor type used in ASan instrumentation">, + Group<f_clang_Group>; // Note: This flag was introduced when it was necessary to distinguish between // ABI for correct codegen. This is no longer needed, but the flag is // not removed since targeting either ABI will behave the same. Index: clang/include/clang/Basic/Sanitizers.h =================================================================== --- clang/include/clang/Basic/Sanitizers.h +++ clang/include/clang/Basic/Sanitizers.h @@ -17,6 +17,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include <cassert> #include <cstdint> @@ -193,6 +194,10 @@ SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero; } +StringRef AsanDtorKindToString(llvm::AsanDtorKind kind); + +llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind); + } // namespace clang #endif // LLVM_CLANG_BASIC_SANITIZERS_H Index: clang/include/clang/Basic/CodeGenOptions.h =================================================================== --- clang/include/clang/Basic/CodeGenOptions.h +++ clang/include/clang/Basic/CodeGenOptions.h @@ -20,6 +20,7 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/Regex.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h" #include <map> #include <memory> #include <string> Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -214,6 +214,9 @@ CODEGENOPT(SanitizeAddressUseOdrIndicator, 1, 0) ///< Enable ODR indicator globals CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer +ENUM_CODEGENOPT(SanitizeAddressDtorKind, llvm::AsanDtorKind, 2, + llvm::AsanDtorKind::Global) ///< Set how ASan global + ///< destructors are emitted. CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection ///< in MemorySanitizer CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI. Index: clang/docs/ClangCommandLineReference.rst =================================================================== --- clang/docs/ClangCommandLineReference.rst +++ clang/docs/ClangCommandLineReference.rst @@ -870,6 +870,17 @@ Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size +.. option:: -fsanitize-address-destructor-kind=<arg> + +Set the kind of module destructors emitted by AddressSanitizer instrumentation. +These destructors are emitted to unregister instrumented global variables when +code is unloaded (e.g. via `dlclose()`). + +Valid options are: + +* ``global`` - Emit module destructors that are called via a platform specific array (see `llvm.global_dtors`). +* ``none`` - Do not emit module destructors. + .. option:: -fsanitize-blacklist=<arg> Path to blacklist file for sanitizers
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits