109467b48Spatrick //===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This family of functions perform manipulations on Modules. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #include "llvm/Transforms/Utils/ModuleUtils.h" 14*097a140dSpatrick #include "llvm/Analysis/TargetLibraryInfo.h" 1509467b48Spatrick #include "llvm/Analysis/VectorUtils.h" 1609467b48Spatrick #include "llvm/IR/DerivedTypes.h" 1709467b48Spatrick #include "llvm/IR/Function.h" 1809467b48Spatrick #include "llvm/IR/IRBuilder.h" 1909467b48Spatrick #include "llvm/IR/Module.h" 2009467b48Spatrick #include "llvm/Support/raw_ostream.h" 2109467b48Spatrick using namespace llvm; 2209467b48Spatrick 23*097a140dSpatrick #define DEBUG_TYPE "moduleutils" 24*097a140dSpatrick 2509467b48Spatrick static void appendToGlobalArray(const char *Array, Module &M, Function *F, 2609467b48Spatrick int Priority, Constant *Data) { 2709467b48Spatrick IRBuilder<> IRB(M.getContext()); 2809467b48Spatrick FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); 2909467b48Spatrick 3009467b48Spatrick // Get the current set of static global constructors and add the new ctor 3109467b48Spatrick // to the list. 3209467b48Spatrick SmallVector<Constant *, 16> CurrentCtors; 3309467b48Spatrick StructType *EltTy = StructType::get( 3409467b48Spatrick IRB.getInt32Ty(), PointerType::getUnqual(FnTy), IRB.getInt8PtrTy()); 3509467b48Spatrick if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { 3609467b48Spatrick if (Constant *Init = GVCtor->getInitializer()) { 3709467b48Spatrick unsigned n = Init->getNumOperands(); 3809467b48Spatrick CurrentCtors.reserve(n + 1); 3909467b48Spatrick for (unsigned i = 0; i != n; ++i) 4009467b48Spatrick CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); 4109467b48Spatrick } 4209467b48Spatrick GVCtor->eraseFromParent(); 4309467b48Spatrick } 4409467b48Spatrick 4509467b48Spatrick // Build a 3 field global_ctor entry. We don't take a comdat key. 4609467b48Spatrick Constant *CSVals[3]; 4709467b48Spatrick CSVals[0] = IRB.getInt32(Priority); 4809467b48Spatrick CSVals[1] = F; 4909467b48Spatrick CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) 5009467b48Spatrick : Constant::getNullValue(IRB.getInt8PtrTy()); 5109467b48Spatrick Constant *RuntimeCtorInit = 5209467b48Spatrick ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); 5309467b48Spatrick 5409467b48Spatrick CurrentCtors.push_back(RuntimeCtorInit); 5509467b48Spatrick 5609467b48Spatrick // Create a new initializer. 5709467b48Spatrick ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size()); 5809467b48Spatrick Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 5909467b48Spatrick 6009467b48Spatrick // Create the new global variable and replace all uses of 6109467b48Spatrick // the old global variable with the new one. 6209467b48Spatrick (void)new GlobalVariable(M, NewInit->getType(), false, 6309467b48Spatrick GlobalValue::AppendingLinkage, NewInit, Array); 6409467b48Spatrick } 6509467b48Spatrick 6609467b48Spatrick void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) { 6709467b48Spatrick appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data); 6809467b48Spatrick } 6909467b48Spatrick 7009467b48Spatrick void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) { 7109467b48Spatrick appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); 7209467b48Spatrick } 7309467b48Spatrick 7409467b48Spatrick static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) { 7509467b48Spatrick GlobalVariable *GV = M.getGlobalVariable(Name); 7609467b48Spatrick SmallPtrSet<Constant *, 16> InitAsSet; 7709467b48Spatrick SmallVector<Constant *, 16> Init; 7809467b48Spatrick if (GV) { 7909467b48Spatrick auto *CA = cast<ConstantArray>(GV->getInitializer()); 8009467b48Spatrick for (auto &Op : CA->operands()) { 8109467b48Spatrick Constant *C = cast_or_null<Constant>(Op); 8209467b48Spatrick if (InitAsSet.insert(C).second) 8309467b48Spatrick Init.push_back(C); 8409467b48Spatrick } 8509467b48Spatrick GV->eraseFromParent(); 8609467b48Spatrick } 8709467b48Spatrick 8809467b48Spatrick Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); 8909467b48Spatrick for (auto *V : Values) { 9009467b48Spatrick Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy); 9109467b48Spatrick if (InitAsSet.insert(C).second) 9209467b48Spatrick Init.push_back(C); 9309467b48Spatrick } 9409467b48Spatrick 9509467b48Spatrick if (Init.empty()) 9609467b48Spatrick return; 9709467b48Spatrick 9809467b48Spatrick ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); 9909467b48Spatrick GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, 10009467b48Spatrick ConstantArray::get(ATy, Init), Name); 10109467b48Spatrick GV->setSection("llvm.metadata"); 10209467b48Spatrick } 10309467b48Spatrick 10409467b48Spatrick void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { 10509467b48Spatrick appendToUsedList(M, "llvm.used", Values); 10609467b48Spatrick } 10709467b48Spatrick 10809467b48Spatrick void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { 10909467b48Spatrick appendToUsedList(M, "llvm.compiler.used", Values); 11009467b48Spatrick } 11109467b48Spatrick 11209467b48Spatrick FunctionCallee 11309467b48Spatrick llvm::declareSanitizerInitFunction(Module &M, StringRef InitName, 11409467b48Spatrick ArrayRef<Type *> InitArgTypes) { 11509467b48Spatrick assert(!InitName.empty() && "Expected init function name"); 11609467b48Spatrick return M.getOrInsertFunction( 11709467b48Spatrick InitName, 11809467b48Spatrick FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false), 11909467b48Spatrick AttributeList()); 12009467b48Spatrick } 12109467b48Spatrick 122*097a140dSpatrick Function *llvm::createSanitizerCtor(Module &M, StringRef CtorName) { 123*097a140dSpatrick Function *Ctor = Function::Create( 124*097a140dSpatrick FunctionType::get(Type::getVoidTy(M.getContext()), false), 125*097a140dSpatrick GlobalValue::InternalLinkage, CtorName, &M); 126*097a140dSpatrick BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 127*097a140dSpatrick ReturnInst::Create(M.getContext(), CtorBB); 128*097a140dSpatrick return Ctor; 129*097a140dSpatrick } 130*097a140dSpatrick 13109467b48Spatrick std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions( 13209467b48Spatrick Module &M, StringRef CtorName, StringRef InitName, 13309467b48Spatrick ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 13409467b48Spatrick StringRef VersionCheckName) { 13509467b48Spatrick assert(!InitName.empty() && "Expected init function name"); 13609467b48Spatrick assert(InitArgs.size() == InitArgTypes.size() && 13709467b48Spatrick "Sanitizer's init function expects different number of arguments"); 13809467b48Spatrick FunctionCallee InitFunction = 13909467b48Spatrick declareSanitizerInitFunction(M, InitName, InitArgTypes); 140*097a140dSpatrick Function *Ctor = createSanitizerCtor(M, CtorName); 141*097a140dSpatrick IRBuilder<> IRB(Ctor->getEntryBlock().getTerminator()); 14209467b48Spatrick IRB.CreateCall(InitFunction, InitArgs); 14309467b48Spatrick if (!VersionCheckName.empty()) { 14409467b48Spatrick FunctionCallee VersionCheckFunction = M.getOrInsertFunction( 14509467b48Spatrick VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 14609467b48Spatrick AttributeList()); 14709467b48Spatrick IRB.CreateCall(VersionCheckFunction, {}); 14809467b48Spatrick } 14909467b48Spatrick return std::make_pair(Ctor, InitFunction); 15009467b48Spatrick } 15109467b48Spatrick 15209467b48Spatrick std::pair<Function *, FunctionCallee> 15309467b48Spatrick llvm::getOrCreateSanitizerCtorAndInitFunctions( 15409467b48Spatrick Module &M, StringRef CtorName, StringRef InitName, 15509467b48Spatrick ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 15609467b48Spatrick function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback, 15709467b48Spatrick StringRef VersionCheckName) { 15809467b48Spatrick assert(!CtorName.empty() && "Expected ctor function name"); 15909467b48Spatrick 16009467b48Spatrick if (Function *Ctor = M.getFunction(CtorName)) 16109467b48Spatrick // FIXME: Sink this logic into the module, similar to the handling of 16209467b48Spatrick // globals. This will make moving to a concurrent model much easier. 16309467b48Spatrick if (Ctor->arg_size() == 0 || 16409467b48Spatrick Ctor->getReturnType() == Type::getVoidTy(M.getContext())) 16509467b48Spatrick return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)}; 16609467b48Spatrick 16709467b48Spatrick Function *Ctor; 16809467b48Spatrick FunctionCallee InitFunction; 16909467b48Spatrick std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions( 17009467b48Spatrick M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName); 17109467b48Spatrick FunctionsCreatedCallback(Ctor, InitFunction); 17209467b48Spatrick return std::make_pair(Ctor, InitFunction); 17309467b48Spatrick } 17409467b48Spatrick 17509467b48Spatrick Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) { 17609467b48Spatrick assert(!Name.empty() && "Expected init function name"); 17709467b48Spatrick if (Function *F = M.getFunction(Name)) { 17809467b48Spatrick if (F->arg_size() != 0 || 17909467b48Spatrick F->getReturnType() != Type::getVoidTy(M.getContext())) { 18009467b48Spatrick std::string Err; 18109467b48Spatrick raw_string_ostream Stream(Err); 18209467b48Spatrick Stream << "Sanitizer interface function defined with wrong type: " << *F; 18309467b48Spatrick report_fatal_error(Err); 18409467b48Spatrick } 18509467b48Spatrick return F; 18609467b48Spatrick } 18709467b48Spatrick Function *F = 18809467b48Spatrick cast<Function>(M.getOrInsertFunction(Name, AttributeList(), 18909467b48Spatrick Type::getVoidTy(M.getContext())) 19009467b48Spatrick .getCallee()); 19109467b48Spatrick 19209467b48Spatrick appendToGlobalCtors(M, F, 0); 19309467b48Spatrick 19409467b48Spatrick return F; 19509467b48Spatrick } 19609467b48Spatrick 19709467b48Spatrick void llvm::filterDeadComdatFunctions( 19809467b48Spatrick Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) { 19909467b48Spatrick // Build a map from the comdat to the number of entries in that comdat we 20009467b48Spatrick // think are dead. If this fully covers the comdat group, then the entire 20109467b48Spatrick // group is dead. If we find another entry in the comdat group though, we'll 20209467b48Spatrick // have to preserve the whole group. 20309467b48Spatrick SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered; 20409467b48Spatrick for (Function *F : DeadComdatFunctions) { 20509467b48Spatrick Comdat *C = F->getComdat(); 20609467b48Spatrick assert(C && "Expected all input GVs to be in a comdat!"); 20709467b48Spatrick ComdatEntriesCovered[C] += 1; 20809467b48Spatrick } 20909467b48Spatrick 21009467b48Spatrick auto CheckComdat = [&](Comdat &C) { 21109467b48Spatrick auto CI = ComdatEntriesCovered.find(&C); 21209467b48Spatrick if (CI == ComdatEntriesCovered.end()) 21309467b48Spatrick return; 21409467b48Spatrick 21509467b48Spatrick // If this could have been covered by a dead entry, just subtract one to 21609467b48Spatrick // account for it. 21709467b48Spatrick if (CI->second > 0) { 21809467b48Spatrick CI->second -= 1; 21909467b48Spatrick return; 22009467b48Spatrick } 22109467b48Spatrick 22209467b48Spatrick // If we've already accounted for all the entries that were dead, the 22309467b48Spatrick // entire comdat is alive so remove it from the map. 22409467b48Spatrick ComdatEntriesCovered.erase(CI); 22509467b48Spatrick }; 22609467b48Spatrick 22709467b48Spatrick auto CheckAllComdats = [&] { 22809467b48Spatrick for (Function &F : M.functions()) 22909467b48Spatrick if (Comdat *C = F.getComdat()) { 23009467b48Spatrick CheckComdat(*C); 23109467b48Spatrick if (ComdatEntriesCovered.empty()) 23209467b48Spatrick return; 23309467b48Spatrick } 23409467b48Spatrick for (GlobalVariable &GV : M.globals()) 23509467b48Spatrick if (Comdat *C = GV.getComdat()) { 23609467b48Spatrick CheckComdat(*C); 23709467b48Spatrick if (ComdatEntriesCovered.empty()) 23809467b48Spatrick return; 23909467b48Spatrick } 24009467b48Spatrick for (GlobalAlias &GA : M.aliases()) 24109467b48Spatrick if (Comdat *C = GA.getComdat()) { 24209467b48Spatrick CheckComdat(*C); 24309467b48Spatrick if (ComdatEntriesCovered.empty()) 24409467b48Spatrick return; 24509467b48Spatrick } 24609467b48Spatrick }; 24709467b48Spatrick CheckAllComdats(); 24809467b48Spatrick 24909467b48Spatrick if (ComdatEntriesCovered.empty()) { 25009467b48Spatrick DeadComdatFunctions.clear(); 25109467b48Spatrick return; 25209467b48Spatrick } 25309467b48Spatrick 25409467b48Spatrick // Remove the entries that were not covering. 25509467b48Spatrick erase_if(DeadComdatFunctions, [&](GlobalValue *GV) { 25609467b48Spatrick return ComdatEntriesCovered.find(GV->getComdat()) == 25709467b48Spatrick ComdatEntriesCovered.end(); 25809467b48Spatrick }); 25909467b48Spatrick } 26009467b48Spatrick 26109467b48Spatrick std::string llvm::getUniqueModuleId(Module *M) { 26209467b48Spatrick MD5 Md5; 26309467b48Spatrick bool ExportsSymbols = false; 26409467b48Spatrick auto AddGlobal = [&](GlobalValue &GV) { 26509467b48Spatrick if (GV.isDeclaration() || GV.getName().startswith("llvm.") || 26609467b48Spatrick !GV.hasExternalLinkage() || GV.hasComdat()) 26709467b48Spatrick return; 26809467b48Spatrick ExportsSymbols = true; 26909467b48Spatrick Md5.update(GV.getName()); 27009467b48Spatrick Md5.update(ArrayRef<uint8_t>{0}); 27109467b48Spatrick }; 27209467b48Spatrick 27309467b48Spatrick for (auto &F : *M) 27409467b48Spatrick AddGlobal(F); 27509467b48Spatrick for (auto &GV : M->globals()) 27609467b48Spatrick AddGlobal(GV); 27709467b48Spatrick for (auto &GA : M->aliases()) 27809467b48Spatrick AddGlobal(GA); 27909467b48Spatrick for (auto &IF : M->ifuncs()) 28009467b48Spatrick AddGlobal(IF); 28109467b48Spatrick 28209467b48Spatrick if (!ExportsSymbols) 28309467b48Spatrick return ""; 28409467b48Spatrick 28509467b48Spatrick MD5::MD5Result R; 28609467b48Spatrick Md5.final(R); 28709467b48Spatrick 28809467b48Spatrick SmallString<32> Str; 28909467b48Spatrick MD5::stringifyResult(R, Str); 29009467b48Spatrick return ("$" + Str).str(); 29109467b48Spatrick } 29209467b48Spatrick 29309467b48Spatrick void VFABI::setVectorVariantNames( 29409467b48Spatrick CallInst *CI, const SmallVector<std::string, 8> &VariantMappings) { 29509467b48Spatrick if (VariantMappings.empty()) 29609467b48Spatrick return; 29709467b48Spatrick 29809467b48Spatrick SmallString<256> Buffer; 29909467b48Spatrick llvm::raw_svector_ostream Out(Buffer); 30009467b48Spatrick for (const std::string &VariantMapping : VariantMappings) 30109467b48Spatrick Out << VariantMapping << ","; 30209467b48Spatrick // Get rid of the trailing ','. 30309467b48Spatrick assert(!Buffer.str().empty() && "Must have at least one char."); 30409467b48Spatrick Buffer.pop_back(); 30509467b48Spatrick 30609467b48Spatrick Module *M = CI->getModule(); 30709467b48Spatrick #ifndef NDEBUG 30809467b48Spatrick for (const std::string &VariantMapping : VariantMappings) { 309*097a140dSpatrick LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n"); 310*097a140dSpatrick Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping, *M); 311*097a140dSpatrick assert(VI.hasValue() && "Cannot add an invalid VFABI name."); 31209467b48Spatrick assert(M->getNamedValue(VI.getValue().VectorName) && 31309467b48Spatrick "Cannot add variant to attribute: " 31409467b48Spatrick "vector function declaration is missing."); 31509467b48Spatrick } 31609467b48Spatrick #endif 31709467b48Spatrick CI->addAttribute( 31809467b48Spatrick AttributeList::FunctionIndex, 31909467b48Spatrick Attribute::get(M->getContext(), MappingsAttrName, Buffer.str())); 32009467b48Spatrick } 321