[llvm] r282988 - [ASAN] Add the binder globals on Darwin to llvm.compiler.used to avoid LTO dead-stripping

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 30 17:05:34 PDT 2016


Author: mehdi_amini
Date: Fri Sep 30 19:05:34 2016
New Revision: 282988

URL: http://llvm.org/viewvc/llvm-project?rev=282988&view=rev
Log:
[ASAN] Add the binder globals on Darwin to llvm.compiler.used to avoid LTO dead-stripping

The binder is in a specific section that "reverse" the edges in a
regular dead-stripping: the binder is live as long as a global it
references is live.

This is a big hammer that prevents LLVM from dead-stripping these,
while still allowing linker dead-stripping (with special knowledge
of the section).

Differential Revision: https://reviews.llvm.org/D24673

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
    llvm/trunk/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=282988&r1=282987&r2=282988&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Fri Sep 30 19:05:34 2016
@@ -1626,6 +1626,10 @@ bool AddressSanitizerModule::InstrumentG
     // variable to the metadata struct.
     StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
 
+    // Keep the list of "Liveness" GV created to be added to llvm.compiler.used
+    SmallVector<Constant *, 16> LivenessGlobals;
+    LivenessGlobals.reserve(n);
+
     for (size_t i = 0; i < n; i++) {
       GlobalVariable *Metadata = new GlobalVariable(
           M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
@@ -1637,10 +1641,38 @@ bool AddressSanitizerModule::InstrumentG
           Initializers[i]->getAggregateElement(0u),
           ConstantExpr::getPointerCast(Metadata, IntptrTy),
           nullptr);
+
+      // Recover the name of the variable this global is pointing to
+      StringRef GVName =
+          Initializers[i]->getAggregateElement(0u)->getOperand(0)->getName();
+
       GlobalVariable *Liveness = new GlobalVariable(
-          M, LivenessTy, false, GlobalVariable::InternalLinkage,
-          LivenessBinder, "");
+          M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
+          Twine("__asan_binder_") + GVName);
       Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
+      LivenessGlobals.push_back(
+          ConstantExpr::getBitCast(Liveness, IRB.getInt8PtrTy()));
+    }
+
+    if (!LivenessGlobals.empty()) {
+      // Update llvm.compiler.used, adding the new liveness globals. This is
+      // needed so that during LTO these variables stay alive. The alternative
+      // would be to have the linker handling the LTO symbols, but libLTO
+      // current
+      // API does not expose access to the section for each symbol.
+      if (GlobalVariable *LLVMUsed =
+              M.getGlobalVariable("llvm.compiler.used")) {
+        ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
+        for (auto &V : Inits->operands())
+          LivenessGlobals.push_back(cast<Constant>(&V));
+        LLVMUsed->eraseFromParent();
+      }
+      llvm::ArrayType *ATy =
+          llvm::ArrayType::get(IRB.getInt8PtrTy(), LivenessGlobals.size());
+      auto *LLVMUsed = new llvm::GlobalVariable(
+          M, ATy, false, llvm::GlobalValue::AppendingLinkage,
+          llvm::ConstantArray::get(ATy, LivenessGlobals), "llvm.compiler.used");
+      LLVMUsed->setSection("llvm.metadata");
     }
   } else {
     // On all other platfoms, we just emit an array of global metadata

Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll?rev=282988&r1=282987&r2=282988&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll Fri Sep 30 19:05:34 2016
@@ -22,7 +22,12 @@ target triple = "x86_64-apple-macosx10.1
 ; CHECK: [[METADATA:@[0-9]+]] = internal global {{.*}} @global {{.*}} section "__DATA,__asan_globals,regular", align 1
 
 ; Find the liveness binder for @global and its metadata:
-; CHECK: @{{[0-9]+}} = internal global {{.*}} @global {{.*}} [[METADATA]] {{.*}} section "__DATA,__asan_liveness,regular,live_support"
+; CHECK: @__asan_binder_global = internal global {{.*}} @global {{.*}} [[METADATA]] {{.*}} section "__DATA,__asan_liveness,regular,live_support"
+
+; The binder has to be inserted to llvm.compiler.used to avoid being stripped
+; during LTO.
+; CHECK: @llvm.compiler.used {{.*}} @__asan_binder_global {{.*}} section "llvm.metadata"
+
 
 ; Test that __asan_register_image_globals is invoked from the constructor:
 ; CHECK-LABEL: define internal void @asan.module_ctor




More information about the llvm-commits mailing list