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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits