[llvm] r260632 - [msan] Put msan constructor in a comdat.

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 11 16:37:52 PST 2016


Author: eugenis
Date: Thu Feb 11 18:37:52 2016
New Revision: 260632

URL: http://llvm.org/viewvc/llvm-project?rev=260632&view=rev
Log:
[msan] Put msan constructor in a comdat.

MSan adds a constructor to each translation unit that calls
__msan_init, and does nothing else. The idea is to run __msan_init
before any instrumented code. This results in multiple constructors
and multiple .init_array entries in the final binary, one per
translation unit. This is absolutely unnecessary; one would be
enough.

This change moves the constructors to a comdat group in order to drop
the extra ones.

Added:
    llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll
Modified:
    llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h
    llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
    llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp
    llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll

Modified: llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h?rev=260632&r1=260631&r2=260632&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h Thu Feb 11 18:37:52 2016
@@ -34,10 +34,12 @@ template <class PtrType> class SmallPtrS
 /// This wraps the function in the appropriate structure and stores it along
 /// side other global constructors. For details see
 /// http://llvm.org/docs/LangRef.html#intg_global_ctors
-void appendToGlobalCtors(Module &M, Function *F, int Priority);
+void appendToGlobalCtors(Module &M, Function *F, int Priority,
+                         Constant *Data = nullptr);
 
 /// Same as appendToGlobalCtors(), but for global dtors.
-void appendToGlobalDtors(Module &M, Function *F, int Priority);
+void appendToGlobalDtors(Module &M, Function *F, int Priority,
+                         Constant *Data = nullptr);
 
 /// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect
 /// the initializer elements of that global in Set and return the global itself.

Modified: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp?rev=260632&r1=260631&r2=260632&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp Thu Feb 11 18:37:52 2016
@@ -540,8 +540,10 @@ bool MemorySanitizer::doInitialization(M
       createSanitizerCtorAndInitFunctions(M, kMsanModuleCtorName, kMsanInitName,
                                           /*InitArgTypes=*/{},
                                           /*InitArgs=*/{});
+  Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
+  MsanCtorFunction->setComdat(MsanCtorComdat);
 
-  appendToGlobalCtors(M, MsanCtorFunction, 0);
+  appendToGlobalCtors(M, MsanCtorFunction, 0, MsanCtorFunction);
 
   if (TrackOrigins)
     new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,

Modified: llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp?rev=260632&r1=260631&r2=260632&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp Thu Feb 11 18:37:52 2016
@@ -21,8 +21,8 @@
 
 using namespace llvm;
 
-static void appendToGlobalArray(const char *Array, 
-                                Module &M, Function *F, int Priority) {
+static void appendToGlobalArray(const char *Array, Module &M, Function *F,
+                                int Priority, Constant *Data) {
   IRBuilder<> IRB(M.getContext());
   FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
 
@@ -31,15 +31,26 @@ static void appendToGlobalArray(const ch
   SmallVector<Constant *, 16> CurrentCtors;
   StructType *EltTy;
   if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
-    // If there is a global_ctors array, use the existing struct type, which can
-    // have 2 or 3 fields.
     ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType());
-    EltTy = cast<StructType>(ATy->getElementType());
+    StructType *OldEltTy = cast<StructType>(ATy->getElementType());
+    // Upgrade a 2-field global array type to the new 3-field format if needed.
+    if (Data && OldEltTy->getNumElements() < 3)
+      EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
+                              IRB.getInt8PtrTy(), nullptr);
+    else
+      EltTy = OldEltTy;
     if (Constant *Init = GVCtor->getInitializer()) {
       unsigned n = Init->getNumOperands();
       CurrentCtors.reserve(n + 1);
-      for (unsigned i = 0; i != n; ++i)
-        CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
+      for (unsigned i = 0; i != n; ++i) {
+        auto Ctor = cast<Constant>(Init->getOperand(i));
+        if (EltTy != OldEltTy)
+          Ctor = ConstantStruct::get(
+              EltTy, Ctor->getAggregateElement((unsigned)0),
+              Ctor->getAggregateElement(1),
+              Constant::getNullValue(IRB.getInt8PtrTy()), nullptr);
+        CurrentCtors.push_back(Ctor);
+      }
     }
     GVCtor->eraseFromParent();
   } else {
@@ -54,7 +65,8 @@ static void appendToGlobalArray(const ch
   CSVals[1] = F;
   // FIXME: Drop support for the two element form in LLVM 4.0.
   if (EltTy->getNumElements() >= 3)
-    CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
+    CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy())
+                     : Constant::getNullValue(IRB.getInt8PtrTy());
   Constant *RuntimeCtorInit =
       ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
 
@@ -70,12 +82,12 @@ static void appendToGlobalArray(const ch
                            GlobalValue::AppendingLinkage, NewInit, Array);
 }
 
-void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) {
-  appendToGlobalArray("llvm.global_ctors", M, F, Priority);
+void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) {
+  appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data);
 }
 
-void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) {
-  appendToGlobalArray("llvm.global_dtors", M, F, Priority);
+void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) {
+  appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
 }
 
 GlobalVariable *
@@ -132,4 +144,3 @@ std::pair<Function *, Function *> llvm::
   }
   return std::make_pair(Ctor, InitFunction);
 }
-

Added: llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll?rev=260632&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll (added)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll Thu Feb 11 18:37:52 2016
@@ -0,0 +1,17 @@
+; MSan converts 2-element global_ctors to 3-element when adding the new entry.
+; RUN: opt < %s -msan -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: $msan.module_ctor = comdat any
+; CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }]
+
+ at llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }]
+
+define internal void @f() {
+entry:
+  ret void
+}
+
+; CHECK: define internal void @msan.module_ctor() comdat {

Modified: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll?rev=260632&r1=260631&r2=260632&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll (original)
+++ llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll Thu Feb 11 18:37:52 2016
@@ -4,7 +4,8 @@
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-; CHECK: @llvm.global_ctors {{.*}} @msan.module_ctor
+; CHECK: $msan.module_ctor = comdat any
+; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }
 
 ; Check the presence and the linkage type of __msan_track_origins and
 ; other interface symbols.
@@ -981,5 +982,5 @@ define i8* @MismatchingCallMustTailCall(
 ; CHECK-NEXT: ret i8*
 
 
-; CHECK-LABEL: define internal void @msan.module_ctor
+; CHECK-LABEL: define internal void @msan.module_ctor() comdat {
 ; CHECK: call void @__msan_init()




More information about the llvm-commits mailing list