1 //===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This family of functions perform manipulations on Modules. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Transforms/Utils/ModuleUtils.h" 14 #include "llvm/Analysis/VectorUtils.h" 15 #include "llvm/IR/DerivedTypes.h" 16 #include "llvm/IR/Function.h" 17 #include "llvm/IR/IRBuilder.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/Support/raw_ostream.h" 20 using namespace llvm; 21 22 #define DEBUG_TYPE "moduleutils" 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 = StructType::get( 33 IRB.getInt32Ty(), PointerType::getUnqual(FnTy), IRB.getInt8PtrTy()); 34 if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { 35 if (Constant *Init = GVCtor->getInitializer()) { 36 unsigned n = Init->getNumOperands(); 37 CurrentCtors.reserve(n + 1); 38 for (unsigned i = 0; i != n; ++i) 39 CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); 40 } 41 GVCtor->eraseFromParent(); 42 } 43 44 // Build a 3 field global_ctor entry. We don't take a comdat key. 45 Constant *CSVals[3]; 46 CSVals[0] = IRB.getInt32(Priority); 47 CSVals[1] = F; 48 CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) 49 : Constant::getNullValue(IRB.getInt8PtrTy()); 50 Constant *RuntimeCtorInit = 51 ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); 52 53 CurrentCtors.push_back(RuntimeCtorInit); 54 55 // Create a new initializer. 56 ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size()); 57 Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 58 59 // Create the new global variable and replace all uses of 60 // the old global variable with the new one. 61 (void)new GlobalVariable(M, NewInit->getType(), false, 62 GlobalValue::AppendingLinkage, NewInit, Array); 63 } 64 65 void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) { 66 appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data); 67 } 68 69 void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) { 70 appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); 71 } 72 73 static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) { 74 GlobalVariable *GV = M.getGlobalVariable(Name); 75 SmallPtrSet<Constant *, 16> InitAsSet; 76 SmallVector<Constant *, 16> Init; 77 if (GV) { 78 if (GV->hasInitializer()) { 79 auto *CA = cast<ConstantArray>(GV->getInitializer()); 80 for (auto &Op : CA->operands()) { 81 Constant *C = cast_or_null<Constant>(Op); 82 if (InitAsSet.insert(C).second) 83 Init.push_back(C); 84 } 85 } 86 GV->eraseFromParent(); 87 } 88 89 Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); 90 for (auto *V : Values) { 91 Constant *C = ConstantExpr::getPointerBitCastOrAddrSpaceCast(V, Int8PtrTy); 92 if (InitAsSet.insert(C).second) 93 Init.push_back(C); 94 } 95 96 if (Init.empty()) 97 return; 98 99 ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); 100 GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, 101 ConstantArray::get(ATy, Init), Name); 102 GV->setSection("llvm.metadata"); 103 } 104 105 void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { 106 appendToUsedList(M, "llvm.used", Values); 107 } 108 109 void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { 110 appendToUsedList(M, "llvm.compiler.used", Values); 111 } 112 113 FunctionCallee 114 llvm::declareSanitizerInitFunction(Module &M, StringRef InitName, 115 ArrayRef<Type *> InitArgTypes) { 116 assert(!InitName.empty() && "Expected init function name"); 117 return M.getOrInsertFunction( 118 InitName, 119 FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false), 120 AttributeList()); 121 } 122 123 Function *llvm::createSanitizerCtor(Module &M, StringRef CtorName) { 124 Function *Ctor = Function::createWithDefaultAttr( 125 FunctionType::get(Type::getVoidTy(M.getContext()), false), 126 GlobalValue::InternalLinkage, 0, CtorName, &M); 127 Ctor->addFnAttr(Attribute::NoUnwind); 128 BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 129 ReturnInst::Create(M.getContext(), CtorBB); 130 // Ensure Ctor cannot be discarded, even if in a comdat. 131 appendToUsed(M, {Ctor}); 132 return Ctor; 133 } 134 135 std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions( 136 Module &M, StringRef CtorName, StringRef InitName, 137 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 138 StringRef VersionCheckName) { 139 assert(!InitName.empty() && "Expected init function name"); 140 assert(InitArgs.size() == InitArgTypes.size() && 141 "Sanitizer's init function expects different number of arguments"); 142 FunctionCallee InitFunction = 143 declareSanitizerInitFunction(M, InitName, InitArgTypes); 144 Function *Ctor = createSanitizerCtor(M, CtorName); 145 IRBuilder<> IRB(Ctor->getEntryBlock().getTerminator()); 146 IRB.CreateCall(InitFunction, InitArgs); 147 if (!VersionCheckName.empty()) { 148 FunctionCallee VersionCheckFunction = M.getOrInsertFunction( 149 VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 150 AttributeList()); 151 IRB.CreateCall(VersionCheckFunction, {}); 152 } 153 return std::make_pair(Ctor, InitFunction); 154 } 155 156 std::pair<Function *, FunctionCallee> 157 llvm::getOrCreateSanitizerCtorAndInitFunctions( 158 Module &M, StringRef CtorName, StringRef InitName, 159 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 160 function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback, 161 StringRef VersionCheckName) { 162 assert(!CtorName.empty() && "Expected ctor function name"); 163 164 if (Function *Ctor = M.getFunction(CtorName)) 165 // FIXME: Sink this logic into the module, similar to the handling of 166 // globals. This will make moving to a concurrent model much easier. 167 if (Ctor->arg_empty() || 168 Ctor->getReturnType() == Type::getVoidTy(M.getContext())) 169 return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)}; 170 171 Function *Ctor; 172 FunctionCallee InitFunction; 173 std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions( 174 M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName); 175 FunctionsCreatedCallback(Ctor, InitFunction); 176 return std::make_pair(Ctor, InitFunction); 177 } 178 179 void llvm::filterDeadComdatFunctions( 180 SmallVectorImpl<Function *> &DeadComdatFunctions) { 181 SmallPtrSet<Function *, 32> MaybeDeadFunctions; 182 SmallPtrSet<Comdat *, 32> MaybeDeadComdats; 183 for (Function *F : DeadComdatFunctions) { 184 MaybeDeadFunctions.insert(F); 185 if (Comdat *C = F->getComdat()) 186 MaybeDeadComdats.insert(C); 187 } 188 189 // Find comdats for which all users are dead now. 190 SmallPtrSet<Comdat *, 32> DeadComdats; 191 for (Comdat *C : MaybeDeadComdats) { 192 auto IsUserDead = [&](GlobalObject *GO) { 193 auto *F = dyn_cast<Function>(GO); 194 return F && MaybeDeadFunctions.contains(F); 195 }; 196 if (all_of(C->getUsers(), IsUserDead)) 197 DeadComdats.insert(C); 198 } 199 200 // Only keep functions which have no comdat or a dead comdat. 201 erase_if(DeadComdatFunctions, [&](Function *F) { 202 Comdat *C = F->getComdat(); 203 return C && !DeadComdats.contains(C); 204 }); 205 } 206 207 std::string llvm::getUniqueModuleId(Module *M) { 208 MD5 Md5; 209 bool ExportsSymbols = false; 210 auto AddGlobal = [&](GlobalValue &GV) { 211 if (GV.isDeclaration() || GV.getName().startswith("llvm.") || 212 !GV.hasExternalLinkage() || GV.hasComdat()) 213 return; 214 ExportsSymbols = true; 215 Md5.update(GV.getName()); 216 Md5.update(ArrayRef<uint8_t>{0}); 217 }; 218 219 for (auto &F : *M) 220 AddGlobal(F); 221 for (auto &GV : M->globals()) 222 AddGlobal(GV); 223 for (auto &GA : M->aliases()) 224 AddGlobal(GA); 225 for (auto &IF : M->ifuncs()) 226 AddGlobal(IF); 227 228 if (!ExportsSymbols) 229 return ""; 230 231 MD5::MD5Result R; 232 Md5.final(R); 233 234 SmallString<32> Str; 235 MD5::stringifyResult(R, Str); 236 return ("." + Str).str(); 237 } 238 239 void VFABI::setVectorVariantNames(CallInst *CI, 240 ArrayRef<std::string> VariantMappings) { 241 if (VariantMappings.empty()) 242 return; 243 244 SmallString<256> Buffer; 245 llvm::raw_svector_ostream Out(Buffer); 246 for (const std::string &VariantMapping : VariantMappings) 247 Out << VariantMapping << ","; 248 // Get rid of the trailing ','. 249 assert(!Buffer.str().empty() && "Must have at least one char."); 250 Buffer.pop_back(); 251 252 Module *M = CI->getModule(); 253 #ifndef NDEBUG 254 for (const std::string &VariantMapping : VariantMappings) { 255 LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n"); 256 Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping, *M); 257 assert(VI && "Cannot add an invalid VFABI name."); 258 assert(M->getNamedValue(VI.value().VectorName) && 259 "Cannot add variant to attribute: " 260 "vector function declaration is missing."); 261 } 262 #endif 263 CI->addFnAttr( 264 Attribute::get(M->getContext(), MappingsAttrName, Buffer.str())); 265 } 266 267 void llvm::embedBufferInModule(Module &M, MemoryBufferRef Buf, 268 StringRef SectionName, Align Alignment) { 269 // Embed the memory buffer into the module. 270 Constant *ModuleConstant = ConstantDataArray::get( 271 M.getContext(), makeArrayRef(Buf.getBufferStart(), Buf.getBufferSize())); 272 GlobalVariable *GV = new GlobalVariable( 273 M, ModuleConstant->getType(), true, GlobalValue::PrivateLinkage, 274 ModuleConstant, "llvm.embedded.object"); 275 GV->setSection(SectionName); 276 GV->setAlignment(Alignment); 277 278 LLVMContext &Ctx = M.getContext(); 279 NamedMDNode *MD = M.getOrInsertNamedMetadata("llvm.embedded.objects"); 280 Metadata *MDVals[] = {ConstantAsMetadata::get(GV), 281 MDString::get(Ctx, SectionName)}; 282 283 MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); 284 GV->setMetadata(LLVMContext::MD_exclude, llvm::MDNode::get(Ctx, {})); 285 286 appendToCompilerUsed(M, GV); 287 } 288