Add top-level Clang flag -f(no-)sanitize-address-zero-base-shadow that makes AddressSanitizer use bottom of the address space for the shadow memory. On Linux it can be used with -fPIE/-pie to improve performance.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172974 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 2d8b17f..01e1623 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -392,6 +392,12 @@
"address (memory errors) | thread (race detection) | "
"undefined (miscellaneous undefined behavior)">;
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>;
+def fsanitize_address_zero_base_shadow : Flag<["-"], "fsanitize-address-zero-base-shadow">,
+ Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Make AddressSanitizer map shadow memory"
+ "at zero offset">;
+def fno_sanitize_address_zero_base_shadow : Flag<["-"], "fno-sanitize-address-zero-base-shadow">,
+ Group<f_clang_Group>;
def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Path to blacklist file for sanitizers">;
@@ -402,8 +408,7 @@
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Enable origins tracking in MemorySanitizer">;
def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
- Group<f_clang_Group>,
- HelpText<"Disable origins tracking in MemorySanitizer">;
+ Group<f_clang_Group>;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">,
Group<f_clang_Group>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 5e87dab..64eff9c 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -61,8 +61,6 @@
CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to
///< be generated.
-CODEGENOPT(MemorySanitizerTrackOrigins , 1, 0) ///< Enable tracking origins in
- ///< MemorySanitizer
CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
CODEGENOPT(NoDwarf2CFIAsm , 1, 0) ///< Set when -fno-dwarf2-cfi-asm is enabled.
@@ -85,6 +83,10 @@
CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions.
CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
+CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
+ ///< offset in AddressSanitizer.
+CODEGENOPT(SanitizeMemoryTrackOrigins, 1, 0) ///< Enable tracking origins in
+ ///< MemorySanitizer
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 8a3ee39..b938aac 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -164,12 +164,16 @@
static_cast<const PassManagerBuilderWrapper&>(Builder);
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
- PM.add(createAddressSanitizerFunctionPass(LangOpts.Sanitize.InitOrder,
- LangOpts.Sanitize.UseAfterReturn,
- LangOpts.Sanitize.UseAfterScope,
- CGOpts.SanitizerBlacklistFile));
- PM.add(createAddressSanitizerModulePass(LangOpts.Sanitize.InitOrder,
- CGOpts.SanitizerBlacklistFile));
+ PM.add(createAddressSanitizerFunctionPass(
+ LangOpts.Sanitize.InitOrder,
+ LangOpts.Sanitize.UseAfterReturn,
+ LangOpts.Sanitize.UseAfterScope,
+ CGOpts.SanitizerBlacklistFile,
+ CGOpts.SanitizeAddressZeroBaseShadow));
+ PM.add(createAddressSanitizerModulePass(
+ LangOpts.Sanitize.InitOrder,
+ CGOpts.SanitizerBlacklistFile,
+ CGOpts.SanitizeAddressZeroBaseShadow));
}
static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
@@ -177,7 +181,7 @@
const PassManagerBuilderWrapper &BuilderWrapper =
static_cast<const PassManagerBuilderWrapper&>(Builder);
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
- PM.add(createMemorySanitizerPass(CGOpts.MemorySanitizerTrackOrigins,
+ PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins,
CGOpts.SanitizerBlacklistFile));
}
diff --git a/lib/Driver/SanitizerArgs.h b/lib/Driver/SanitizerArgs.h
index 0955889..ea89904 100644
--- a/lib/Driver/SanitizerArgs.h
+++ b/lib/Driver/SanitizerArgs.h
@@ -41,9 +41,11 @@
unsigned Kind;
std::string BlacklistFile;
bool MsanTrackOrigins;
+ bool AsanZeroBaseShadow;
public:
- SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false) {}
+ SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
+ AsanZeroBaseShadow(false) {}
/// Parses the sanitizer arguments from an argument list.
SanitizerArgs(const Driver &D, const ArgList &Args);
@@ -72,6 +74,10 @@
if (MsanTrackOrigins)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
+
+ if (AsanZeroBaseShadow)
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fsanitize-address-zero-base-shadow"));
}
private:
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 3132e75..0cc9ea2 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1444,7 +1444,8 @@
}
SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args)
- : Kind(0), BlacklistFile(""), MsanTrackOrigins(false) {
+ : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
+ AsanZeroBaseShadow(false) {
for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
unsigned Add, Remove;
@@ -1493,11 +1494,18 @@
}
// Parse -f(no-)sanitize-memory-track-origins options.
- if (Kind & Memory)
+ if (NeedsMsan)
MsanTrackOrigins =
Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
options::OPT_fno_sanitize_memory_track_origins,
/* Default */false);
+
+ // Parse -f(no-)sanitize-address-zero-base-shadow options.
+ if (NeedsAsan)
+ AsanZeroBaseShadow =
+ Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
+ options::OPT_fno_sanitize_address_zero_base_shadow,
+ /* Default */false);
}
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
@@ -1517,6 +1525,13 @@
CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
} else {
if (!Args.hasArg(options::OPT_shared)) {
+ bool ZeroBaseShadow = Args.hasFlag(
+ options::OPT_fsanitize_address_zero_base_shadow,
+ options::OPT_fno_sanitize_address_zero_base_shadow, false);
+ if (ZeroBaseShadow && !Args.hasArg(options::OPT_pie)) {
+ TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
+ "-fsanitize-address-zero-base-shadow" << "-pie";
+ }
// LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
// resource directory.
SmallString<128> LibAsan(TC.getDriver().ResourceDir);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 9329b3b..a16b822 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -404,8 +404,10 @@
Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
- Opts.MemorySanitizerTrackOrigins =
+ Opts.SanitizeMemoryTrackOrigins =
Args.hasArg(OPT_fsanitize_memory_track_origins);
+ Opts.SanitizeAddressZeroBaseShadow =
+ Args.hasArg(OPT_fsanitize_address_zero_base_shadow);
Opts.SSPBufferSize =
Args.getLastArgIntValue(OPT_stack_protector_buffer_size, 8, Diags);
Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 857ae32..a4c8700 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -39,6 +39,9 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-EXTRA-TRACK-ORIGINS
// CHECK-NO-EXTRA-TRACK-ORIGINS-NOT: "-fsanitize-memory-track-origins"
+// RUN: %clang -target x86_64-linux-gnu -fsanitize-address-zero-base-shadow -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-ASAN-ZERO-BASE-SHADOW
+// CHECK-ONLY-ASAN-ZERO-BASE-SHADOW: warning: argument unused during compilation: '-fsanitize-address-zero-base-shadow'
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize=alignment -fsanitize=vptr -fno-sanitize=vptr %s -### 2>&1
// OK
@@ -51,6 +54,9 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr -fno-sanitize=vptr -fsanitize=undefined,address %s -### 2>&1
// OK
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -pie %s -### 2>&1
+// OK
+
// RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fthread-sanitizer -fno-thread-sanitizer -faddress-sanitizer -fno-address-sanitizer -fbounds-checking -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-DEPRECATED
// CHECK-DEPRECATED: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined' instead
// CHECK-DEPRECATED: argument '-fthread-sanitizer' is deprecated, use '-fsanitize=thread' instead
@@ -65,6 +71,12 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NO-PIE
// CHECK-MSAN-NO-PIE: invalid argument '-fsanitize=memory' only allowed with '-pie'
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE
+// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: invalid argument '-fsanitize-address-zero-base-shadow' only allowed with '-pie'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL
+// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: '-fsanitize-address-zero-base-shadow' only allowed with '-pie'
+
// RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-PIE
// CHECK-ANDROID-ASAN-NO-PIE: AddressSanitizer on Android requires '-pie'