1 //===- MemoryTaggingSupport.h - helpers for memory tagging implementations ===// 2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3 // See https://llvm.org/LICENSE.txt for license information. 4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5 // 6 //===----------------------------------------------------------------------===// 7 // 8 // This file declares common infrastructure for HWAddressSanitizer and 9 // Aarch64StackTagging. 10 // 11 //===----------------------------------------------------------------------===// 12 #ifndef LLVM_TRANSFORMS_UTILS_MEMORYTAGGINGSUPPORT_H 13 #define LLVM_TRANSFORMS_UTILS_MEMORYTAGGINGSUPPORT_H 14 15 #include "llvm/ADT/MapVector.h" 16 #include "llvm/ADT/STLFunctionalExtras.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/Analysis/LoopInfo.h" 19 #include "llvm/Support/Alignment.h" 20 21 namespace llvm { 22 class DominatorTree; 23 class DbgVariableIntrinsic; 24 class IntrinsicInst; 25 class PostDominatorTree; 26 class AllocaInst; 27 class Instruction; 28 namespace memtag { 29 // For an alloca valid between lifetime markers Start and Ends, call the 30 // Callback for all possible exits out of the lifetime in the containing 31 // function, which can return from the instructions in RetVec. 32 // 33 // Returns whether Ends covered all possible exits. If they did not, 34 // the caller should remove Ends to ensure that work done at the other 35 // exits does not happen outside of the lifetime. 36 bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT, 37 const LoopInfo &LI, const Instruction *Start, 38 const SmallVectorImpl<IntrinsicInst *> &Ends, 39 const SmallVectorImpl<Instruction *> &RetVec, 40 llvm::function_ref<void(Instruction *)> Callback); 41 42 bool isStandardLifetime(const SmallVectorImpl<IntrinsicInst *> &LifetimeStart, 43 const SmallVectorImpl<IntrinsicInst *> &LifetimeEnd, 44 const DominatorTree *DT, const LoopInfo *LI, 45 size_t MaxLifetimes); 46 47 Instruction *getUntagLocationIfFunctionExit(Instruction &Inst); 48 49 struct AllocaInfo { 50 AllocaInst *AI; 51 SmallVector<IntrinsicInst *, 2> LifetimeStart; 52 SmallVector<IntrinsicInst *, 2> LifetimeEnd; 53 SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics; 54 }; 55 56 struct StackInfo { 57 MapVector<AllocaInst *, AllocaInfo> AllocasToInstrument; 58 SmallVector<Instruction *, 4> UnrecognizedLifetimes; 59 SmallVector<Instruction *, 8> RetVec; 60 bool CallsReturnTwice = false; 61 }; 62 63 class StackInfoBuilder { 64 public: 65 StackInfoBuilder(std::function<bool(const AllocaInst &)> IsInterestingAlloca) 66 : IsInterestingAlloca(IsInterestingAlloca) {} 67 68 void visit(Instruction &Inst); 69 StackInfo &get() { return Info; }; 70 71 private: 72 StackInfo Info; 73 std::function<bool(const AllocaInst &)> IsInterestingAlloca; 74 }; 75 76 uint64_t getAllocaSizeInBytes(const AllocaInst &AI); 77 void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align); 78 79 } // namespace memtag 80 } // namespace llvm 81 82 #endif 83