#include "AArch64.h"
#include "AArch64InstrInfo.h"
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/MemoryTaggingSupport.h"
#include <cassert>
#include <iterator>
#include <memory>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
static cl::opt<bool> ClMergeInit(
"stack-tagging-merge-init", cl::Hidden, cl::init(true),
cl::desc("merge stack variable initializers with tagging when possible"));
static cl::opt<bool>
ClUseStackSafety("stack-tagging-use-stack-safety", cl::Hidden,
cl::init(true),
cl::desc("Use Stack Safety analysis results"));
static cl::opt<unsigned> ClScanLimit("stack-tagging-merge-init-scan-limit",
cl::init(40), cl::Hidden);
static cl::opt<unsigned>
ClMergeInitSizeLimit("stack-tagging-merge-init-size-limit", cl::init(272),
cl::Hidden);
static cl::opt<size_t> ClMaxLifetimes(
"stack-tagging-max-lifetimes-for-alloca", cl::Hidden, cl::init(3),
cl::ReallyHidden,
cl::desc("How many lifetime ends to handle for a single alloca."),
cl::Optional);
enum StackTaggingRecordStackHistoryMode { … };
static cl::opt<StackTaggingRecordStackHistoryMode> ClRecordStackHistory(
"stack-tagging-record-stack-history",
cl::desc("Record stack frames with tagged allocations in a thread-local "
"ring buffer"),
cl::values(clEnumVal(none, "Do not record stack ring history"),
clEnumVal(instr, "Insert instructions into the prologue for "
"storing into the stack ring buffer")),
cl::Hidden, cl::init(none));
static const Align kTagGranuleSize = …;
namespace {
class InitializerBuilder { … };
class AArch64StackTagging : public FunctionPass { … };
}
char AArch64StackTagging::ID = …;
INITIALIZE_PASS_BEGIN(AArch64StackTagging, DEBUG_TYPE, "AArch64 Stack Tagging",
false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(StackSafetyGlobalInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_END(AArch64StackTagging, DEBUG_TYPE, "AArch64 Stack Tagging",
false, false)
FunctionPass *llvm::createAArch64StackTaggingPass(bool IsOptNone) { … }
Instruction *AArch64StackTagging::collectInitializers(Instruction *StartInst,
Value *StartPtr,
uint64_t Size,
InitializerBuilder &IB) { … }
void AArch64StackTagging::tagAlloca(AllocaInst *AI, Instruction *InsertBefore,
Value *Ptr, uint64_t Size) { … }
void AArch64StackTagging::untagAlloca(AllocaInst *AI, Instruction *InsertBefore,
uint64_t Size) { … }
Instruction *AArch64StackTagging::insertBaseTaggedPointer(
const Module &M,
const MapVector<AllocaInst *, memtag::AllocaInfo> &AllocasToInstrument,
const DominatorTree *DT) { … }
bool AArch64StackTagging::runOnFunction(Function &Fn) { … }