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