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 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 GV->eraseFromParent(); 86 } 87 88 Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); 89 for (auto *V : Values) { 90 Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy); 91 if (InitAsSet.insert(C).second) 92 Init.push_back(C); 93 } 94 95 if (Init.empty()) 96 return; 97 98 ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); 99 GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, 100 ConstantArray::get(ATy, Init), Name); 101 GV->setSection("llvm.metadata"); 102 } 103 104 void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { 105 appendToUsedList(M, "llvm.used", Values); 106 } 107 108 void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { 109 appendToUsedList(M, "llvm.compiler.used", Values); 110 } 111 112 FunctionCallee 113 llvm::declareSanitizerInitFunction(Module &M, StringRef InitName, 114 ArrayRef<Type *> InitArgTypes) { 115 assert(!InitName.empty() && "Expected init function name"); 116 return M.getOrInsertFunction( 117 InitName, 118 FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false), 119 AttributeList()); 120 } 121 122 std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions( 123 Module &M, StringRef CtorName, StringRef InitName, 124 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 125 StringRef VersionCheckName) { 126 assert(!InitName.empty() && "Expected init function name"); 127 assert(InitArgs.size() == InitArgTypes.size() && 128 "Sanitizer's init function expects different number of arguments"); 129 FunctionCallee InitFunction = 130 declareSanitizerInitFunction(M, InitName, InitArgTypes); 131 Function *Ctor = Function::Create( 132 FunctionType::get(Type::getVoidTy(M.getContext()), false), 133 GlobalValue::InternalLinkage, CtorName, &M); 134 BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 135 IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); 136 IRB.CreateCall(InitFunction, InitArgs); 137 if (!VersionCheckName.empty()) { 138 FunctionCallee VersionCheckFunction = M.getOrInsertFunction( 139 VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 140 AttributeList()); 141 IRB.CreateCall(VersionCheckFunction, {}); 142 } 143 return std::make_pair(Ctor, InitFunction); 144 } 145 146 std::pair<Function *, FunctionCallee> 147 llvm::getOrCreateSanitizerCtorAndInitFunctions( 148 Module &M, StringRef CtorName, StringRef InitName, 149 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 150 function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback, 151 StringRef VersionCheckName) { 152 assert(!CtorName.empty() && "Expected ctor function name"); 153 154 if (Function *Ctor = M.getFunction(CtorName)) 155 // FIXME: Sink this logic into the module, similar to the handling of 156 // globals. This will make moving to a concurrent model much easier. 157 if (Ctor->arg_size() == 0 || 158 Ctor->getReturnType() == Type::getVoidTy(M.getContext())) 159 return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)}; 160 161 Function *Ctor; 162 FunctionCallee InitFunction; 163 std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions( 164 M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName); 165 FunctionsCreatedCallback(Ctor, InitFunction); 166 return std::make_pair(Ctor, InitFunction); 167 } 168 169 Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) { 170 assert(!Name.empty() && "Expected init function name"); 171 if (Function *F = M.getFunction(Name)) { 172 if (F->arg_size() != 0 || 173 F->getReturnType() != Type::getVoidTy(M.getContext())) { 174 std::string Err; 175 raw_string_ostream Stream(Err); 176 Stream << "Sanitizer interface function defined with wrong type: " << *F; 177 report_fatal_error(Err); 178 } 179 return F; 180 } 181 Function *F = 182 cast<Function>(M.getOrInsertFunction(Name, AttributeList(), 183 Type::getVoidTy(M.getContext())) 184 .getCallee()); 185 186 appendToGlobalCtors(M, F, 0); 187 188 return F; 189 } 190 191 void llvm::filterDeadComdatFunctions( 192 Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) { 193 // Build a map from the comdat to the number of entries in that comdat we 194 // think are dead. If this fully covers the comdat group, then the entire 195 // group is dead. If we find another entry in the comdat group though, we'll 196 // have to preserve the whole group. 197 SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered; 198 for (Function *F : DeadComdatFunctions) { 199 Comdat *C = F->getComdat(); 200 assert(C && "Expected all input GVs to be in a comdat!"); 201 ComdatEntriesCovered[C] += 1; 202 } 203 204 auto CheckComdat = [&](Comdat &C) { 205 auto CI = ComdatEntriesCovered.find(&C); 206 if (CI == ComdatEntriesCovered.end()) 207 return; 208 209 // If this could have been covered by a dead entry, just subtract one to 210 // account for it. 211 if (CI->second > 0) { 212 CI->second -= 1; 213 return; 214 } 215 216 // If we've already accounted for all the entries that were dead, the 217 // entire comdat is alive so remove it from the map. 218 ComdatEntriesCovered.erase(CI); 219 }; 220 221 auto CheckAllComdats = [&] { 222 for (Function &F : M.functions()) 223 if (Comdat *C = F.getComdat()) { 224 CheckComdat(*C); 225 if (ComdatEntriesCovered.empty()) 226 return; 227 } 228 for (GlobalVariable &GV : M.globals()) 229 if (Comdat *C = GV.getComdat()) { 230 CheckComdat(*C); 231 if (ComdatEntriesCovered.empty()) 232 return; 233 } 234 for (GlobalAlias &GA : M.aliases()) 235 if (Comdat *C = GA.getComdat()) { 236 CheckComdat(*C); 237 if (ComdatEntriesCovered.empty()) 238 return; 239 } 240 }; 241 CheckAllComdats(); 242 243 if (ComdatEntriesCovered.empty()) { 244 DeadComdatFunctions.clear(); 245 return; 246 } 247 248 // Remove the entries that were not covering. 249 erase_if(DeadComdatFunctions, [&](GlobalValue *GV) { 250 return ComdatEntriesCovered.find(GV->getComdat()) == 251 ComdatEntriesCovered.end(); 252 }); 253 } 254 255 std::string llvm::getUniqueModuleId(Module *M) { 256 MD5 Md5; 257 bool ExportsSymbols = false; 258 auto AddGlobal = [&](GlobalValue &GV) { 259 if (GV.isDeclaration() || GV.getName().startswith("llvm.") || 260 !GV.hasExternalLinkage() || GV.hasComdat()) 261 return; 262 ExportsSymbols = true; 263 Md5.update(GV.getName()); 264 Md5.update(ArrayRef<uint8_t>{0}); 265 }; 266 267 for (auto &F : *M) 268 AddGlobal(F); 269 for (auto &GV : M->globals()) 270 AddGlobal(GV); 271 for (auto &GA : M->aliases()) 272 AddGlobal(GA); 273 for (auto &IF : M->ifuncs()) 274 AddGlobal(IF); 275 276 if (!ExportsSymbols) 277 return ""; 278 279 MD5::MD5Result R; 280 Md5.final(R); 281 282 SmallString<32> Str; 283 MD5::stringifyResult(R, Str); 284 return ("$" + Str).str(); 285 } 286 287 void VFABI::setVectorVariantNames( 288 CallInst *CI, const SmallVector<std::string, 8> &VariantMappings) { 289 if (VariantMappings.empty()) 290 return; 291 292 SmallString<256> Buffer; 293 llvm::raw_svector_ostream Out(Buffer); 294 for (const std::string &VariantMapping : VariantMappings) 295 Out << VariantMapping << ","; 296 // Get rid of the trailing ','. 297 assert(!Buffer.str().empty() && "Must have at least one char."); 298 Buffer.pop_back(); 299 300 Module *M = CI->getModule(); 301 #ifndef NDEBUG 302 for (const std::string &VariantMapping : VariantMappings) { 303 LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n"); 304 Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping, *M); 305 assert(VI.hasValue() && "Cannot add an invalid VFABI name."); 306 assert(M->getNamedValue(VI.getValue().VectorName) && 307 "Cannot add variant to attribute: " 308 "vector function declaration is missing."); 309 } 310 #endif 311 CI->addAttribute( 312 AttributeList::FunctionIndex, 313 Attribute::get(M->getContext(), MappingsAttrName, Buffer.str())); 314 } 315