24#define DEBUG_TYPE "moduleutils"
36 EltTy = cast<StructType>(GVCtor->getValueType()->getArrayElementType());
38 unsigned n =
Init->getNumOperands();
40 for (
unsigned i = 0; i != n; ++i)
43 GVCtor->eraseFromParent();
46 IRB.
getInt32Ty(), PointerType::get(FnTy,
F->getAddressSpace()),
85 for (
Use &Op : CA->operands())
86 Init.insert(cast<Constant>(Op));
98 for (
auto *V : Values)
132 if (!ShouldRemove(MaybeRemoved->stripPointerCasts()))
136 if (!NewInit.
empty()) {
156 if (!M.getModuleFlag(
"kcfi"))
162 LLVMContext::MD_kcfi_type,
168 if (
auto *MD = mdconst::extract_or_null<ConstantInt>(
169 M.getModuleFlag(
"kcfi-offset"))) {
170 if (
unsigned Offset = MD->getZExtValue())
171 F.addFnAttr(
"patchable-function-prefix", std::to_string(
Offset));
178 assert(!InitName.
empty() &&
"Expected init function name");
180 auto *FnTy = FunctionType::get(VoidTy, InitArgTypes,
false);
181 auto FnCallee = M.getOrInsertFunction(InitName, FnTy);
182 auto *Fn = cast<Function>(FnCallee.getCallee());
183 if (
Weak && Fn->isDeclaration())
184 Fn->setLinkage(Function::ExternalWeakLinkage);
206 assert(!InitName.
empty() &&
"Expected init function name");
208 "Sanitizer's init function expects different number of arguments");
220 auto *InitFn = cast<Function>(InitFunction.
getCallee());
222 PointerType::get(InitFn->getType(), InitFn->getAddressSpace());
233 if (!VersionCheckName.
empty()) {
235 VersionCheckName, FunctionType::get(IRB.
getVoidTy(), {},
false),
243 return std::make_pair(Ctor, InitFunction);
246std::pair<Function *, FunctionCallee>
252 assert(!CtorName.
empty() &&
"Expected ctor function name");
254 if (
Function *Ctor = M.getFunction(CtorName))
257 if (Ctor->arg_empty() ||
265 M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName,
Weak);
266 FunctionsCreatedCallback(Ctor, InitFunction);
267 return std::make_pair(Ctor, InitFunction);
274 for (
Function *
F : DeadComdatFunctions) {
282 for (
Comdat *
C : MaybeDeadComdats) {
284 auto *
F = dyn_cast<Function>(GO);
287 if (
all_of(
C->getUsers(), IsUserDead))
300 bool ExportsSymbols =
false;
302 if (GV.isDeclaration() || GV.getName().startswith(
"llvm.") ||
303 !GV.hasExternalLinkage() || GV.hasComdat())
305 ExportsSymbols =
true;
312 for (
auto &GV : M->globals())
314 for (
auto &GA : M->aliases())
316 for (
auto &IF : M->ifuncs())
327 return (
"." + Str).str();
332 if (VariantMappings.
empty())
337 for (
const std::string &VariantMapping : VariantMappings)
338 Out << VariantMapping <<
",";
345 for (
const std::string &VariantMapping : VariantMappings) {
346 LLVM_DEBUG(
dbgs() <<
"VFABI: adding mapping '" << VariantMapping <<
"'\n");
348 assert(
VI &&
"Cannot add an invalid VFABI name.");
349 assert(M->getNamedValue(
VI->VectorName) &&
350 "Cannot add variant to attribute: "
351 "vector function declaration is missing.");
365 ModuleConstant,
"llvm.embedded.object");
370 NamedMDNode *MD = M.getOrInsertNamedMetadata(
"llvm.embedded.objects");
384 if (FilteredIFuncsToLower.
empty()) {
387 IFuncsToLower = AllIFuncs;
390 bool UnhandledUsers =
false;
397 : PointerType::get(Ctx,
DL.getProgramAddressSpace());
400 ArrayType::get(TableEntryTy, IFuncsToLower.
size());
402 Align PtrAlign =
DL.getABITypeAlign(TableEntryTy);
409 GlobalVariable::NotThreadLocal,
DL.getDefaultGlobalsAddressSpace());
410 FuncPtrTable->setAlignment(PtrAlign);
414 FunctionType::get(
Type::getVoidTy(Ctx),
false), Function::InternalLinkage,
415 DL.getProgramAddressSpace(),
"", &M);
420 size_t TableIndex = 0;
422 Function *ResolvedFunction = GI->getResolverFunction();
430 << ResolvedFunction->
getName() <<
" with parameters\n");
431 UnhandledUsers =
true;
439 FuncPtrTableTy, FuncPtrTable, 0, TableIndex++));
448 UnhandledUsers =
true;
455 Value *ResolvedCast =
462 GI->eraseFromParent();
469 : PointerType::get(Ctx, 0);
473 const int Priority = 10;
476 return UnhandledUsers;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void appendToUsedList(Module &M, StringRef Name, ArrayRef< GlobalValue * > Values)
static void collectUsedGlobals(GlobalVariable *GV, SmallSetVector< Constant *, 16 > &Init)
static void removeFromUsedList(Module &M, StringRef Name, function_ref< bool(Constant *)> ShouldRemove)
static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F, int Priority, Constant *Data)
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
Class to represent array types.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
This class represents a function call, abstracting a target machine's calling convention.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
ArrayRef< Type * > params() const
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const BasicBlock & getEntryBlock() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags applied.
StringRef getSection() const
Get the custom section of this global if it has one.
void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
void setSection(StringRef S)
Change the section for this global.
ThreadLocalMode getThreadLocalMode() const
unsigned getAddressSpace() const
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
@ AppendingLinkage
Special purpose, only applies to global arrays.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Value * CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name="")
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This is an important class for using LLVM in a threaded context.
bool supportsTypedPointers() const
Whether typed pointers are supported. If false, all pointers are opaque.
An instruction for reading from memory.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
static void stringifyResult(MD5Result &Result, SmallVectorImpl< char > &Str)
Translates the bytes in Res to a hex string that is deposited into Str.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
ConstantAsMetadata * createConstant(Constant *C)
Return the given constant as metadata.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDString * get(LLVMContext &Context, StringRef Str)
size_t getBufferSize() const
const char * getBufferStart() const
A Module instance is used to store all the information related to an LLVM module.
void addOperand(MDNode *M)
Class to represent pointers.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Class to represent struct types.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
unsigned getNumElements() const
Random access to the elements.
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static IntegerType * getInt32Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void setName(const Twine &Name)
Change the name of the value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an SmallVector or SmallString.
@ C
The default llvm calling convention, compatible with C.
std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const Module &M)
Function to construct a VFInfo out of a mangled names in the following format:
void setVectorVariantNames(CallInst *CI, ArrayRef< std::string > VariantMappings)
Overwrite the Vector Function ABI variants attribute with the names provide in VariantMappings.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Function * createSanitizerCtor(Module &M, StringRef CtorName)
Creates sanitizer constructor function.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type * > InitArgTypes, bool Weak=false)
std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
std::pair< Function *, FunctionCallee > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void removeFromUsedLists(Module &M, function_ref< bool(Constant *)> ShouldRemove)
Removes global values from the llvm.used and llvm.compiler.used arrays.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
void setKCFIType(Module &M, Function &F, StringRef MangledType)
Sets the KCFI type for the function.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void filterDeadComdatFunctions(SmallVectorImpl< Function * > &DeadComdatFunctions)
Filter out potentially dead comdat functions where other entries keep the entire comdat group alive.
void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName, Align Alignment=Align(1))
Embed the memory buffer Buf into the module M as a global using the specified section name.
bool lowerGlobalIFuncUsersAsGlobalCtor(Module &M, ArrayRef< GlobalIFunc * > IFuncsToLower={})
Lower all calls to ifuncs by replacing uses with indirect calls loaded out of a global table initiali...
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
uint64_t xxHash64(llvm::StringRef Data)
This struct is a compact representation of a valid (non-zero power of two) alignment.