r213392 - Make sure globals created by UBSan are not instrumented by ASan.

Alexey Samsonov vonosmas at gmail.com
Fri Jul 18 10:50:07 PDT 2014


Author: samsonov
Date: Fri Jul 18 12:50:06 2014
New Revision: 213392

URL: http://llvm.org/viewvc/llvm-project?rev=213392&view=rev
Log:
Make sure globals created by UBSan are not instrumented by ASan.

Summary:
This change adds description of globals created by UBSan
instrumentation (UBSan handlers, type descriptors, filenames) to
llvm.asan.globals metadata, effectively "blacklisting" them. This can
dramatically decrease the data section in binaries built with UBSan+ASan,
as UBSan tends to create a lot of handlers, and ASan instrumentation
increases the global size to at least 64 bytes.

Test Plan: clang regression test suite

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits, byoungyoung, kcc

Differential Revision: http://reviews.llvm.org/D4575

Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=213392&r1=213391&r2=213392&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Jul 18 12:50:06 2014
@@ -2127,6 +2127,7 @@ llvm::Constant *CodeGenFunction::EmitChe
       CGM.getModule(), Descriptor->getType(),
       /*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
   GV->setUnnamedAddr(true);
+  CGM.disableSanitizerForGlobal(GV);
 
   // Remember the descriptor for this type.
   CGM.setTypeDescriptorInMap(T, GV);
@@ -2170,14 +2171,23 @@ llvm::Value *CodeGenFunction::EmitCheckV
 /// \endcode
 /// For an invalid SourceLocation, the Filename pointer is null.
 llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
+  llvm::Constant *Filename;
+  int Line, Column;
+
   PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
+  if (PLoc.isValid()) {
+    auto FilenameGV = CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src");
+    CGM.disableSanitizerForGlobal(FilenameGV);
+    Filename = FilenameGV;
+    Line = PLoc.getLine();
+    Column = PLoc.getColumn();
+  } else {
+    Filename = llvm::Constant::getNullValue(Int8PtrTy);
+    Line = Column = 0;
+  }
 
-  llvm::Constant *Data[] = {
-    PLoc.isValid() ? CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src")
-                   : llvm::Constant::getNullValue(Int8PtrTy),
-    Builder.getInt32(PLoc.isValid() ? PLoc.getLine() : 0),
-    Builder.getInt32(PLoc.isValid() ? PLoc.getColumn() : 0)
-  };
+  llvm::Constant *Data[] = {Filename, Builder.getInt32(Line),
+                            Builder.getInt32(Column)};
 
   return llvm::ConstantStruct::getAnon(Data);
 }
@@ -2214,6 +2224,7 @@ void CodeGenFunction::EmitCheck(llvm::Va
       new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
                                llvm::GlobalVariable::PrivateLinkage, Info);
   InfoPtr->setUnnamedAddr(true);
+  CGM.disableSanitizerForGlobal(InfoPtr);
 
   SmallVector<llvm::Value *, 4> Args;
   SmallVector<llvm::Type *, 4> ArgTypes;

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=213392&r1=213391&r2=213392&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Jul 18 12:50:06 2014
@@ -1951,11 +1951,11 @@ void CodeGenModule::EmitGlobalVarDefinit
 
 void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
                                        SourceLocation Loc, StringRef Name,
-                                       bool IsDynInit) {
+                                       bool IsDynInit, bool IsBlacklisted) {
   if (!LangOpts.Sanitize.Address)
     return;
   IsDynInit &= !SanitizerBL.isIn(*GV, "init");
-  bool IsBlacklisted = SanitizerBL.isIn(*GV);
+  IsBlacklisted |= SanitizerBL.isIn(*GV);
 
   llvm::GlobalVariable *LocDescr = nullptr;
   llvm::GlobalVariable *GlobalName = nullptr;
@@ -2008,6 +2008,13 @@ void CodeGenModule::reportGlobalToASan(l
   reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
 }
 
+void CodeGenModule::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
+  // For now, just make sure the global is not modified by the ASan
+  // instrumentation.
+  if (LangOpts.Sanitize.Address)
+    reportGlobalToASan(GV, SourceLocation(), "", false, true);
+}
+
 static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
   // Don't give variables common linkage if -fno-common was specified unless it
   // was overridden by a NoCommon attribute.

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=213392&r1=213391&r2=213392&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Jul 18 12:50:06 2014
@@ -1018,7 +1018,11 @@ public:
   void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
                           bool IsDynInit = false);
   void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
-                          StringRef Name, bool IsDynInit = false);
+                          StringRef Name, bool IsDynInit = false,
+                          bool IsBlacklisted = false);
+
+  /// Disable sanitizer instrumentation for this global.
+  void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
 
   void addDeferredVTable(const CXXRecordDecl *RD) {
     DeferredVTables.push_back(RD);

Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=213392&r1=213391&r2=213392&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Fri Jul 18 12:50:06 2014
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN
 
 struct S {
   double d;
@@ -6,6 +7,12 @@ struct S {
   virtual int f();
 };
 
+// Check that type descriptor global is not modified by ASan.
+// CHECK-ASAN: [[TYPE_DESCR:@[0-9]+]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'S'\00" }
+
+// Check that type mismatch handler is not modified by ASan.
+// CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
+
 struct T : S {};
 
 // CHECK-LABEL: @_Z17reference_binding
@@ -31,6 +38,7 @@ void reference_binding(int *p, S *q) {
 }
 
 // CHECK-LABEL: @_Z13member_access
+// CHECK-ASAN-LABEL: @_Z13member_access
 void member_access(S *p) {
   // (1a) Check 'p' is appropriately sized and aligned for member access.
 





More information about the cfe-commits mailing list