Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1666,6 +1666,10 @@ // 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 LivenessGlobals; + LivenessGlobals.reserve(n); + for (size_t i = 0; i < n; i++) { GlobalVariable *Metadata = new GlobalVariable( M, GlobalStructTy, false, GlobalVariable::InternalLinkage, @@ -1677,10 +1681,38 @@ 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(LLVMUsed->getInitializer()); + for (auto &V : Inits->operands()) + LivenessGlobals.push_back(cast(&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 Index: llvm/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll =================================================================== --- llvm/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll +++ llvm/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll @@ -22,7 +22,12 @@ ; 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