Index: include/llvm/Transforms/InstrProfiling.h =================================================================== --- include/llvm/Transforms/InstrProfiling.h +++ include/llvm/Transforms/InstrProfiling.h @@ -44,7 +44,7 @@ } }; DenseMap ProfileDataMap; - std::vector UsedVars; + std::vector UsedVars; std::vector ReferencedNames; GlobalVariable *NamesVar; size_t NamesSize; Index: include/llvm/Transforms/Utils/ModuleUtils.h =================================================================== --- include/llvm/Transforms/Utils/ModuleUtils.h +++ include/llvm/Transforms/Utils/ModuleUtils.h @@ -59,6 +59,12 @@ /// the list of public globals in the module. bool nameUnamedGlobals(Module &M); +/// \brief Adds global values to the llvm.used list. +void appendToUsed(Module &M, ArrayRef Values); + +/// \brief Adds global values to the llvm.compiler.used list. +void appendToCompilerUsed(Module &M, ArrayRef Values); + } // End llvm namespace #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H Index: lib/LTO/LTOCodeGenerator.cpp =================================================================== --- lib/LTO/LTOCodeGenerator.cpp +++ lib/LTO/LTOCodeGenerator.cpp @@ -58,6 +58,7 @@ #include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/ObjCARC.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include using namespace llvm; @@ -364,18 +365,10 @@ void LTOCodeGenerator::preserveDiscardableGVs( Module &TheModule, llvm::function_ref mustPreserveGV) { - SetVector UsedValuesSet; - if (GlobalVariable *LLVMUsed = - TheModule.getGlobalVariable("llvm.compiler.used")) { - ConstantArray *Inits = cast(LLVMUsed->getInitializer()); - for (auto &V : Inits->operands()) - UsedValuesSet.insert(cast(&V)); - LLVMUsed->eraseFromParent(); - } - llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext()); + SetVector UsedValuesSet; auto mayPreserveGlobal = [&](GlobalValue &GV) { if (!GV.isDiscardableIfUnused() || GV.isDeclaration() || - !mustPreserveGV(GV)) + !mustPreserveGV(GV)) return; if (GV.hasAvailableExternallyLinkage()) return emitWarning( @@ -384,7 +377,7 @@ if (GV.hasInternalLinkage()) return emitWarning((Twine("Linker asked to preserve internal global: '") + GV.getName() + "'").str()); - UsedValuesSet.insert(ConstantExpr::getBitCast(&GV, i8PTy)); + UsedValuesSet.insert(&GV); }; for (auto &GV : TheModule) mayPreserveGlobal(GV); @@ -396,12 +389,7 @@ if (UsedValuesSet.empty()) return; - llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesSet.size()); - auto *LLVMUsed = new llvm::GlobalVariable( - TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, UsedValuesSet.getArrayRef()), - "llvm.compiler.used"); - LLVMUsed->setSection("llvm.metadata"); + appendToCompilerUsed(TheModule, UsedValuesSet.getArrayRef()); } void LTOCodeGenerator::applyScopeRestrictions() { Index: lib/LTO/UpdateCompilerUsed.cpp =================================================================== --- lib/LTO/UpdateCompilerUsed.cpp +++ lib/LTO/UpdateCompilerUsed.cpp @@ -18,6 +18,7 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; @@ -121,26 +122,9 @@ if (UsedValues.empty()) return; - llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext()); - std::vector UsedValuesList; - for (const auto *GV : UsedValues) { - Constant *c = - ConstantExpr::getBitCast(const_cast(GV), i8PTy); - UsedValuesList.push_back(c); - } - - GlobalVariable *LLVMUsed = TheModule.getGlobalVariable("llvm.compiler.used"); - if (LLVMUsed) { - ConstantArray *Inits = cast(LLVMUsed->getInitializer()); - for (auto &V : Inits->operands()) - UsedValuesList.push_back(cast(&V)); - LLVMUsed->eraseFromParent(); - } - - llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesList.size()); - LLVMUsed = new llvm::GlobalVariable( - TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, UsedValuesList), "llvm.compiler.used"); + std::vector UsedValuesList; + for (const auto *GV : UsedValues) + UsedValuesList.push_back(const_cast(GV)); - LLVMUsed->setSection("llvm.metadata"); + appendToCompilerUsed(TheModule, UsedValuesList); } Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1624,7 +1624,7 @@ StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr); // Keep the list of "Liveness" GV created to be added to llvm.compiler.used - SmallVector LivenessGlobals; + SmallVector LivenessGlobals; LivenessGlobals.reserve(n); for (size_t i = 0; i < n; i++) { @@ -1647,30 +1647,15 @@ 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())); + LivenessGlobals.push_back(Liveness); } - 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"); - } + // 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 (!LivenessGlobals.empty()) + appendToCompilerUsed(M, LivenessGlobals); } else { // On all other platfoms, we just emit an array of global metadata // structures. Index: lib/Transforms/Instrumentation/InstrProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/InstrProfiling.cpp +++ lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -553,31 +553,8 @@ } void InstrProfiling::emitUses() { - if (UsedVars.empty()) - return; - - GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); - std::vector MergedVars; - if (LLVMUsed) { - // Collect the existing members of llvm.used. - ConstantArray *Inits = cast(LLVMUsed->getInitializer()); - for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I) - MergedVars.push_back(Inits->getOperand(I)); - LLVMUsed->eraseFromParent(); - } - - Type *i8PTy = Type::getInt8PtrTy(M->getContext()); - // Add uses for our data. - for (auto *Value : UsedVars) - MergedVars.push_back( - ConstantExpr::getBitCast(cast(Value), i8PTy)); - - // Recreate llvm.used. - ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size()); - LLVMUsed = - new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage, - ConstantArray::get(ATy, MergedVars), "llvm.used"); - LLVMUsed->setSection("llvm.metadata"); + if (!UsedVars.empty()) + appendToUsed(*M, UsedVars); } void InstrProfiling::emitInitialization() { Index: lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- lib/Transforms/Utils/ModuleUtils.cpp +++ lib/Transforms/Utils/ModuleUtils.cpp @@ -89,6 +89,37 @@ appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); } +static void appendToUsedList(Module &M, StringRef Name, ArrayRef Values) { + GlobalVariable *GV = M.getGlobalVariable(Name); + SmallVector Init; + if (GV) { + ConstantArray *CA = dyn_cast(GV->getInitializer()); + for (auto &Op : CA->operands()) + Init.push_back(cast_or_null(Op)); + GV->eraseFromParent(); + } + + Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); + for (auto *V : Values) + Init.push_back(ConstantExpr::getBitCast(V, Int8PtrTy)); + + if (Init.empty()) + return; + + ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); + GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, + ConstantArray::get(ATy, Init), Name); + GV->setSection("llvm.metadata"); +} + +void llvm::appendToUsed(Module &M, ArrayRef Values) { + appendToUsedList(M, "llvm.used", Values); +} + +void llvm::appendToCompilerUsed(Module &M, ArrayRef Values) { + appendToUsedList(M, "llvm.compiler.used", Values); +} + Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { if (isa(FuncOrBitcast)) return cast(FuncOrBitcast);