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