51 #define DEBUG_TYPE "hwasan" 57 "__hwasan_shadow_memory_dynamic_address";
70 "hwasan-memory-access-callback-prefix",
76 cl::desc(
"instrument reads and writes with callbacks"),
80 cl::desc(
"instrument read instructions"),
84 "hwasan-instrument-writes",
cl::desc(
"instrument write instructions"),
88 "hwasan-instrument-atomics",
94 cl::desc(
"Enable recovery mode (continue-after-error)."),
98 cl::desc(
"instrument stack (allocas)"),
102 "hwasan-uar-retag-to-zero",
103 cl::desc(
"Clear alloca tags before returning from the function to allow " 104 "non-instrumented and instrumented function calls mix. When set " 105 "to false, allocas are retagged before returning from the " 106 "function to detect use after return."),
110 "hwasan-generate-tags-with-calls",
115 "hwasan-match-all-tag",
116 cl::desc(
"don't report bad accesses via pointers with this tag"),
121 cl::desc(
"Enable KernelHWAddressSanitizer instrumentation"),
129 "hwasan-mapping-offset",
135 cl::desc(
"Access dynamic shadow through an ifunc global on " 136 "platforms that support this"),
141 cl::desc(
"Access dynamic shadow through an thread-local pointer on " 142 "platforms that support this"),
147 cl::desc(
"Record stack frames with tagged allocations " 148 "in a thread-local ring buffer"),
152 cl::desc(
"create static frame descriptions"),
157 cl::desc(
"instrument memory intrinsics"),
168 explicit HWAddressSanitizer(
bool CompileKernel =
false,
bool Recover =
false)
175 StringRef getPassName()
const override {
return "HWAddressSanitizer"; }
178 bool doInitialization(
Module &M)
override;
180 void initializeCallbacks(
Module &M);
186 void instrumentMemAccessInline(
Value *PtrLong,
bool IsWrite,
187 unsigned AccessSizeIndex,
192 uint64_t *TypeSize,
unsigned *Alignment,
195 bool isInterestingAlloca(
const AllocaInst &AI);
212 std::string CurModuleUniqueId;
214 Function *HWAsanMemmove, *HWAsanMemcpy, *HWAsanMemset;
221 void createFrameGlobal(
Function &
F,
const std::string &FrameString);
223 const char *getFrameSection() {
return "__hwasan_frames"; }
224 const char *getFrameSectionBeg() {
return "__start___hwasan_frames"; }
225 const char *getFrameSectionEnd() {
return "__stop___hwasan_frames"; }
242 struct ShadowMapping {
249 unsigned getAllocaAlignment()
const {
return 1U << Scale; }
251 ShadowMapping Mapping;
263 Function *HwasanMemoryAccessCallbackSized[2];
271 Value *LocalDynamicShadow =
nullptr;
280 HWAddressSanitizer,
"hwasan",
281 "HWAddressSanitizer: detect memory bugs using tagged addressing.",
false,
285 "HWAddressSanitizer: detect memory bugs using tagged addressing.",
false,
290 assert(!CompileKernel || Recover);
291 return new HWAddressSanitizer(CompileKernel, Recover);
297 bool HWAddressSanitizer::doInitialization(
Module &M) {
303 Mapping.init(TargetTriple);
312 HwasanCtorFunction =
nullptr;
313 if (!CompileKernel) {
314 std::tie(HwasanCtorFunction, std::ignore) =
320 HwasanCtorFunction->setComdat(CtorComdat);
333 GV->setSection(getFrameSection());
334 GV->setComdat(CtorComdat);
337 IRBuilder<> IRBCtor(HwasanCtorFunction->getEntryBlock().getTerminator());
340 {Int8PtrTy, Int8PtrTy}),
341 {createFrameSectionBound(M, Int8Ty, getFrameSectionBeg()),
342 createFrameSectionBound(M, Int8Ty, getFrameSectionEnd())});
345 if (!TargetTriple.isAndroid())
354 void HWAddressSanitizer::initializeCallbacks(
Module &M) {
356 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
357 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
358 const std::string EndingStr = Recover ?
"_noabort" :
"";
360 HwasanMemoryAccessCallbackSized[AccessIsWrite] =
367 HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
370 itostr(1ULL << AccessSizeIndex) + EndingStr,
376 "__hwasan_tag_memory", IRB.
getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy));
380 if (Mapping.InGlobal)
384 const std::string MemIntrinCallbackPrefix =
387 MemIntrinCallbackPrefix +
"memmove", IRB.
getInt8PtrTy(),
405 if (Mapping.InGlobal) {
412 return IRB.
CreateCall(Asm, {ShadowGlobal},
".hwasan.shadow");
414 Value *GlobalDynamicAddress =
416 kHwasanShadowMemoryDynamicAddress, IntptrTy);
430 if (LocalDynamicShadow == I)
433 Value *PtrOperand =
nullptr;
435 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
439 *Alignment = LI->getAlignment();
440 PtrOperand = LI->getPointerOperand();
441 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(I)) {
445 *Alignment =
SI->getAlignment();
446 PtrOperand =
SI->getPointerOperand();
447 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
452 PtrOperand = RMW->getPointerOperand();
458 PtrOperand = XCHG->getPointerOperand();
480 if (
LoadInst *LI = dyn_cast<LoadInst>(I))
481 return LI->getPointerOperandIndex();
483 return SI->getPointerOperandIndex();
485 return RMW->getPointerOperandIndex();
487 return XCHG->getPointerOperandIndex();
499 if (TargetTriple.isAArch64())
512 if (Mapping.Offset == 0)
516 if (LocalDynamicShadow)
517 ShadowBase = LocalDynamicShadow;
520 return IRB.
CreateAdd(Shadow, ShadowBase);
523 void HWAddressSanitizer::instrumentMemAccessInline(
Value *PtrLong,
bool IsWrite,
524 unsigned AccessSizeIndex,
529 Value *AddrLong = untagPointer(IRB, PtrLong);
530 Value *ShadowLong = memToShadow(AddrLong, PtrLong->
getType(), IRB);
536 if (matchAllTag != -1) {
539 TagMismatch = IRB.
CreateAnd(TagMismatch, TagNotIgnored);
547 const int64_t AccessInfo = Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex;
549 switch (TargetTriple.getArch()) {
554 "int3\nnopl " +
itostr(0x40 + AccessInfo) +
"(%rax)",
563 "brk #" +
itostr(0x900 + AccessInfo),
573 void HWAddressSanitizer::instrumentMemIntrinsic(
MemIntrinsic *
MI) {
575 if (isa<MemTransferInst>(MI)) {
577 isa<MemMoveInst>(MI) ? HWAsanMemmove : HWAsanMemcpy,
581 }
else if (isa<MemSetInst>(MI)) {
591 bool HWAddressSanitizer::instrumentMemAccess(
Instruction *I) {
593 bool IsWrite =
false;
594 unsigned Alignment = 0;
595 uint64_t TypeSize = 0;
596 Value *MaybeMask =
nullptr;
599 instrumentMemIntrinsic(cast<MemIntrinsic>(I));
604 isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask);
616 (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 ||
617 Alignment >= TypeSize / 8)) {
620 IRB.
CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex],
623 instrumentMemAccessInline(AddrLong, IsWrite, AccessSizeIndex, I);
626 IRB.
CreateCall(HwasanMemoryAccessCallbackSized[IsWrite],
629 untagPointerOperand(I, Addr);
635 uint64_t ArraySize = 1;
638 assert(CI &&
"non-constant array size");
643 return SizeInBytes * ArraySize;
649 ~(Mapping.getAllocaAlignment() - 1);
657 size_t ShadowSize = Size >> Mapping.Scale;
677 static unsigned FastMasks[] = {
678 0, 1, 2, 3, 4, 6, 7, 8, 12, 14, 15, 16, 24,
679 28, 30, 31, 32, 48, 56, 60, 62, 63, 64, 96, 112, 120,
680 124, 126, 127, 128, 192, 224, 240, 248, 252, 254};
681 return FastMasks[AllocaNo % (
sizeof(FastMasks) /
sizeof(FastMasks[0]))];
690 return getNextTagWithCall(IRB);
694 auto GetStackPointerFn =
705 "hwasan.stack.base.tag");
712 return getNextTagWithCall(IRB);
721 return getNextTagWithCall(IRB);
728 Value *TaggedPtrLong;
734 TaggedPtrLong = IRB.
CreateAnd(PtrLong, ShiftedTag);
738 TaggedPtrLong = IRB.
CreateOr(PtrLong, ShiftedTag);
745 Value *UntaggedPtrLong;
748 UntaggedPtrLong = IRB.
CreateOr(PtrLong,
755 return UntaggedPtrLong;
760 if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) {
771 return ThreadPtrGlobal;
782 std::ostringstream Descr;
783 for (
auto AI : Allocas)
790 void HWAddressSanitizer::createFrameGlobal(
Function &
F,
791 const std::string &FrameString) {
799 GV->setSection(getFrameSection());
808 bool WithFrameRecord) {
810 return getDynamicShadowNonTls(IRB);
812 Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
819 Value *ThreadLongEqZero =
822 ThreadLongEqZero, cast<Instruction>(ThreadLongEqZero)->getNextNode(),
835 ThreadLong = ThreadLongPhi;
839 Value *ThreadLongMaybeUntagged =
840 TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong);
842 if (WithFrameRecord) {
845 auto GetStackPointerFn =
849 {Constant::getNullValue(IRB.getInt32Ty())}),
861 IRB.
CreateIntToPtr(ThreadLongMaybeUntagged, IntptrTy->getPointerTo(0));
884 ThreadLongMaybeUntagged,
890 bool HWAddressSanitizer::instrumentStack(
898 for (
unsigned N = 0;
N < Allocas.
size(); ++
N) {
899 auto *AI = Allocas[
N];
903 Value *Tag = getAllocaTag(IRB, StackTag, AI,
N);
908 Replacement->
setName(Name +
".hwasan");
916 tagAlloca(IRB, AI, Tag);
918 for (
auto RI : RetVec) {
922 Value *Tag = getUARTag(IRB, StackTag);
923 tagAlloca(IRB, AI, Tag);
930 bool HWAddressSanitizer::isInterestingAlloca(
const AllocaInst &AI) {
947 if (&F == HwasanCtorFunction)
959 for (
auto &Inst : BB) {
961 if (
AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
967 if (isInterestingAlloca(*AI))
972 if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst) ||
973 isa<CleanupReturnInst>(Inst))
976 Value *MaybeMask =
nullptr;
980 Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
981 &Alignment, &MaybeMask);
982 if (Addr || isa<MemIntrinsic>(Inst))
983 ToInstrument.push_back(&Inst);
987 if (AllocasToInstrument.
empty() && ToInstrument.empty())
991 createFrameGlobal(F, createFrameString(AllocasToInstrument));
993 initializeCallbacks(*F.getParent());
995 assert(!LocalDynamicShadow);
997 Instruction *InsertPt = &*F.getEntryBlock().begin();
999 LocalDynamicShadow = emitPrologue(EntryIRB,
1001 !AllocasToInstrument.
empty());
1003 bool Changed =
false;
1004 if (!AllocasToInstrument.
empty()) {
1007 Changed |= instrumentStack(AllocasToInstrument, RetVec, StackTag);
1010 for (
auto Inst : ToInstrument)
1011 Changed |= instrumentMemAccess(Inst);
1013 LocalDynamicShadow =
nullptr;
static cl::opt< int > ClMatchAllTag("hwasan-match-all-tag", cl::desc("don't report bad accesses via pointers with this tag"), cl::Hidden, cl::init(-1))
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue *> Values)
Adds global values to the llvm.compiler.used list.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Value * CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name="")
Function * declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type *> InitArgTypes)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Function * checkSanitizerInterfaceFunction(Constant *FuncOrBitcast)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
A Module instance is used to store all the information related to an LLVM module. ...
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
void setAlignment(unsigned Align)
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
static cl::opt< bool > ClRecover("hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
void push_back(const T &Elt)
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
Like Internal, but omit from symbol table.
Externally visible function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
StringRef getName() const
Get a short "name" for the module.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
An instruction for reading from memory.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
static const char *const kHwasanInitName
static unsigned getPointerOperandIndex(Instruction *I)
static const size_t kDefaultShadowScale
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static const char *const kHwasanShadowMemoryDynamicAddress
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
LLVMContext & getContext() const
Get the global data context.
static cl::opt< bool > ClInstrumentWrites("hwasan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
A Use represents the edge between a Value definition and its users.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
IntegerType * getIntPtrTy(const DataLayout &DL, unsigned AddrSpace=0)
Fetch the type representing a pointer to an integer value.
This file contains the simple types necessary to represent the attributes associated with functions a...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void setName(const Twine &Name)
Change the name of the value.
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Type * getType() const
All values are typed, get the type of this value.
std::string itostr(int64_t X)
bool isSwiftError() const
Return true if this value is a swifterror value.
BasicBlock * GetInsertBlock() const
static const unsigned kShadowBaseAlignment
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static const unsigned kPointerTagShift
An instruction for storing to memory.
static cl::opt< bool > ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics", cl::desc("instrument memory intrinsics"), cl::Hidden, cl::init(true))
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Value * getOperand(unsigned i) const
static cl::opt< bool > ClInstrumentStack("hwasan-instrument-stack", cl::desc("instrument stack (allocas)"), cl::Hidden, cl::init(true))
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
The instances of the Type class are immutable: once they are created, they are never changed...
std::pair< Function *, Function * > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type *> InitArgTypes, ArrayRef< Value *> InitArgs, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function, and calls sanitizer's init function from it.
This is an important class for using LLVM in a threaded context.
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("hwasan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__hwasan_"))
This is an important base class in LLVM.
INITIALIZE_PASS_BEGIN(HWAddressSanitizer, "hwasan", "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, false) INITIALIZE_PASS_END(HWAddressSanitizer
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< bool > ClGenerateTagsWithCalls("hwasan-generate-tags-with-calls", cl::desc("generate new tags with runtime library calls"), cl::Hidden, cl::init(false))
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClInstrumentAtomics("hwasan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
FunctionPass class - This class is used to implement most global optimizations.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Constant * get(StructType *T, ArrayRef< Constant *> V)
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
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...
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
const Value * getArraySize() const
Get the number of elements allocated.
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Triple - Helper class for working with autoconf configuration names.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
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.
GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, const char *NamePrefix="")
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 setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Comdat * GetOrCreateFunctionComdat(Function &F, Triple &T, const std::string &ModuleId)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
static cl::opt< bool > ClWithTls("hwasan-with-tls", cl::desc("Access dynamic shadow through an thread-local pointer on " "platforms that support this"), cl::Hidden, cl::init(true))
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
static cl::opt< bool > ClEnableKhwasan("hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
Constant * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
LLVM_NODISCARD bool empty() const
StringRef getValueAsString() const
Return the attribute's value as a string.
static const uint64_t kDynamicShadowSentinel
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
static unsigned RetagMask(unsigned AllocaNo)
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
static cl::opt< bool > ClRecordStackHistory("hwasan-record-stack-history", cl::desc("Record stack frames with tagged allocations " "in a thread-local ring buffer"), cl::Hidden, cl::init(true))
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
static cl::opt< bool > ClWithIfunc("hwasan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInstrumentWithCalls("hwasan-instrument-with-calls", cl::desc("instrument reads and writes with callbacks"), cl::Hidden, cl::init(false))
FunctionPass * createHWAddressSanitizerPass(bool CompileKernel=false, bool Recover=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
static cl::opt< bool > ClCreateFrameDescriptions("hwasan-create-frame-descriptions", cl::desc("create static frame descriptions"), cl::Hidden, cl::init(true))
static uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
bool isArrayAllocation() const
Return true if there is an allocation size parameter to the allocation instruction that is not 1...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
StringRef - Represent a constant reference to a string, i.e.
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
static cl::opt< unsigned long long > ClMappingOffset("hwasan-mapping-offset", cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
static const char *const kHwasanModuleCtorName
PointerType * getType() const
Global values are always pointers.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
static cl::opt< bool > ClUARRetagToZero("hwasan-uar-retag-to-zero", cl::desc("Clear alloca tags before returning from the function to allow " "non-instrumented and instrumented function calls mix. When set " "to false, allocas are retagged before returning from the " "function to detect use after return."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentReads("hwasan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))