[cfe-commits] [PATCH] ASan: support for zero-based shadow for PIE binaries (Clang part).

Alexey Samsonov samsonov at google.com
Wed Jan 16 08:15:21 PST 2013


Hi rsmith, kcc,

This change adds top-level Clang flag -f(no-)sanitize-address-assume-pie,
which specifies that sources will be linked with PIE, and thus AddressSanitizer
may use different shadow mapping to improve performance. Naming the flag is hard,
but I've chosen current variant instead of smth like -fsanitize-address-zero-based-shadow,
as this flag is top-level and user-visible, so it's good if it's understandable.
If there is a case when -pie doesn't give us the desired properties
(available memory at the bottom of address space), we'd have to deal with this in
backend. Thoughts?

http://llvm-reviews.chandlerc.com/D303

Files:
  include/clang/Frontend/CodeGenOptions.def
  include/clang/Driver/Options.td
  lib/Driver/SanitizerArgs.h
  lib/Driver/Tools.cpp
  lib/CodeGen/BackendUtil.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/Driver/fsanitize.c

Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ 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(SanitizeAddressAssumePie   , 1, 0) ///< Let AddressSanitizer assume
+                                              ///< code is built with PIE.
+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.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ 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_assume_pie : Flag<["-"], "fsanitize-address-assume-pie">,
+                                   Group<f_clang_Group>, Flags<[CC1Option]>,
+                                   HelpText<"Assume that code is built with PIE in AddressSanitizer">;
+def fno_sanitize_address_assume_pie : Flag<["-"], "fno-sanitize-address-assume-pie">,
+                                      Group<f_clang_Group>,
+                                      HelpText<"Don't assume that code is built with PIE in AddressSanitizer">;
 def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
                           Group<f_clang_Group>, Flags<[CC1Option]>,
                           HelpText<"Path to blacklist file for sanitizers">;
Index: lib/Driver/SanitizerArgs.h
===================================================================
--- lib/Driver/SanitizerArgs.h
+++ lib/Driver/SanitizerArgs.h
@@ -41,9 +41,11 @@
   unsigned Kind;
   std::string BlacklistFile;
   bool MsanTrackOrigins;
+  bool AsanAssumePie;
 
  public:
-  SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false) {}
+  SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
+                    AsanAssumePie(false) {}
   /// Parses the sanitizer arguments from an argument list.
   SanitizerArgs(const Driver &D, const ArgList &Args);
 
@@ -72,6 +74,9 @@
 
     if (MsanTrackOrigins)
       CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
+
+    if (AsanAssumePie)
+      CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-assume-pie"));
   }
 
  private:
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1443,7 +1443,8 @@
 }
 
 SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args)
-    : Kind(0), BlacklistFile(""), MsanTrackOrigins(false) {
+    : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
+      AsanAssumePie(false) {
 
   for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
     unsigned Add, Remove;
@@ -1492,11 +1493,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-assume-pie options.
+  if (NeedsAsan)
+    AsanAssumePie =
+      Args.hasFlag(options::OPT_fsanitize_address_assume_pie,
+                   options::OPT_fno_sanitize_address_assume_pie,
+                   /* Default */false);
 }
 
 /// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
@@ -1516,6 +1524,13 @@
     CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
   } else {
     if (!Args.hasArg(options::OPT_shared)) {
+      bool assume_pie = Args.hasFlag(
+          options::OPT_fsanitize_address_assume_pie,
+          options::OPT_fno_sanitize_address_assume_pie, false);
+      if (assume_pie && !Args.hasArg(options::OPT_pie)) {
+        TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
+            "-fsanitize-address-assume-pie" << "-pie";
+      }
       // LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
       // resource directory.
       SmallString<128> LibAsan(TC.getDriver().ResourceDir);
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -167,17 +167,19 @@
   PM.add(createAddressSanitizerFunctionPass(LangOpts.SanitizeInitOrder,
                                             LangOpts.SanitizeUseAfterReturn,
                                             LangOpts.SanitizeUseAfterScope,
-                                            CGOpts.SanitizerBlacklistFile));
+                                            CGOpts.SanitizerBlacklistFile,
+                                            CGOpts.SanitizeAddressAssumePie));
   PM.add(createAddressSanitizerModulePass(LangOpts.SanitizeInitOrder,
-                                          CGOpts.SanitizerBlacklistFile));
+                                          CGOpts.SanitizerBlacklistFile,
+                                          CGOpts.SanitizeAddressAssumePie));
 }
 
 static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
                                    PassManagerBase &PM) {
   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));
 }
 
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ 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.SanitizeAddressAssumePie =
+    Args.hasArg(OPT_fsanitize_address_assume_pie);
   Opts.SSPBufferSize =
     Args.getLastArgIntValue(OPT_stack_protector_buffer_size, 8, Diags);
   Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
Index: test/Driver/fsanitize.c
===================================================================
--- test/Driver/fsanitize.c
+++ 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-assume-pie -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-ASAN-ASSUME-PIE
+// CHECK-ONLY-ASAN-ASSUME-PIE: warning: argument unused during compilation: '-fsanitize-address-assume-pie'
+
 // 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-assume-pie -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-assume-pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ASSUME-PIE-NO-PIE
+// CHECK-ASAN-ASSUME-PIE-NO-PIE: invalid argument '-fsanitize-address-assume-pie' only allowed with '-pie'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-assume-pie -fno-sanitize-address-assume-pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ASSUME-PIE-CANCEL
+// CHECK-ASAN-ASSUME-PIE-CANCEL-NOT: '-fsanitize-address-assume-pie' 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'
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D303.1.patch
Type: text/x-patch
Size: 10249 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130116/3f0cbd8f/attachment.bin>


More information about the cfe-commits mailing list