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