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