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