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