1 //===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This family of functions perform manipulations on Modules. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Utils/ModuleUtils.h" 15 #include "llvm/ADT/SmallPtrSet.h" 16 #include "llvm/IR/DerivedTypes.h" 17 #include "llvm/IR/Function.h" 18 #include "llvm/IR/IRBuilder.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/Support/raw_ostream.h" 21 22 using namespace llvm; 23 24 static void appendToGlobalArray(const char *Array, Module &M, Function *F, 25 int Priority, Constant *Data) { 26 IRBuilder<> IRB(M.getContext()); 27 FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); 28 29 // Get the current set of static global constructors and add the new ctor 30 // to the list. 31 SmallVector<Constant *, 16> CurrentCtors; 32 StructType *EltTy; 33 if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { 34 ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType()); 35 StructType *OldEltTy = cast<StructType>(ATy->getElementType()); 36 // Upgrade a 2-field global array type to the new 3-field format if needed. 37 if (Data && OldEltTy->getNumElements() < 3) 38 EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), 39 IRB.getInt8PtrTy(), nullptr); 40 else 41 EltTy = OldEltTy; 42 if (Constant *Init = GVCtor->getInitializer()) { 43 unsigned n = Init->getNumOperands(); 44 CurrentCtors.reserve(n + 1); 45 for (unsigned i = 0; i != n; ++i) { 46 auto Ctor = cast<Constant>(Init->getOperand(i)); 47 if (EltTy != OldEltTy) 48 Ctor = ConstantStruct::get( 49 EltTy, Ctor->getAggregateElement((unsigned)0), 50 Ctor->getAggregateElement(1), 51 Constant::getNullValue(IRB.getInt8PtrTy()), nullptr); 52 CurrentCtors.push_back(Ctor); 53 } 54 } 55 GVCtor->eraseFromParent(); 56 } else { 57 // Use the new three-field struct if there isn't one already. 58 EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), 59 IRB.getInt8PtrTy(), nullptr); 60 } 61 62 // Build a 2 or 3 field global_ctor entry. We don't take a comdat key. 63 Constant *CSVals[3]; 64 CSVals[0] = IRB.getInt32(Priority); 65 CSVals[1] = F; 66 // FIXME: Drop support for the two element form in LLVM 4.0. 67 if (EltTy->getNumElements() >= 3) 68 CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) 69 : Constant::getNullValue(IRB.getInt8PtrTy()); 70 Constant *RuntimeCtorInit = 71 ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); 72 73 CurrentCtors.push_back(RuntimeCtorInit); 74 75 // Create a new initializer. 76 ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size()); 77 Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 78 79 // Create the new global variable and replace all uses of 80 // the old global variable with the new one. 81 (void)new GlobalVariable(M, NewInit->getType(), false, 82 GlobalValue::AppendingLinkage, NewInit, Array); 83 } 84 85 void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) { 86 appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data); 87 } 88 89 void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) { 90 appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); 91 } 92 93 GlobalVariable * 94 llvm::collectUsedGlobalVariables(Module &M, SmallPtrSetImpl<GlobalValue *> &Set, 95 bool CompilerUsed) { 96 const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; 97 GlobalVariable *GV = M.getGlobalVariable(Name); 98 if (!GV || !GV->hasInitializer()) 99 return GV; 100 101 const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); 102 for (Value *Op : Init->operands()) { 103 GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases()); 104 Set.insert(G); 105 } 106 return GV; 107 } 108 109 Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { 110 if (isa<Function>(FuncOrBitcast)) 111 return cast<Function>(FuncOrBitcast); 112 FuncOrBitcast->dump(); 113 std::string Err; 114 raw_string_ostream Stream(Err); 115 Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast; 116 report_fatal_error(Err); 117 } 118 119 std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions( 120 Module &M, StringRef CtorName, StringRef InitName, 121 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 122 StringRef VersionCheckName) { 123 assert(!InitName.empty() && "Expected init function name"); 124 assert(InitArgTypes.size() == InitArgTypes.size() && 125 "Sanitizer's init function expects different number of arguments"); 126 Function *Ctor = Function::Create( 127 FunctionType::get(Type::getVoidTy(M.getContext()), false), 128 GlobalValue::InternalLinkage, CtorName, &M); 129 BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 130 IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); 131 Function *InitFunction = 132 checkSanitizerInterfaceFunction(M.getOrInsertFunction( 133 InitName, FunctionType::get(IRB.getVoidTy(), InitArgTypes, false), 134 AttributeSet())); 135 InitFunction->setLinkage(Function::ExternalLinkage); 136 IRB.CreateCall(InitFunction, InitArgs); 137 if (!VersionCheckName.empty()) { 138 Function *VersionCheckFunction = 139 checkSanitizerInterfaceFunction(M.getOrInsertFunction( 140 VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 141 AttributeSet())); 142 IRB.CreateCall(VersionCheckFunction, {}); 143 } 144 return std::make_pair(Ctor, InitFunction); 145 } 146