xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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:
StackInfoBuilder(const StackSafetyGlobalInfo * SSI)69   StackInfoBuilder(const StackSafetyGlobalInfo *SSI) : SSI(SSI) {}
70 
71   void visit(Instruction &Inst);
72   bool isInterestingAlloca(const AllocaInst &AI);
get()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 void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag);
90 
91 } // namespace memtag
92 } // namespace llvm
93 
94 #endif
95