71#define DEBUG_TYPE "hwasan"
79 "__hwasan_shadow_memory_dynamic_address";
86 std::numeric_limits<uint64_t>::max();
92 cl::desc(
"Prefix for memory access callbacks"),
96 "hwasan-kernel-mem-intrinsic-prefix",
101 "hwasan-instrument-with-calls",
106 cl::desc(
"instrument read instructions"),
115 "hwasan-instrument-atomics",
120 cl::desc(
"instrument byval arguments"),
125 cl::desc(
"Enable recovery mode (continue-after-error)."),
129 cl::desc(
"instrument stack (allocas)"),
140 cl::desc(
"How many lifetime ends to handle for a single alloca."),
145 cl::desc(
"detect use after scope within function"),
149 "hwasan-generate-tags-with-calls",
157 "hwasan-match-all-tag",
158 cl::desc(
"don't report bad accesses via pointers with this tag"),
163 cl::desc(
"Enable KernelHWAddressSanitizer instrumentation"),
172 cl::desc(
"HWASan shadow mapping offset [EXPERIMENTAL]"),
177 cl::desc(
"Access dynamic shadow through an ifunc global on "
178 "platforms that support this"),
183 cl::desc(
"Access dynamic shadow through an thread-local pointer on "
184 "platforms that support this"),
188 cl::desc(
"Hot percentile cuttoff."));
192 cl::desc(
"Probability value in the range [0.0, 1.0] "
193 "to keep instrumentation of a function."));
196STATISTIC(NumInstrumentedFuncs,
"Number of instrumented funcs");
197STATISTIC(NumNoProfileSummaryFuncs,
"Number of funcs without PS");
214 "hwasan-record-stack-history",
215 cl::desc(
"Record stack frames with tagged allocations in a thread-local "
219 "storing into the stack ring buffer directly"),
221 "storing into the stack ring buffer")),
226 cl::desc(
"instrument memory intrinsics"),
235 "hwasan-use-short-granules",
240 "hwasan-instrument-personality-functions",
253 cl::desc(
"Use page aliasing in HWASan"),
262bool shouldUsePageAliases(
const Triple &TargetTriple) {
266bool shouldInstrumentStack(
const Triple &TargetTriple) {
270bool shouldInstrumentWithCalls(
const Triple &TargetTriple) {
274bool mightUseStackSafetyAnalysis(
bool DisableOptimization) {
278bool shouldUseStackSafetyAnalysis(
const Triple &TargetTriple,
279 bool DisableOptimization) {
280 return shouldInstrumentStack(TargetTriple) &&
281 mightUseStackSafetyAnalysis(DisableOptimization);
284bool shouldDetectUseAfterScope(
const Triple &TargetTriple) {
290class HWAddressSanitizer {
292 HWAddressSanitizer(
Module &M,
bool CompileKernel,
bool Recover,
295 this->Recover = optOr(
ClRecover, Recover);
306 struct ShadowTagCheckInfo {
308 Value *PtrLong =
nullptr;
309 Value *AddrLong =
nullptr;
310 Value *PtrTag =
nullptr;
311 Value *MemTag =
nullptr;
314 bool selectiveInstrumentationShouldSkip(
Function &
F,
316 void initializeModule();
317 void createHwasanCtorComdat();
319 void initializeCallbacks(
Module &M);
329 int64_t getAccessInfo(
bool IsWrite,
unsigned AccessSizeIndex);
332 void instrumentMemAccessOutline(
Value *
Ptr,
bool IsWrite,
333 unsigned AccessSizeIndex,
336 void instrumentMemAccessInline(
Value *
Ptr,
bool IsWrite,
337 unsigned AccessSizeIndex,
348 void getInterestingMemoryOperands(
367 unsigned retagMask(
unsigned AllocaNo);
369 void emitPrologue(
IRBuilder<> &IRB,
bool WithFrameRecord);
372 void instrumentGlobals();
377 void instrumentPersonalityFunctions();
383 std::unique_ptr<RandomNumberGenerator> Rng;
396 struct ShadowMapping {
401 bool WithFrameRecord;
403 void init(
Triple &TargetTriple,
bool InstrumentWithCalls);
404 Align getObjectAlignment()
const {
return Align(1ULL << Scale); }
407 ShadowMapping Mapping;
410 Type *IntptrTy =
M.getDataLayout().getIntPtrType(
M.getContext());
411 PointerType *PtrTy = PointerType::getUnqual(
M.getContext());
420 bool UseShortGranules;
421 bool InstrumentLandingPads;
422 bool InstrumentWithCalls;
423 bool InstrumentStack;
424 bool InstrumentGlobals;
425 bool DetectUseAfterScope;
427 bool UseMatchAllCallback;
429 std::optional<uint8_t> MatchAllTag;
431 unsigned PointerTagShift;
448 Value *ShadowBase =
nullptr;
449 Value *StackBaseTag =
nullptr;
450 Value *CachedFP =
nullptr;
466 HWASan.sanitizeFunction(
F,
FAM);
484 OS, MapClassName2PassName);
493void HWAddressSanitizer::createHwasanCtorComdat() {
494 std::tie(HwasanCtorFunction, std::ignore) =
543 nullptr,
"__start_hwasan_globals");
547 nullptr,
"__stop_hwasan_globals");
559 Note->setSection(
".note.hwasan.globals");
560 Note->setComdat(NoteComdat);
572 {ConstantInt::get(Int32Ty, 8),
573 ConstantInt::get(Int32Ty, 8),
575 Name, CreateRelPtr(Start), CreateRelPtr(Stop)}));
583 Dummy->setSection(
"hwasan_globals");
584 Dummy->setComdat(NoteComdat);
585 Dummy->setMetadata(LLVMContext::MD_associated,
593void HWAddressSanitizer::initializeModule() {
595 TargetTriple =
Triple(
M.getTargetTriple());
601 UsePageAliases = shouldUsePageAliases(TargetTriple);
602 InstrumentWithCalls = shouldInstrumentWithCalls(TargetTriple);
603 InstrumentStack = shouldInstrumentStack(TargetTriple);
604 DetectUseAfterScope = shouldDetectUseAfterScope(TargetTriple);
605 PointerTagShift = IsX86_64 ? 57 : 56;
606 TagMaskByte = IsX86_64 ? 0x3F : 0xFF;
608 Mapping.init(TargetTriple, InstrumentWithCalls);
610 C = &(
M.getContext());
613 HwasanCtorFunction =
nullptr;
634 }
else if (CompileKernel) {
637 UseMatchAllCallback = !CompileKernel && MatchAllTag.has_value();
643 !CompileKernel && !UsePageAliases && optOr(
ClGlobals, NewRuntime);
645 if (!CompileKernel) {
646 createHwasanCtorComdat();
648 if (InstrumentGlobals)
651 bool InstrumentPersonalityFunctions =
653 if (InstrumentPersonalityFunctions)
654 instrumentPersonalityFunctions();
658 Constant *
C =
M.getOrInsertGlobal(
"__hwasan_tls", IntptrTy, [&] {
661 "__hwasan_tls",
nullptr,
666 ThreadPtrGlobal = cast<GlobalVariable>(
C);
670void HWAddressSanitizer::initializeCallbacks(
Module &M) {
672 const std::string MatchAllStr = UseMatchAllCallback ?
"_match_all" :
"";
674 *HwasanMemoryAccessCallbackFnTy, *HwasanMemTransferFnTy,
676 if (UseMatchAllCallback) {
677 HwasanMemoryAccessCallbackSizedFnTy =
679 HwasanMemoryAccessCallbackFnTy =
681 HwasanMemTransferFnTy =
686 HwasanMemoryAccessCallbackSizedFnTy =
688 HwasanMemoryAccessCallbackFnTy =
690 HwasanMemTransferFnTy =
696 for (
size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
697 const std::string TypeStr = AccessIsWrite ?
"store" :
"load";
698 const std::string EndingStr = Recover ?
"_noabort" :
"";
700 HwasanMemoryAccessCallbackSized[AccessIsWrite] =
M.getOrInsertFunction(
702 HwasanMemoryAccessCallbackSizedFnTy);
706 HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
708 itostr(1ULL << AccessSizeIndex) +
709 MatchAllStr + EndingStr,
710 HwasanMemoryAccessCallbackFnTy);
714 const std::string MemIntrinCallbackPrefix =
719 HwasanMemmove =
M.getOrInsertFunction(
720 MemIntrinCallbackPrefix +
"memmove" + MatchAllStr, HwasanMemTransferFnTy);
721 HwasanMemcpy =
M.getOrInsertFunction(
722 MemIntrinCallbackPrefix +
"memcpy" + MatchAllStr, HwasanMemTransferFnTy);
723 HwasanMemset =
M.getOrInsertFunction(
724 MemIntrinCallbackPrefix +
"memset" + MatchAllStr, HwasanMemsetFnTy);
726 HwasanTagMemoryFunc =
M.getOrInsertFunction(
"__hwasan_tag_memory", VoidTy,
727 PtrTy, Int8Ty, IntptrTy);
728 HwasanGenerateTagFunc =
729 M.getOrInsertFunction(
"__hwasan_generate_tag", Int8Ty);
731 HwasanRecordFrameRecordFunc =
732 M.getOrInsertFunction(
"__hwasan_add_frame_record", VoidTy, Int64Ty);
738 M.getOrInsertFunction(
"__hwasan_handle_vfork", VoidTy, IntptrTy);
750 return IRB.
CreateCall(Asm, {Val},
".hwasan.shadow");
754 return getOpaqueNoopCast(IRB, ShadowGlobal);
759 return getOpaqueNoopCast(
761 ConstantInt::get(IntptrTy, Mapping.Offset), PtrTy));
763 if (Mapping.InGlobal)
764 return getDynamicShadowIfunc(IRB);
766 Value *GlobalDynamicAddress =
769 return IRB.
CreateLoad(PtrTy, GlobalDynamicAddress);
772bool HWAddressSanitizer::ignoreAccessWithoutRemark(
Instruction *Inst,
776 Type *PtrTy = cast<PointerType>(
Ptr->getType()->getScalarType());
784 if (
Ptr->isSwiftError())
788 if (!InstrumentStack)
795 if (!InstrumentGlobals)
805 bool Ignored = ignoreAccessWithoutRemark(Inst,
Ptr);
817void HWAddressSanitizer::getInterestingMemoryOperands(
822 if (
I->hasMetadata(LLVMContext::MD_nosanitize))
829 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
832 Interesting.
emplace_back(
I, LI->getPointerOperandIndex(),
false,
833 LI->getType(), LI->getAlign());
834 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
838 SI->getValueOperand()->getType(),
SI->getAlign());
842 Interesting.
emplace_back(
I, RMW->getPointerOperandIndex(),
true,
843 RMW->getValOperand()->getType(), std::nullopt);
847 Interesting.
emplace_back(
I, XCHG->getPointerOperandIndex(),
true,
848 XCHG->getCompareOperand()->getType(),
850 }
else if (
auto *CI = dyn_cast<CallInst>(
I)) {
851 for (
unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
853 ignoreAccess(ORE,
I, CI->getArgOperand(ArgNo)))
855 Type *Ty = CI->getParamByValType(ArgNo);
863 if (
LoadInst *LI = dyn_cast<LoadInst>(
I))
864 return LI->getPointerOperandIndex();
866 return SI->getPointerOperandIndex();
868 return RMW->getPointerOperandIndex();
870 return XCHG->getPointerOperandIndex();
896 if (Mapping.Offset == 0)
902int64_t HWAddressSanitizer::getAccessInfo(
bool IsWrite,
903 unsigned AccessSizeIndex) {
912HWAddressSanitizer::ShadowTagCheckInfo
915 ShadowTagCheckInfo
R;
922 R.AddrLong = untagPointer(IRB,
R.PtrLong);
923 Value *Shadow = memToShadow(
R.AddrLong, IRB);
927 if (MatchAllTag.has_value()) {
929 R.PtrTag, ConstantInt::get(
R.PtrTag->getType(), *MatchAllTag));
930 TagMismatch = IRB.
CreateAnd(TagMismatch, TagNotIgnored);
934 TagMismatch, InsertBefore,
false,
940void HWAddressSanitizer::instrumentMemAccessOutline(
Value *
Ptr,
bool IsWrite,
941 unsigned AccessSizeIndex,
946 const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
950 insertShadowTagCheck(
Ptr, InsertBefore, DTU, LI).TagMismatchTerm;
954 bool useFixedShadowIntrinsic =
false;
963 uint16_t offset_shifted = Mapping.Offset >> 32;
964 useFixedShadowIntrinsic = (
uint64_t)offset_shifted << 32 == Mapping.Offset;
967 if (useFixedShadowIntrinsic)
971 ? Intrinsic::hwasan_check_memaccess_shortgranules_fixedshadow
972 : Intrinsic::hwasan_check_memaccess_fixedshadow),
973 {
Ptr, ConstantInt::get(Int32Ty, AccessInfo),
974 ConstantInt::get(Int64Ty, Mapping.Offset)});
978 ? Intrinsic::hwasan_check_memaccess_shortgranules
979 : Intrinsic::hwasan_check_memaccess),
980 {ShadowBase,
Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
983void HWAddressSanitizer::instrumentMemAccessInline(
Value *
Ptr,
bool IsWrite,
984 unsigned AccessSizeIndex,
989 const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
991 ShadowTagCheckInfo TCI = insertShadowTagCheck(
Ptr, InsertBefore, DTU, LI);
994 Value *OutOfShortGranuleTagRange =
997 OutOfShortGranuleTagRange, TCI.TagMismatchTerm, !Recover,
1003 PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
1020 switch (TargetTriple.
getArch()) {
1044 "ebreak\naddiw x0, x11, " +
1054 cast<BranchInst>(CheckFailTerm)
1064 if (isa<MemSetInst>(
MI))
1069void HWAddressSanitizer::instrumentMemIntrinsic(
MemIntrinsic *
MI) {
1071 if (isa<MemTransferInst>(
MI)) {
1073 MI->getOperand(0),
MI->getOperand(1),
1076 if (UseMatchAllCallback)
1077 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1078 IRB.
CreateCall(isa<MemMoveInst>(
MI) ? HwasanMemmove : HwasanMemcpy, Args);
1079 }
else if (isa<MemSetInst>(
MI)) {
1084 if (UseMatchAllCallback)
1085 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1088 MI->eraseFromParent();
1102 if (!
O.TypeStoreSize.isScalable() &&
isPowerOf2_64(
O.TypeStoreSize) &&
1104 (!
O.Alignment || *
O.Alignment >= Mapping.getObjectAlignment() ||
1105 *
O.Alignment >=
O.TypeStoreSize / 8)) {
1107 if (InstrumentWithCalls) {
1109 if (UseMatchAllCallback)
1110 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1111 IRB.
CreateCall(HwasanMemoryAccessCallback[
O.IsWrite][AccessSizeIndex],
1113 }
else if (OutlinedChecks) {
1114 instrumentMemAccessOutline(
Addr,
O.IsWrite, AccessSizeIndex,
O.getInsn(),
1117 instrumentMemAccessInline(
Addr,
O.IsWrite, AccessSizeIndex,
O.getInsn(),
1124 ConstantInt::get(IntptrTy, 8))};
1125 if (UseMatchAllCallback)
1126 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1127 IRB.
CreateCall(HwasanMemoryAccessCallbackSized[
O.IsWrite], Args);
1129 untagPointerOperand(
O.getInsn(),
Addr);
1136 size_t AlignedSize =
alignTo(
Size, Mapping.getObjectAlignment());
1137 if (!UseShortGranules)
1141 if (InstrumentWithCalls) {
1144 ConstantInt::get(IntptrTy, AlignedSize)});
1146 size_t ShadowSize =
Size >> Mapping.Scale;
1148 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1157 if (
Size != AlignedSize) {
1158 const uint8_t SizeRemainder =
Size % Mapping.getObjectAlignment().value();
1159 IRB.
CreateStore(ConstantInt::get(Int8Ty, SizeRemainder),
1168unsigned HWAddressSanitizer::retagMask(
unsigned AllocaNo) {
1170 return AllocaNo & TagMaskByte;
1182 static const unsigned FastMasks[] = {
1183 0, 128, 64, 192, 32, 96, 224, 112, 240, 48, 16, 120,
1184 248, 56, 24, 8, 124, 252, 60, 28, 12, 4, 126, 254,
1185 62, 30, 14, 6, 2, 127, 63, 31, 15, 7, 3, 1};
1186 return FastMasks[AllocaNo % std::size(FastMasks)];
1190 if (TagMaskByte == 0xFF)
1193 ConstantInt::get(OldTag->
getType(), TagMaskByte));
1204 return StackBaseTag;
1208 Value *FramePointerLong = getCachedFP(IRB);
1210 applyTagMask(IRB, IRB.
CreateXor(FramePointerLong,
1212 StackTag->
setName(
"hwasan.stack.base.tag");
1217 unsigned AllocaNo) {
1219 return getNextTagWithCall(IRB);
1221 StackTag, ConstantInt::get(StackTag->
getType(), retagMask(AllocaNo)));
1225 Value *FramePointerLong = getCachedFP(IRB);
1227 applyTagMask(IRB, IRB.
CreateLShr(FramePointerLong, PointerTagShift));
1229 UARTag->
setName(
"hwasan.uar.tag");
1237 Value *TaggedPtrLong;
1238 if (CompileKernel) {
1242 ConstantInt::get(IntptrTy, (1ULL << PointerTagShift) - 1));
1243 TaggedPtrLong = IRB.
CreateAnd(PtrLong, ShiftedTag);
1247 TaggedPtrLong = IRB.
CreateOr(PtrLong, ShiftedTag);
1255 Value *UntaggedPtrLong;
1256 if (CompileKernel) {
1260 TagMaskByte << PointerTagShift));
1264 PtrLong, ConstantInt::get(PtrLong->
getType(),
1265 ~(TagMaskByte << PointerTagShift)));
1267 return UntaggedPtrLong;
1273 constexpr int SanitizerSlot = 6;
1276 return ThreadPtrGlobal;
1303void HWAddressSanitizer::emitPrologue(
IRBuilder<> &IRB,
bool WithFrameRecord) {
1305 ShadowBase = getShadowNonTls(IRB);
1306 else if (!WithFrameRecord && TargetTriple.
isAndroid())
1307 ShadowBase = getDynamicShadowIfunc(IRB);
1309 if (!WithFrameRecord && ShadowBase)
1312 Value *SlotPtr =
nullptr;
1313 Value *ThreadLong =
nullptr;
1314 Value *ThreadLongMaybeUntagged =
nullptr;
1316 auto getThreadLongMaybeUntagged = [&]() {
1318 SlotPtr = getHwasanThreadSlotPtr(IRB);
1320 ThreadLong = IRB.
CreateLoad(IntptrTy, SlotPtr);
1323 return TargetTriple.
isAArch64() ? ThreadLong
1324 : untagPointer(IRB, ThreadLong);
1327 if (WithFrameRecord) {
1332 Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1333 IRB.
CreateCall(HwasanRecordFrameRecordFunc, {FrameRecordInfo});
1337 ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1339 StackBaseTag = IRB.
CreateAShr(ThreadLong, 3);
1342 Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1372 ConstantInt::get(IntptrTy, (
uint64_t)-1));
1374 IRB.
CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask);
1380 "A stack history recording mode should've been selected.");
1386 if (!ThreadLongMaybeUntagged)
1387 ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1394 ThreadLongMaybeUntagged,
1396 ConstantInt::get(IntptrTy, 1),
"hwasan.shadow");
1401bool HWAddressSanitizer::instrumentLandingPads(
1403 for (
auto *LP : LandingPadVec) {
1404 IRBuilder<> IRB(LP->getNextNonDebugInstruction());
1427 auto *AI = KV.first;
1432 Value *
Tag = getAllocaTag(IRB, StackTag,
N);
1434 Value *AINoTagLong = untagPointer(IRB, AILong);
1435 Value *Replacement = tagPointer(IRB, AI->
getType(), AINoTagLong,
Tag);
1441 size_t AlignedSize =
alignTo(
Size, Mapping.getObjectAlignment());
1456 II->setArgOperand(0, ConstantInt::get(Int64Ty, AlignedSize));
1457 II->setArgOperand(1, AICast);
1463 auto *
User =
U.getUser();
1464 return User != AILong &&
User != AICast &&
1476 tagAlloca(IRB, AI, UARTag, AlignedSize);
1482 bool StandardLifetime =
1487 if (DetectUseAfterScope && StandardLifetime) {
1490 tagAlloca(IRB, AI,
Tag,
Size);
1493 for (
auto *
End :
Info.LifetimeEnd)
1494 End->eraseFromParent();
1497 tagAlloca(IRB, AI,
Tag,
Size);
1498 for (
auto *RI : SInfo.
RetVec)
1502 for (
auto &
II :
Info.LifetimeStart)
1503 II->eraseFromParent();
1504 for (
auto &
II :
Info.LifetimeEnd)
1505 II->eraseFromParent();
1510 I->eraseFromParent();
1519 <<
"Skipped: F=" <<
ore::NV(
"Function", &
F);
1524 <<
"Sanitized: F=" <<
ore::NV(
"Function", &
F);
1529bool HWAddressSanitizer::selectiveInstrumentationShouldSkip(
1541 if (!PSI || !PSI->hasProfileSummary()) {
1542 ++NumNoProfileSummaryFuncs;
1545 return PSI->isFunctionHotInCallGraphNthPercentile(
1552void HWAddressSanitizer::sanitizeFunction(
Function &
F,
1554 if (&
F == HwasanCtorFunction)
1557 if (!
F.hasFnAttribute(Attribute::SanitizeHWAddress))
1568 if (selectiveInstrumentationShouldSkip(
F,
FAM))
1571 NumInstrumentedFuncs++;
1582 if (InstrumentStack) {
1586 if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
1589 getInterestingMemoryOperands(ORE, &Inst, TLI, OperandsToInstrument);
1592 if (!ignoreMemIntrinsic(ORE,
MI))
1598 initializeCallbacks(*
F.getParent());
1600 if (!LandingPadVec.
empty())
1601 instrumentLandingPads(LandingPadVec);
1607 F.setPersonalityFn(
nullptr);
1611 IntrinToInstrument.
empty())
1620 F.removeFnAttr(llvm::Attribute::Memory);
1621 for (
auto &
A :
F.args())
1622 A.removeAttr(llvm::Attribute::WriteOnly);
1626 emitPrologue(EntryIRB,
1628 Mapping.WithFrameRecord &&
1635 Value *StackTag = getStackBaseTag(EntryIRB);
1636 Value *UARTag = getUARTag(EntryIRB);
1637 instrumentStack(SInfo, StackTag, UARTag, DT, PDT, LI);
1643 if (EntryIRB.GetInsertBlock() != &
F.getEntryBlock()) {
1644 InsertPt =
F.getEntryBlock().begin();
1647 if (
auto *AI = dyn_cast<AllocaInst>(&
I))
1649 I.moveBefore(
F.getEntryBlock(), InsertPt);
1656 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
1657 for (
auto &Operand : OperandsToInstrument)
1658 instrumentMemAccess(Operand, DTU, LI);
1662 for (
auto *Inst : IntrinToInstrument)
1663 instrumentMemIntrinsic(Inst);
1666 ShadowBase =
nullptr;
1667 StackBaseTag =
nullptr;
1675 M.getDataLayout().getTypeAllocSize(Initializer->
getType());
1676 uint64_t NewSize =
alignTo(SizeInBytes, Mapping.getObjectAlignment());
1677 if (SizeInBytes != NewSize) {
1680 std::vector<uint8_t>
Init(NewSize - SizeInBytes, 0);
1689 NewGV->copyAttributesFrom(GV);
1691 NewGV->copyMetadata(GV, 0);
1692 NewGV->setAlignment(
1712 const uint64_t MaxDescriptorSize = 0xfffff0;
1713 for (
uint64_t DescriptorPos = 0; DescriptorPos < SizeInBytes;
1714 DescriptorPos += MaxDescriptorSize) {
1717 nullptr, GV->
getName() +
".hwasan.descriptor");
1723 ConstantInt::get(Int64Ty, DescriptorPos)),
1725 uint32_t Size = std::min(SizeInBytes - DescriptorPos, MaxDescriptorSize);
1726 auto *SizeAndTag = ConstantInt::get(Int32Ty,
Size | (
uint32_t(
Tag) << 24));
1727 Descriptor->setComdat(NewGV->getComdat());
1729 Descriptor->setSection(
"hwasan_globals");
1730 Descriptor->setMetadata(LLVMContext::MD_associated,
1738 ConstantInt::get(Int64Ty,
uint64_t(
Tag) << PointerTagShift)),
1743 Alias->takeName(GV);
1748void HWAddressSanitizer::instrumentGlobals() {
1749 std::vector<GlobalVariable *> Globals;
1768 Globals.push_back(&GV);
1772 Hasher.
update(
M.getSourceFileName());
1775 uint8_t
Tag = Hash[0];
1777 assert(TagMaskByte >= 16);
1783 if (Tag < 16 || Tag > TagMaskByte)
1785 instrumentGlobal(GV,
Tag++);
1789void HWAddressSanitizer::instrumentPersonalityFunctions() {
1798 if (
F.isDeclaration() || !
F.hasFnAttribute(Attribute::SanitizeHWAddress))
1801 if (
F.hasPersonalityFn()) {
1802 PersonalityFns[
F.getPersonalityFn()->stripPointerCasts()].push_back(&
F);
1803 }
else if (!
F.hasFnAttribute(Attribute::NoUnwind)) {
1804 PersonalityFns[
nullptr].push_back(&
F);
1808 if (PersonalityFns.
empty())
1812 "__hwasan_personality_wrapper", Int32Ty, Int32Ty, Int32Ty, Int64Ty, PtrTy,
1813 PtrTy, PtrTy, PtrTy, PtrTy);
1814 FunctionCallee UnwindGetGR =
M.getOrInsertFunction(
"_Unwind_GetGR", VoidTy);
1815 FunctionCallee UnwindGetCFA =
M.getOrInsertFunction(
"_Unwind_GetCFA", VoidTy);
1817 for (
auto &
P : PersonalityFns) {
1820 ThunkName += (
"." +
P.first->getName()).str();
1822 Int32Ty, {Int32Ty, Int32Ty, Int64Ty, PtrTy, PtrTy},
false);
1823 bool IsLocal =
P.first && (!isa<GlobalValue>(
P.first) ||
1824 cast<GlobalValue>(
P.first)->hasLocalLinkage());
1831 ThunkFn->setComdat(
M.getOrInsertComdat(ThunkName));
1837 HwasanPersonalityWrapper,
1838 {ThunkFn->getArg(0), ThunkFn->getArg(1), ThunkFn->getArg(2),
1839 ThunkFn->getArg(3), ThunkFn->getArg(4),
1846 F->setPersonalityFn(ThunkFn);
1850void HWAddressSanitizer::ShadowMapping::init(
Triple &TargetTriple,
1851 bool InstrumentWithCalls) {
1859 WithFrameRecord =
true;
1864 WithFrameRecord =
false;
1869 WithFrameRecord =
false;
1874 WithFrameRecord =
false;
1879 WithFrameRecord =
true;
1884 WithFrameRecord =
false;
static cl::opt< size_t > ClMaxLifetimes("stack-tagging-max-lifetimes-for-alloca", cl::Hidden, cl::init(3), cl::ReallyHidden, cl::desc("How many lifetime ends to handle for a single alloca."), cl::Optional)
static cl::opt< StackTaggingRecordStackHistoryMode > ClRecordStackHistory("stack-tagging-record-stack-history", cl::desc("Record stack frames with tagged allocations in a thread-local " "ring buffer"), cl::values(clEnumVal(none, "Do not record stack ring history"), clEnumVal(instr, "Insert instructions into the prologue for " "storing into the stack ring buffer")), cl::Hidden, cl::init(none))
static const uint64_t kDefaultShadowScale
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("asan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__asan_"))
static cl::opt< bool > ClInstrumentWrites("asan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentByval("asan-instrument-byval", cl::desc("instrument byval call arguments"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClGlobals("asan-globals", cl::desc("Handle global objects"), cl::Hidden, cl::init(true))
static const uint64_t kDynamicShadowSentinel
static cl::opt< bool > ClInstrumentAtomics("asan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClInstrumentReads("asan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClWithIfunc("asan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("asan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
static cl::opt< uint64_t > ClMappingOffset("asan-mapping-offset", cl::desc("offset of asan shadow mapping [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file contains constants used for implementing Dwarf debug support.
std::optional< std::vector< StOtherPiece > > Other
This is the interface for a simple mod/ref and alias analysis over globals.
static cl::opt< float > ClRandomSkipRate("hwasan-random-rate", cl::desc("Probability value in the range [0.0, 1.0] " "to keep instrumentation of a function."))
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
static cl::opt< bool > ClInstrumentWrites("hwasan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
static const size_t kDefaultShadowScale
static cl::opt< RecordStackHistoryMode > ClRecordStackHistory("hwasan-record-stack-history", cl::desc("Record stack frames with tagged allocations in a thread-local " "ring buffer"), cl::values(clEnumVal(none, "Do not record stack ring history"), clEnumVal(instr, "Insert instructions into the prologue for " "storing into the stack ring buffer directly"), clEnumVal(libcall, "Add a call to __hwasan_add_frame_record for " "storing into the stack ring buffer")), cl::Hidden, cl::init(instr))
const char kHwasanModuleCtorName[]
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))
static cl::opt< bool > ClUseAfterScope("hwasan-use-after-scope", cl::desc("detect use after scope within function"), cl::Hidden, cl::init(true))
const char kHwasanNoteName[]
static cl::opt< int > ClHotPercentileCutoff("hwasan-percentile-cutoff-hot", cl::desc("Hot percentile cuttoff."))
static const unsigned kShadowBaseAlignment
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 cl::opt< bool > ClInstrumentReads("hwasan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentWithCalls("hwasan-instrument-with-calls", cl::desc("instrument reads and writes with callbacks"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClUseStackSafety("hwasan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"), cl::Optional)
static cl::opt< bool > ClInstrumentAtomics("hwasan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentStack("hwasan-instrument-stack", cl::desc("instrument stack (allocas)"), cl::Hidden, cl::init(true))
static cl::opt< uint64_t > ClMappingOffset("hwasan-mapping-offset", cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClRecover("hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClEnableKhwasan("hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInlineAllChecks("hwasan-inline-all-checks", cl::desc("inline all checks"), cl::Hidden, cl::init(false))
static const uint64_t kDynamicShadowSentinel
static cl::opt< bool > ClUsePageAliases("hwasan-experimental-use-page-aliases", cl::desc("Use page aliasing in HWASan"), cl::Hidden, cl::init(false))
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("hwasan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__hwasan_"))
static cl::opt< bool > ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics", cl::desc("instrument memory intrinsics"), cl::Hidden, cl::init(true))
static const size_t kNumberOfAccessSizes
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))
static cl::opt< bool > ClGlobals("hwasan-globals", cl::desc("Instrument globals"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("hwasan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInstrumentByval("hwasan-instrument-byval", cl::desc("instrument byval arguments"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClUseShortGranules("hwasan-use-short-granules", cl::desc("use short granules in allocas and outlined checks"), cl::Hidden, cl::init(false))
const char kHwasanShadowMemoryDynamicAddress[]
static unsigned getPointerOperandIndex(Instruction *I)
static cl::opt< bool > ClInlineFastPathChecks("hwasan-inline-fast-path-checks", cl::desc("inline all checks"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInstrumentPersonalityFunctions("hwasan-instrument-personality-functions", cl::desc("instrument personality functions"), cl::Hidden)
const char kHwasanInitName[]
static cl::opt< bool > ClInstrumentLandingPads("hwasan-instrument-landing-pads", cl::desc("instrument landing pads"), cl::Hidden, cl::init(false))
static cl::opt< size_t > ClMaxLifetimes("hwasan-max-lifetimes-for-alloca", cl::Hidden, cl::init(3), cl::ReallyHidden, cl::desc("How many lifetime ends to handle for a single alloca."), cl::Optional)
const char kHwasanPersonalityThunkName[]
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 void emitRemark(const Function &F, OptimizationRemarkEmitter &ORE, bool Skip)
This file implements a map that provides insertion order iteration.
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
const Value * getArraySize() const
Get the number of elements allocated.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
Analysis pass which computes BlockFrequencyInfo.
This class represents a function call, abstracting a target machine's calling convention.
void setTailCall(bool IsTc=true)
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 * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
void setComdat(Comdat *C)
bool hasSection() const
Check if this global has a custom object file section.
const SanitizerMetadata & getSanitizerMetadata() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
VisibilityTypes getVisibility() const
LinkageTypes getLinkage() const
bool isDeclarationForLinker() const
bool hasSanitizerMetadata() const
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
@ HiddenVisibility
The GV is hidden.
bool hasCommonLinkage() const
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Analysis pass providing a never-invalidated alias analysis result.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign 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.
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTypeSize(Type *DstType, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
BasicBlock * GetInsertBlock() const
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
const Instruction * getNextNonDebugInstruction(bool SkipPseudoOp=false) const
Return a pointer to the next non-debug instruction in the same basic block as 'this',...
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
This class implements a map that also provides access to all stored values in a deterministic order.
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Constant * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
void abandon()
Mark an analysis as abandoned.
void preserve()
Mark an analysis as preserved.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
bool stackAccessIsSafe(const Instruction &I) const
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
bool isAndroidVersionLT(unsigned Major) const
bool isAndroid() const
Tests whether the target is Android.
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
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.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
StringRef getName() const
Return a constant reference to the value's name.
int getNumOccurrences() const
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
Value * getFP(IRBuilder<> &IRB)
bool isStandardLifetime(const SmallVectorImpl< IntrinsicInst * > &LifetimeStart, const SmallVectorImpl< IntrinsicInst * > &LifetimeEnd, const DominatorTree *DT, const LoopInfo *LI, size_t MaxLifetimes)
bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT, const LoopInfo &LI, const Instruction *Start, const SmallVectorImpl< IntrinsicInst * > &Ends, const SmallVectorImpl< Instruction * > &RetVec, llvm::function_ref< void(Instruction *)> Callback)
uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
Value * getAndroidSlotPtr(IRBuilder<> &IRB, int Slot)
Value * readRegister(IRBuilder<> &IRB, StringRef Name)
void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag)
void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align)
Value * getPC(const Triple &TargetTriple, IRBuilder<> &IRB)
bool isLifetimeIntrinsic(Value *V)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
This struct is a compact representation of a valid (non-zero power of two) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
A CRTP mix-in to automatically provide informational APIs needed for passes.
MapVector< AllocaInst *, AllocaInfo > AllocasToInstrument
SmallVector< Instruction *, 4 > UnrecognizedLifetimes
SmallVector< Instruction *, 8 > RetVec