1 //===-- ModuleUtils.h - Functions to manipulate Modules ---------*- C++ -*-===// 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 #ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H 14 #define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H 15 16 #include "llvm/ADT/STLFunctionalExtras.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/IR/GlobalIFunc.h" 19 #include "llvm/Support/Alignment.h" 20 #include "llvm/Support/MemoryBufferRef.h" 21 #include <utility> // for std::pair 22 23 namespace llvm { 24 template <typename T> class SmallVectorImpl; 25 26 template <typename T> class ArrayRef; 27 class Module; 28 class Function; 29 class FunctionCallee; 30 class GlobalIFunc; 31 class GlobalValue; 32 class Constant; 33 class ConstantStruct; 34 class Value; 35 class Type; 36 37 /// Append F to the list of global ctors of module M with the given Priority. 38 /// This wraps the function in the appropriate structure and stores it along 39 /// side other global constructors. For details see 40 /// https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable 41 void appendToGlobalCtors(Module &M, Function *F, int Priority, 42 Constant *Data = nullptr); 43 44 /// Same as appendToGlobalCtors(), but for global dtors. 45 void appendToGlobalDtors(Module &M, Function *F, int Priority, 46 Constant *Data = nullptr); 47 48 /// Apply 'Fn' to the list of global ctors of module M and replace contructor 49 /// record with the one returned by `Fn`. If `nullptr` was returned, the 50 /// corresponding constructor will be removed from the array. For details see 51 /// https://llvm.org/docs/LangRef.html#the-llvm-global-ctors-global-variable 52 using GlobalCtorTransformFn = llvm::function_ref<Constant *(Constant *)>; 53 void transformGlobalCtors(Module &M, const GlobalCtorTransformFn &Fn); 54 void transformGlobalDtors(Module &M, const GlobalCtorTransformFn &Fn); 55 56 /// Sets the KCFI type for the function. Used for compiler-generated functions 57 /// that are indirectly called in instrumented code. 58 void setKCFIType(Module &M, Function &F, StringRef MangledType); 59 60 FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, 61 ArrayRef<Type *> InitArgTypes, 62 bool Weak = false); 63 64 /// Creates sanitizer constructor function. 65 /// \return Returns pointer to constructor. 66 Function *createSanitizerCtor(Module &M, StringRef CtorName); 67 68 /// Creates sanitizer constructor function, and calls sanitizer's init 69 /// function from it. 70 /// \return Returns pair of pointers to constructor, and init functions 71 /// respectively. 72 std::pair<Function *, FunctionCallee> createSanitizerCtorAndInitFunctions( 73 Module &M, StringRef CtorName, StringRef InitName, 74 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 75 StringRef VersionCheckName = StringRef(), bool Weak = false); 76 77 /// Creates sanitizer constructor function lazily. If a constructor and init 78 /// function already exist, this function returns it. Otherwise it calls \c 79 /// createSanitizerCtorAndInitFunctions. The FunctionsCreatedCallback is invoked 80 /// in that case, passing the new Ctor and Init function. 81 /// 82 /// \return Returns pair of pointers to constructor, and init functions 83 /// respectively. 84 std::pair<Function *, FunctionCallee> getOrCreateSanitizerCtorAndInitFunctions( 85 Module &M, StringRef CtorName, StringRef InitName, 86 ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs, 87 function_ref<void(Function *, FunctionCallee)> FunctionsCreatedCallback, 88 StringRef VersionCheckName = StringRef(), bool Weak = false); 89 90 /// Rename all the anon globals in the module using a hash computed from 91 /// the list of public globals in the module. 92 bool nameUnamedGlobals(Module &M); 93 94 /// Adds global values to the llvm.used list. 95 void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values); 96 97 /// Adds global values to the llvm.compiler.used list. 98 void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values); 99 100 /// Removes global values from the llvm.used and llvm.compiler.used arrays. \p 101 /// ShouldRemove should return true for any initializer field that should not be 102 /// included in the replacement global. 103 void removeFromUsedLists(Module &M, 104 function_ref<bool(Constant *)> ShouldRemove); 105 106 /// Filter out potentially dead comdat functions where other entries keep the 107 /// entire comdat group alive. 108 /// 109 /// This is designed for cases where functions appear to become dead but remain 110 /// alive due to other live entries in their comdat group. 111 /// 112 /// The \p DeadComdatFunctions container should only have pointers to 113 /// `Function`s which are members of a comdat group and are believed to be 114 /// dead. 115 /// 116 /// After this routine finishes, the only remaining `Function`s in \p 117 /// DeadComdatFunctions are those where every member of the comdat is listed 118 /// and thus removing them is safe (provided *all* are removed). 119 void filterDeadComdatFunctions( 120 SmallVectorImpl<Function *> &DeadComdatFunctions); 121 122 /// Produce a unique identifier for this module by taking the MD5 sum of 123 /// the names of the module's strong external symbols that are not comdat 124 /// members. 125 /// 126 /// This identifier is normally guaranteed to be unique, or the program would 127 /// fail to link due to multiply defined symbols. 128 /// 129 /// If the module has no strong external symbols (such a module may still have a 130 /// semantic effect if it performs global initialization), we cannot produce a 131 /// unique identifier for this module, so we return the empty string. 132 std::string getUniqueModuleId(Module *M); 133 134 /// Embed the memory buffer \p Buf into the module \p M as a global using the 135 /// specified section name. Also provide a metadata entry to identify it in the 136 /// module using the same section name. 137 void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName, 138 Align Alignment = Align(1)); 139 140 /// Lower all calls to ifuncs by replacing uses with indirect calls loaded out 141 /// of a global table initialized in a global constructor. This will introduce 142 /// one constructor function and adds it to llvm.global_ctors. The constructor 143 /// will call the resolver function once for each ifunc. 144 /// 145 /// Leaves any unhandled constant initializer uses as-is. 146 /// 147 /// If \p IFuncsToLower is empty, all ifuncs in the module will be lowered. 148 /// If \p IFuncsToLower is non-empty, only the selected ifuncs will be lowered. 149 /// 150 /// The processed ifuncs without remaining users will be removed from the 151 /// module. 152 bool lowerGlobalIFuncUsersAsGlobalCtor( 153 Module &M, ArrayRef<GlobalIFunc *> IFuncsToLower = {}); 154 155 } // End llvm namespace 156 157 #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H 158