1dff0c46cSDimitry Andric //===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// 2dff0c46cSDimitry Andric // 3dff0c46cSDimitry Andric // The LLVM Compiler Infrastructure 4dff0c46cSDimitry Andric // 5dff0c46cSDimitry Andric // This file is distributed under the University of Illinois Open Source 6dff0c46cSDimitry Andric // License. See LICENSE.TXT for details. 7dff0c46cSDimitry Andric // 8dff0c46cSDimitry Andric //===----------------------------------------------------------------------===// 9dff0c46cSDimitry Andric // 10dff0c46cSDimitry Andric // This family of functions perform manipulations on Modules. 11dff0c46cSDimitry Andric // 12dff0c46cSDimitry Andric //===----------------------------------------------------------------------===// 13dff0c46cSDimitry Andric 14dff0c46cSDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h" 15139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h" 16139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 17139f7f9bSDimitry Andric #include "llvm/IR/IRBuilder.h" 18139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 19ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h" 20dff0c46cSDimitry Andric 21dff0c46cSDimitry Andric using namespace llvm; 22dff0c46cSDimitry Andric 233ca95b02SDimitry Andric static void appendToGlobalArray(const char *Array, Module &M, Function *F, 243ca95b02SDimitry Andric int Priority, Constant *Data) { 25dff0c46cSDimitry Andric IRBuilder<> IRB(M.getContext()); 26dff0c46cSDimitry Andric FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); 27dff0c46cSDimitry Andric 28dff0c46cSDimitry Andric // Get the current set of static global constructors and add the new ctor 29dff0c46cSDimitry Andric // to the list. 30dff0c46cSDimitry Andric SmallVector<Constant *, 16> CurrentCtors; 3191bc56edSDimitry Andric StructType *EltTy; 32dff0c46cSDimitry Andric if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { 333ca95b02SDimitry Andric ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType()); 343ca95b02SDimitry Andric StructType *OldEltTy = cast<StructType>(ATy->getElementType()); 353ca95b02SDimitry Andric // Upgrade a 2-field global array type to the new 3-field format if needed. 363ca95b02SDimitry Andric if (Data && OldEltTy->getNumElements() < 3) 373ca95b02SDimitry Andric EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), 385517e702SDimitry Andric IRB.getInt8PtrTy()); 393ca95b02SDimitry Andric else 403ca95b02SDimitry Andric EltTy = OldEltTy; 41dff0c46cSDimitry Andric if (Constant *Init = GVCtor->getInitializer()) { 42dff0c46cSDimitry Andric unsigned n = Init->getNumOperands(); 43dff0c46cSDimitry Andric CurrentCtors.reserve(n + 1); 443ca95b02SDimitry Andric for (unsigned i = 0; i != n; ++i) { 453ca95b02SDimitry Andric auto Ctor = cast<Constant>(Init->getOperand(i)); 463ca95b02SDimitry Andric if (EltTy != OldEltTy) 475517e702SDimitry Andric Ctor = 485517e702SDimitry Andric ConstantStruct::get(EltTy, Ctor->getAggregateElement((unsigned)0), 493ca95b02SDimitry Andric Ctor->getAggregateElement(1), 505517e702SDimitry Andric Constant::getNullValue(IRB.getInt8PtrTy())); 513ca95b02SDimitry Andric CurrentCtors.push_back(Ctor); 523ca95b02SDimitry Andric } 53dff0c46cSDimitry Andric } 54dff0c46cSDimitry Andric GVCtor->eraseFromParent(); 5591bc56edSDimitry Andric } else { 567d523365SDimitry Andric // Use the new three-field struct if there isn't one already. 5791bc56edSDimitry Andric EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), 585517e702SDimitry Andric IRB.getInt8PtrTy()); 59dff0c46cSDimitry Andric } 60dff0c46cSDimitry Andric 6191bc56edSDimitry Andric // Build a 2 or 3 field global_ctor entry. We don't take a comdat key. 6291bc56edSDimitry Andric Constant *CSVals[3]; 6391bc56edSDimitry Andric CSVals[0] = IRB.getInt32(Priority); 6491bc56edSDimitry Andric CSVals[1] = F; 6591bc56edSDimitry Andric // FIXME: Drop support for the two element form in LLVM 4.0. 6691bc56edSDimitry Andric if (EltTy->getNumElements() >= 3) 673ca95b02SDimitry Andric CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) 683ca95b02SDimitry Andric : Constant::getNullValue(IRB.getInt8PtrTy()); 6991bc56edSDimitry Andric Constant *RuntimeCtorInit = 7091bc56edSDimitry Andric ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); 7191bc56edSDimitry Andric 72dff0c46cSDimitry Andric CurrentCtors.push_back(RuntimeCtorInit); 73dff0c46cSDimitry Andric 74dff0c46cSDimitry Andric // Create a new initializer. 7591bc56edSDimitry Andric ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size()); 76dff0c46cSDimitry Andric Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 77dff0c46cSDimitry Andric 78dff0c46cSDimitry Andric // Create the new global variable and replace all uses of 79dff0c46cSDimitry Andric // the old global variable with the new one. 80dff0c46cSDimitry Andric (void)new GlobalVariable(M, NewInit->getType(), false, 81dff0c46cSDimitry Andric GlobalValue::AppendingLinkage, NewInit, Array); 82dff0c46cSDimitry Andric } 83dff0c46cSDimitry Andric 843ca95b02SDimitry Andric void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) { 853ca95b02SDimitry Andric appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data); 86dff0c46cSDimitry Andric } 87dff0c46cSDimitry Andric 883ca95b02SDimitry Andric void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) { 893ca95b02SDimitry Andric appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); 90f785676fSDimitry Andric } 91ff0cc061SDimitry Andric 92d88c1a5aSDimitry Andric static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) { 93d88c1a5aSDimitry Andric GlobalVariable *GV = M.getGlobalVariable(Name); 94d88c1a5aSDimitry Andric SmallPtrSet<Constant *, 16> InitAsSet; 95d88c1a5aSDimitry Andric SmallVector<Constant *, 16> Init; 96d88c1a5aSDimitry Andric if (GV) { 97d88c1a5aSDimitry Andric ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer()); 98d88c1a5aSDimitry Andric for (auto &Op : CA->operands()) { 99d88c1a5aSDimitry Andric Constant *C = cast_or_null<Constant>(Op); 100d88c1a5aSDimitry Andric if (InitAsSet.insert(C).second) 101d88c1a5aSDimitry Andric Init.push_back(C); 102d88c1a5aSDimitry Andric } 103d88c1a5aSDimitry Andric GV->eraseFromParent(); 104d88c1a5aSDimitry Andric } 105d88c1a5aSDimitry Andric 106d88c1a5aSDimitry Andric Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); 107d88c1a5aSDimitry Andric for (auto *V : Values) { 108d88c1a5aSDimitry Andric Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy); 109d88c1a5aSDimitry Andric if (InitAsSet.insert(C).second) 110d88c1a5aSDimitry Andric Init.push_back(C); 111d88c1a5aSDimitry Andric } 112d88c1a5aSDimitry Andric 113d88c1a5aSDimitry Andric if (Init.empty()) 114d88c1a5aSDimitry Andric return; 115d88c1a5aSDimitry Andric 116d88c1a5aSDimitry Andric ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); 117d88c1a5aSDimitry Andric GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, 118d88c1a5aSDimitry Andric ConstantArray::get(ATy, Init), Name); 119d88c1a5aSDimitry Andric GV->setSection("llvm.metadata"); 120d88c1a5aSDimitry Andric } 121d88c1a5aSDimitry Andric 122d88c1a5aSDimitry Andric void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { 123d88c1a5aSDimitry Andric appendToUsedList(M, "llvm.used", Values); 124d88c1a5aSDimitry Andric } 125d88c1a5aSDimitry Andric 126d88c1a5aSDimitry Andric void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { 127d88c1a5aSDimitry Andric appendToUsedList(M, "llvm.compiler.used", Values); 128d88c1a5aSDimitry Andric } 129d88c1a5aSDimitry Andric 130ff0cc061SDimitry Andric Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { 131ff0cc061SDimitry Andric if (isa<Function>(FuncOrBitcast)) 132ff0cc061SDimitry Andric return cast<Function>(FuncOrBitcast); 1337a7e6055SDimitry Andric FuncOrBitcast->print(errs()); 1347a7e6055SDimitry Andric errs() << '\n'; 135ff0cc061SDimitry Andric std::string Err; 136ff0cc061SDimitry Andric raw_string_ostream Stream(Err); 137ff0cc061SDimitry Andric Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast; 138ff0cc061SDimitry Andric report_fatal_error(Err); 139ff0cc061SDimitry Andric } 140ff0cc061SDimitry Andric 1417a7e6055SDimitry Andric Function *llvm::declareSanitizerInitFunction(Module &M, StringRef InitName, 1427a7e6055SDimitry Andric ArrayRef<Type *> InitArgTypes) { 1437a7e6055SDimitry Andric assert(!InitName.empty() && "Expected init function name"); 1447a7e6055SDimitry Andric Function *F = checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1457a7e6055SDimitry Andric InitName, 1467a7e6055SDimitry Andric FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false), 1477a7e6055SDimitry Andric AttributeList())); 1487a7e6055SDimitry Andric F->setLinkage(Function::ExternalLinkage); 1497a7e6055SDimitry Andric return F; 1507a7e6055SDimitry Andric } 1517a7e6055SDimitry Andric 152ff0cc061SDimitry Andric std::pair<Function *, Function *> llvm::createSanitizerCtorAndInitFunctions( 153ff0cc061SDimitry Andric Module &M, StringRef CtorName, StringRef InitName, 1547d523365SDimitry Andric ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 1557d523365SDimitry Andric StringRef VersionCheckName) { 156ff0cc061SDimitry Andric assert(!InitName.empty() && "Expected init function name"); 157d88c1a5aSDimitry Andric assert(InitArgs.size() == InitArgTypes.size() && 158ff0cc061SDimitry Andric "Sanitizer's init function expects different number of arguments"); 1597a7e6055SDimitry Andric Function *InitFunction = 1607a7e6055SDimitry Andric declareSanitizerInitFunction(M, InitName, InitArgTypes); 161ff0cc061SDimitry Andric Function *Ctor = Function::Create( 162ff0cc061SDimitry Andric FunctionType::get(Type::getVoidTy(M.getContext()), false), 163ff0cc061SDimitry Andric GlobalValue::InternalLinkage, CtorName, &M); 164ff0cc061SDimitry Andric BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 165ff0cc061SDimitry Andric IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); 166ff0cc061SDimitry Andric IRB.CreateCall(InitFunction, InitArgs); 1677d523365SDimitry Andric if (!VersionCheckName.empty()) { 1687d523365SDimitry Andric Function *VersionCheckFunction = 1697d523365SDimitry Andric checkSanitizerInterfaceFunction(M.getOrInsertFunction( 1707d523365SDimitry Andric VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 1717a7e6055SDimitry Andric AttributeList())); 1727d523365SDimitry Andric IRB.CreateCall(VersionCheckFunction, {}); 1737d523365SDimitry Andric } 174ff0cc061SDimitry Andric return std::make_pair(Ctor, InitFunction); 175ff0cc061SDimitry Andric } 176d88c1a5aSDimitry Andric 177d88c1a5aSDimitry Andric void llvm::filterDeadComdatFunctions( 178d88c1a5aSDimitry Andric Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) { 179d88c1a5aSDimitry Andric // Build a map from the comdat to the number of entries in that comdat we 180d88c1a5aSDimitry Andric // think are dead. If this fully covers the comdat group, then the entire 181d88c1a5aSDimitry Andric // group is dead. If we find another entry in the comdat group though, we'll 182d88c1a5aSDimitry Andric // have to preserve the whole group. 183d88c1a5aSDimitry Andric SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered; 184d88c1a5aSDimitry Andric for (Function *F : DeadComdatFunctions) { 185d88c1a5aSDimitry Andric Comdat *C = F->getComdat(); 186d88c1a5aSDimitry Andric assert(C && "Expected all input GVs to be in a comdat!"); 187d88c1a5aSDimitry Andric ComdatEntriesCovered[C] += 1; 188d88c1a5aSDimitry Andric } 189d88c1a5aSDimitry Andric 190d88c1a5aSDimitry Andric auto CheckComdat = [&](Comdat &C) { 191d88c1a5aSDimitry Andric auto CI = ComdatEntriesCovered.find(&C); 192d88c1a5aSDimitry Andric if (CI == ComdatEntriesCovered.end()) 193d88c1a5aSDimitry Andric return; 194d88c1a5aSDimitry Andric 195d88c1a5aSDimitry Andric // If this could have been covered by a dead entry, just subtract one to 196d88c1a5aSDimitry Andric // account for it. 197d88c1a5aSDimitry Andric if (CI->second > 0) { 198d88c1a5aSDimitry Andric CI->second -= 1; 199d88c1a5aSDimitry Andric return; 200d88c1a5aSDimitry Andric } 201d88c1a5aSDimitry Andric 202d88c1a5aSDimitry Andric // If we've already accounted for all the entries that were dead, the 203d88c1a5aSDimitry Andric // entire comdat is alive so remove it from the map. 204d88c1a5aSDimitry Andric ComdatEntriesCovered.erase(CI); 205d88c1a5aSDimitry Andric }; 206d88c1a5aSDimitry Andric 207d88c1a5aSDimitry Andric auto CheckAllComdats = [&] { 208d88c1a5aSDimitry Andric for (Function &F : M.functions()) 209d88c1a5aSDimitry Andric if (Comdat *C = F.getComdat()) { 210d88c1a5aSDimitry Andric CheckComdat(*C); 211d88c1a5aSDimitry Andric if (ComdatEntriesCovered.empty()) 212d88c1a5aSDimitry Andric return; 213d88c1a5aSDimitry Andric } 214d88c1a5aSDimitry Andric for (GlobalVariable &GV : M.globals()) 215d88c1a5aSDimitry Andric if (Comdat *C = GV.getComdat()) { 216d88c1a5aSDimitry Andric CheckComdat(*C); 217d88c1a5aSDimitry Andric if (ComdatEntriesCovered.empty()) 218d88c1a5aSDimitry Andric return; 219d88c1a5aSDimitry Andric } 220d88c1a5aSDimitry Andric for (GlobalAlias &GA : M.aliases()) 221d88c1a5aSDimitry Andric if (Comdat *C = GA.getComdat()) { 222d88c1a5aSDimitry Andric CheckComdat(*C); 223d88c1a5aSDimitry Andric if (ComdatEntriesCovered.empty()) 224d88c1a5aSDimitry Andric return; 225d88c1a5aSDimitry Andric } 226d88c1a5aSDimitry Andric }; 227d88c1a5aSDimitry Andric CheckAllComdats(); 228d88c1a5aSDimitry Andric 229d88c1a5aSDimitry Andric if (ComdatEntriesCovered.empty()) { 230d88c1a5aSDimitry Andric DeadComdatFunctions.clear(); 231d88c1a5aSDimitry Andric return; 232d88c1a5aSDimitry Andric } 233d88c1a5aSDimitry Andric 234d88c1a5aSDimitry Andric // Remove the entries that were not covering. 235d88c1a5aSDimitry Andric erase_if(DeadComdatFunctions, [&](GlobalValue *GV) { 236d88c1a5aSDimitry Andric return ComdatEntriesCovered.find(GV->getComdat()) == 237d88c1a5aSDimitry Andric ComdatEntriesCovered.end(); 238d88c1a5aSDimitry Andric }); 239d88c1a5aSDimitry Andric } 240f37b6182SDimitry Andric 241f37b6182SDimitry Andric std::string llvm::getUniqueModuleId(Module *M) { 242f37b6182SDimitry Andric MD5 Md5; 243f37b6182SDimitry Andric bool ExportsSymbols = false; 244f37b6182SDimitry Andric auto AddGlobal = [&](GlobalValue &GV) { 245f37b6182SDimitry Andric if (GV.isDeclaration() || GV.getName().startswith("llvm.") || 2462cab237bSDimitry Andric !GV.hasExternalLinkage() || GV.hasComdat()) 247f37b6182SDimitry Andric return; 248f37b6182SDimitry Andric ExportsSymbols = true; 249f37b6182SDimitry Andric Md5.update(GV.getName()); 250f37b6182SDimitry Andric Md5.update(ArrayRef<uint8_t>{0}); 251f37b6182SDimitry Andric }; 252f37b6182SDimitry Andric 253f37b6182SDimitry Andric for (auto &F : *M) 254f37b6182SDimitry Andric AddGlobal(F); 255f37b6182SDimitry Andric for (auto &GV : M->globals()) 256f37b6182SDimitry Andric AddGlobal(GV); 257f37b6182SDimitry Andric for (auto &GA : M->aliases()) 258f37b6182SDimitry Andric AddGlobal(GA); 259f37b6182SDimitry Andric for (auto &IF : M->ifuncs()) 260f37b6182SDimitry Andric AddGlobal(IF); 261f37b6182SDimitry Andric 262f37b6182SDimitry Andric if (!ExportsSymbols) 263f37b6182SDimitry Andric return ""; 264f37b6182SDimitry Andric 265f37b6182SDimitry Andric MD5::MD5Result R; 266f37b6182SDimitry Andric Md5.final(R); 267f37b6182SDimitry Andric 268f37b6182SDimitry Andric SmallString<32> Str; 269f37b6182SDimitry Andric MD5::stringifyResult(R, Str); 270f37b6182SDimitry Andric return ("$" + Str).str(); 271f37b6182SDimitry Andric } 272