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