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 21 using namespace llvm; 22 23 static void appendToGlobalArray(const char *Array, Module &M, Function *F, 24 int Priority, Constant *Data) { 25 IRBuilder<> IRB(M.getContext()); 26 FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); 27 28 // Get the current set of static global constructors and add the new ctor 29 // to the list. 30 SmallVector<Constant *, 16> CurrentCtors; 31 StructType *EltTy = StructType::get( 32 IRB.getInt32Ty(), PointerType::getUnqual(FnTy), IRB.getInt8PtrTy()); 33 if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { 34 if (Constant *Init = GVCtor->getInitializer()) { 35 unsigned n = Init->getNumOperands(); 36 CurrentCtors.reserve(n + 1); 37 for (unsigned i = 0; i != n; ++i) 38 CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); 39 } 40 GVCtor->eraseFromParent(); 41 } 42 43 // Build a 3 field global_ctor entry. We don't take a comdat key. 44 Constant *CSVals[3]; 45 CSVals[0] = IRB.getInt32(Priority); 46 CSVals[1] = F; 47 CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) 48 : Constant::getNullValue(IRB.getInt8PtrTy()); 49 Constant *RuntimeCtorInit = 50 ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); 51 52 CurrentCtors.push_back(RuntimeCtorInit); 53 54 // Create a new initializer. 55 ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size()); 56 Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 57 58 // Create the new global variable and replace all uses of 59 // the old global variable with the new one. 60 (void)new GlobalVariable(M, NewInit->getType(), false, 61 GlobalValue::AppendingLinkage, NewInit, Array); 62 } 63 64 void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) { 65 appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data); 66 } 67 68 void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) { 69 appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); 70 } 71 72 static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) { 73 GlobalVariable *GV = M.getGlobalVariable(Name); 74 SmallPtrSet<Constant *, 16> InitAsSet; 75 SmallVector<Constant *, 16> Init; 76 if (GV) { 77 auto *CA = cast<ConstantArray>(GV->getInitializer()); 78 for (auto &Op : CA->operands()) { 79 Constant *C = cast_or_null<Constant>(Op); 80 if (InitAsSet.insert(C).second) 81 Init.push_back(C); 82 } 83 GV->eraseFromParent(); 84 } 85 86 Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); 87 for (auto *V : Values) { 88 Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy); 89 if (InitAsSet.insert(C).second) 90 Init.push_back(C); 91 } 92 93 if (Init.empty()) 94 return; 95 96 ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); 97 GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, 98 ConstantArray::get(ATy, Init), Name); 99 GV->setSection("llvm.metadata"); 100 } 101 102 void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { 103 appendToUsedList(M, "llvm.used", Values); 104 } 105 106 void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { 107 appendToUsedList(M, "llvm.compiler.used", Values); 108 } 109 110 FunctionCallee 111 llvm::declareSanitizerInitFunction(Module &M, StringRef InitName, 112 ArrayRef<Type *> InitArgTypes) { 113 assert(!InitName.empty() && "Expected init function name"); 114 return M.getOrInsertFunction( 115 InitName, 116 FunctionType::get(Type::getVoidTy(M.getContext()), InitArgTypes, false), 117 AttributeList()); 118 } 119 120 std::pair<Function *, FunctionCallee> llvm::createSanitizerCtorAndInitFunctions( 121 Module &M, StringRef CtorName, StringRef InitName, 122 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 123 StringRef VersionCheckName) { 124 assert(!InitName.empty() && "Expected init function name"); 125 assert(InitArgs.size() == InitArgTypes.size() && 126 "Sanitizer's init function expects different number of arguments"); 127 FunctionCallee InitFunction = 128 declareSanitizerInitFunction(M, InitName, InitArgTypes); 129 Function *Ctor = Function::Create( 130 FunctionType::get(Type::getVoidTy(M.getContext()), false), 131 GlobalValue::InternalLinkage, CtorName, &M); 132 BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor); 133 IRBuilder<> IRB(ReturnInst::Create(M.getContext(), CtorBB)); 134 IRB.CreateCall(InitFunction, InitArgs); 135 if (!VersionCheckName.empty()) { 136 FunctionCallee VersionCheckFunction = M.getOrInsertFunction( 137 VersionCheckName, FunctionType::get(IRB.getVoidTy(), {}, false), 138 AttributeList()); 139 IRB.CreateCall(VersionCheckFunction, {}); 140 } 141 return std::make_pair(Ctor, InitFunction); 142 } 143 144 std::pair<Function *, FunctionCallee> 145 llvm::getOrCreateSanitizerCtorAndInitFunctions( 146 Module &M, StringRef CtorName, StringRef InitName, 147 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 148 function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback, 149 StringRef VersionCheckName) { 150 assert(!CtorName.empty() && "Expected ctor function name"); 151 152 if (Function *Ctor = M.getFunction(CtorName)) 153 // FIXME: Sink this logic into the module, similar to the handling of 154 // globals. This will make moving to a concurrent model much easier. 155 if (Ctor->arg_size() == 0 || 156 Ctor->getReturnType() == Type::getVoidTy(M.getContext())) 157 return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)}; 158 159 Function *Ctor; 160 FunctionCallee InitFunction; 161 std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions( 162 M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName); 163 FunctionsCreatedCallback(Ctor, InitFunction); 164 return std::make_pair(Ctor, InitFunction); 165 } 166 167 Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) { 168 assert(!Name.empty() && "Expected init function name"); 169 if (Function *F = M.getFunction(Name)) { 170 if (F->arg_size() != 0 || 171 F->getReturnType() != Type::getVoidTy(M.getContext())) { 172 std::string Err; 173 raw_string_ostream Stream(Err); 174 Stream << "Sanitizer interface function defined with wrong type: " << *F; 175 report_fatal_error(Err); 176 } 177 return F; 178 } 179 Function *F = 180 cast<Function>(M.getOrInsertFunction(Name, AttributeList(), 181 Type::getVoidTy(M.getContext())) 182 .getCallee()); 183 184 appendToGlobalCtors(M, F, 0); 185 186 return F; 187 } 188 189 void llvm::filterDeadComdatFunctions( 190 Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions) { 191 // Build a map from the comdat to the number of entries in that comdat we 192 // think are dead. If this fully covers the comdat group, then the entire 193 // group is dead. If we find another entry in the comdat group though, we'll 194 // have to preserve the whole group. 195 SmallDenseMap<Comdat *, int, 16> ComdatEntriesCovered; 196 for (Function *F : DeadComdatFunctions) { 197 Comdat *C = F->getComdat(); 198 assert(C && "Expected all input GVs to be in a comdat!"); 199 ComdatEntriesCovered[C] += 1; 200 } 201 202 auto CheckComdat = [&](Comdat &C) { 203 auto CI = ComdatEntriesCovered.find(&C); 204 if (CI == ComdatEntriesCovered.end()) 205 return; 206 207 // If this could have been covered by a dead entry, just subtract one to 208 // account for it. 209 if (CI->second > 0) { 210 CI->second -= 1; 211 return; 212 } 213 214 // If we've already accounted for all the entries that were dead, the 215 // entire comdat is alive so remove it from the map. 216 ComdatEntriesCovered.erase(CI); 217 }; 218 219 auto CheckAllComdats = [&] { 220 for (Function &F : M.functions()) 221 if (Comdat *C = F.getComdat()) { 222 CheckComdat(*C); 223 if (ComdatEntriesCovered.empty()) 224 return; 225 } 226 for (GlobalVariable &GV : M.globals()) 227 if (Comdat *C = GV.getComdat()) { 228 CheckComdat(*C); 229 if (ComdatEntriesCovered.empty()) 230 return; 231 } 232 for (GlobalAlias &GA : M.aliases()) 233 if (Comdat *C = GA.getComdat()) { 234 CheckComdat(*C); 235 if (ComdatEntriesCovered.empty()) 236 return; 237 } 238 }; 239 CheckAllComdats(); 240 241 if (ComdatEntriesCovered.empty()) { 242 DeadComdatFunctions.clear(); 243 return; 244 } 245 246 // Remove the entries that were not covering. 247 erase_if(DeadComdatFunctions, [&](GlobalValue *GV) { 248 return ComdatEntriesCovered.find(GV->getComdat()) == 249 ComdatEntriesCovered.end(); 250 }); 251 } 252 253 std::string llvm::getUniqueModuleId(Module *M) { 254 MD5 Md5; 255 bool ExportsSymbols = false; 256 auto AddGlobal = [&](GlobalValue &GV) { 257 if (GV.isDeclaration() || GV.getName().startswith("llvm.") || 258 !GV.hasExternalLinkage() || GV.hasComdat()) 259 return; 260 ExportsSymbols = true; 261 Md5.update(GV.getName()); 262 Md5.update(ArrayRef<uint8_t>{0}); 263 }; 264 265 for (auto &F : *M) 266 AddGlobal(F); 267 for (auto &GV : M->globals()) 268 AddGlobal(GV); 269 for (auto &GA : M->aliases()) 270 AddGlobal(GA); 271 for (auto &IF : M->ifuncs()) 272 AddGlobal(IF); 273 274 if (!ExportsSymbols) 275 return ""; 276 277 MD5::MD5Result R; 278 Md5.final(R); 279 280 SmallString<32> Str; 281 MD5::stringifyResult(R, Str); 282 return ("$" + Str).str(); 283 } 284 285 void VFABI::setVectorVariantNames( 286 CallInst *CI, const SmallVector<std::string, 8> &VariantMappings) { 287 if (VariantMappings.empty()) 288 return; 289 290 SmallString<256> Buffer; 291 llvm::raw_svector_ostream Out(Buffer); 292 for (const std::string &VariantMapping : VariantMappings) 293 Out << VariantMapping << ","; 294 // Get rid of the trailing ','. 295 assert(!Buffer.str().empty() && "Must have at least one char."); 296 Buffer.pop_back(); 297 298 Module *M = CI->getModule(); 299 #ifndef NDEBUG 300 for (const std::string &VariantMapping : VariantMappings) { 301 Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping); 302 assert(VI.hasValue() && "Canno add an invalid VFABI name."); 303 assert(M->getNamedValue(VI.getValue().VectorName) && 304 "Cannot add variant to attribute: " 305 "vector function declaration is missing."); 306 } 307 #endif 308 CI->addAttribute( 309 AttributeList::FunctionIndex, 310 Attribute::get(M->getContext(), MappingsAttrName, Buffer.str())); 311 } 312