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
23namespace llvm {
24class DominatorTree;
25class DbgVariableIntrinsic;
26class IntrinsicInst;
27class PostDominatorTree;
28class AllocaInst;
29class Instruction;
30namespace 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.
38bool 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
44bool isStandardLifetime(const SmallVectorImpl<IntrinsicInst *> &LifetimeStart,
45 const SmallVectorImpl<IntrinsicInst *> &LifetimeEnd,
46 const DominatorTree *DT, const LoopInfo *LI,
47 size_t MaxLifetimes);
48
49Instruction *getUntagLocationIfFunctionExit(Instruction &Inst);
50
51struct 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
60struct StackInfo {
61 MapVector<AllocaInst *, AllocaInfo> AllocasToInstrument;
62 SmallVector<Instruction *, 4> UnrecognizedLifetimes;
63 SmallVector<Instruction *, 8> RetVec;
64 bool CallsReturnTwice = false;
65};
66
67class StackInfoBuilder {
68public:
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
75private:
76 StackInfo Info;
77 const StackSafetyGlobalInfo *SSI;
78};
79
80uint64_t getAllocaSizeInBytes(const AllocaInst &AI);
81void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align);
82bool isLifetimeIntrinsic(Value *V);
83
84Value *readRegister(IRBuilder<> &IRB, StringRef Name);
85Value *getFP(IRBuilder<> &IRB);
86Value *getPC(const Triple &TargetTriple, IRBuilder<> &IRB);
87Value *getAndroidSlotPtr(IRBuilder<> &IRB, int Slot);
88
89} // namespace memtag
90} // namespace llvm
91
92#endif
93

source code of llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h