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 22using namespace llvm; 23 24static void appendToGlobalArray(const char *Array, 25 Module &M, Function *F, int Priority) { 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 // If there is a global_ctors array, use the existing struct type, which can 35 // have 2 or 3 fields. 36 ArrayType *ATy = cast<ArrayType>(GVCtor->getType()->getElementType()); 37 EltTy = cast<StructType>(ATy->getElementType()); 38 if (Constant *Init = GVCtor->getInitializer()) { 39 unsigned n = Init->getNumOperands(); 40 CurrentCtors.reserve(n + 1); 41 for (unsigned i = 0; i != n; ++i) 42 CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); 43 } 44 GVCtor->eraseFromParent(); 45 } else { 46 // Use the new three-field struct if there isn't one already. 47 EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), 48 IRB.getInt8PtrTy(), nullptr); 49 } 50 51 // Build a 2 or 3 field global_ctor entry. We don't take a comdat key. 52 Constant *CSVals[3]; 53 CSVals[0] = IRB.getInt32(Priority); 54 CSVals[1] = F; 55 // FIXME: Drop support for the two element form in LLVM 4.0. 56 if (EltTy->getNumElements() >= 3) 57 CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy()); 58 Constant *RuntimeCtorInit = 59 ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); 60 61 CurrentCtors.push_back(RuntimeCtorInit); 62 63 // Create a new initializer. 64 ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size()); 65 Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 66 67 // Create the new global variable and replace all uses of 68 // the old global variable with the new one. 69 (void)new GlobalVariable(M, NewInit->getType(), false, 70 GlobalValue::AppendingLinkage, NewInit, Array); 71} 72 73void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) { 74 appendToGlobalArray("llvm.global_ctors", M, F, Priority); 75} 76 77void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) { 78 appendToGlobalArray("llvm.global_dtors", M, F, Priority); 79} 80 81GlobalVariable * 82llvm::collectUsedGlobalVariables(Module &M, SmallPtrSetImpl<GlobalValue *> &Set, 83 bool CompilerUsed) { 84 const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; 85 GlobalVariable *GV = M.getGlobalVariable(Name); 86 if (!GV || !GV->hasInitializer()) 87 return GV; 88 89 const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); 90 for (unsigned I = 0, E = Init->getNumOperands(); I != E; ++I) { 91 Value *Op = Init->getOperand(I); 92 GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases()); 93 Set.insert(G); 94 } 95 return GV; 96} 97 98Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { 99 if (isa<Function>(FuncOrBitcast)) 100 return cast<Function>(FuncOrBitcast); 101 FuncOrBitcast->dump(); 102 std::string Err; 103 raw_string_ostream Stream(Err); 104 Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast; 105 report_fatal_error(Err); 106} 107 108std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions( 109 Module &M, StringRef CtorName, StringRef InitName, 110 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 111 StringRef VersionCheckName) { 112 assert(!InitName.empty() && "Expected init function name"); 113 assert(InitArgTypes.size() == InitArgTypes.size() && 114 "Sanitizer's init function expects different number of arguments"); 115 Function *Ctor = Function::Create( 116 FunctionType::get(Type::getVoidTy(M.getContext()), false), 117 GlobalValue::InternalLinkage, CtorName, &M); 118 BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 119 IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); 120 Function *InitFunction = 121 checkSanitizerInterfaceFunction(M.getOrInsertFunction( 122 InitName, FunctionType::get(IRB.getVoidTy(), InitArgTypes, false), 123 AttributeSet())); 124 InitFunction->setLinkage(Function::ExternalLinkage); 125 IRB.CreateCall(InitFunction, InitArgs); 126 if (!VersionCheckName.empty()) { 127 Function *VersionCheckFunction = 128 checkSanitizerInterfaceFunction(M.getOrInsertFunction( 129 VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 130 AttributeSet())); 131 IRB.CreateCall(VersionCheckFunction, {}); 132 } 133 return std::make_pair(Ctor, InitFunction); 134} 135 136