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/Analysis/StackSafetyAnalysis.h" 20 #include "llvm/Support/Alignment.h" 21 22 namespace llvm { 23 class DominatorTree; 24 class DbgVariableIntrinsic; 25 class IntrinsicInst; 26 class PostDominatorTree; 27 class AllocaInst; 28 class Instruction; 29 namespace memtag { 30 // For an alloca valid between lifetime markers Start and Ends, call the 31 // Callback for all possible exits out of the lifetime in the containing 32 // function, which can return from the instructions in RetVec. 33 // 34 // Returns whether Ends covered all possible exits. If they did not, 35 // the caller should remove Ends to ensure that work done at the other 36 // exits does not happen outside of the lifetime. 37 bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT, 38 const LoopInfo &LI, const Instruction *Start, 39 const SmallVectorImpl<IntrinsicInst *> &Ends, 40 const SmallVectorImpl<Instruction *> &RetVec, 41 llvm::function_ref<void(Instruction *)> Callback); 42 43 bool isStandardLifetime(const SmallVectorImpl<IntrinsicInst *> &LifetimeStart, 44 const SmallVectorImpl<IntrinsicInst *> &LifetimeEnd, 45 const DominatorTree *DT, const LoopInfo *LI, 46 size_t MaxLifetimes); 47 48 Instruction *getUntagLocationIfFunctionExit(Instruction &Inst); 49 50 struct AllocaInfo { 51 AllocaInst *AI; 52 SmallVector<IntrinsicInst *, 2> LifetimeStart; 53 SmallVector<IntrinsicInst *, 2> LifetimeEnd; 54 SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics; 55 }; 56 57 struct StackInfo { 58 MapVector<AllocaInst *, AllocaInfo> AllocasToInstrument; 59 SmallVector<Instruction *, 4> UnrecognizedLifetimes; 60 SmallVector<Instruction *, 8> RetVec; 61 bool CallsReturnTwice = false; 62 }; 63 64 class StackInfoBuilder { 65 public: StackInfoBuilder(const StackSafetyGlobalInfo * SSI)66 StackInfoBuilder(const StackSafetyGlobalInfo *SSI) : SSI(SSI) {} 67 68 void visit(Instruction &Inst); 69 bool isInterestingAlloca(const AllocaInst &AI); get()70 StackInfo &get() { return Info; }; 71 72 private: 73 StackInfo Info; 74 const StackSafetyGlobalInfo *SSI; 75 }; 76 77 uint64_t getAllocaSizeInBytes(const AllocaInst &AI); 78 void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align); 79 80 } // namespace memtag 81 } // namespace llvm 82 83 #endif 84