LLVM: lib/Transforms/Instrumentation/BoundsChecking.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

31#include

32

33using namespace llvm;

34

35#define DEBUG_TYPE "bounds-checking"

36

38 cl::desc("Use one trap block per function"));

39

40STATISTIC(ChecksAdded, "Bounds checks added");

41STATISTIC(ChecksSkipped, "Bounds checks skipped");

42STATISTIC(ChecksUnable, "Bounds checks unable to add");

43

51

52

53

54

55

56

57

58

64 LLVM_DEBUG(dbgs() << "Instrument " << *Ptr << " for " << Twine(NeededSize)

65 << " bytes\n");

66

68

70 ++ChecksUnable;

71 return nullptr;

72 }

73

77

80

84

85

86

87

88

89

90

91

93 Value *Cmp2 = SizeRange.getUnsignedMin().uge(OffsetRange.getUnsignedMax())

96 Value *Cmp3 = SizeRange.sub(OffsetRange)

97 .getUnsignedMin()

98 .uge(NeededSizeRange.getUnsignedMax())

102 if ((!SizeCI || SizeCI->getValue().slt(0)) &&

103 !SizeRange.getSignedMin().isNonNegative()) {

106 }

107

108 return Or;

109}

110

112 std::optional<int8_t> GuardKind) {

113 if (!DebugTrapBB)

115

117 Intrinsic::ubsantrap,

118 ConstantInt::get(IRB.getInt8Ty(),

119 GuardKind.has_value()

120 ? GuardKind.value()

122}

123

127 llvm::AttrBuilder B(Ctx);

128 B.addAttribute(llvm::Attribute::NoUnwind);

129 if (!MayReturn)

130 B.addAttribute(llvm::Attribute::NoReturn);

132 Name,

133 llvm::AttributeList::get(Ctx, llvm::AttributeList::FunctionIndex, B),

136}

137

138

139

140

141

142

143template

145

147 if (C) {

148 ++ChecksSkipped;

149

150 if (C->getZExtValue())

151 return;

152 }

153 ++ChecksAdded;

154

159

160 BasicBlock *TrapBB = GetTrapBB(IRB, Cont);

161

162 if (C) {

163

164

165

167 return;

168 }

169

170

172}

173

174static std::string

176 std::string Name = "__ubsan_handle_local_out_of_bounds";

178 Name += "_minimal";

180 Name += "_abort";

182 Name += "_preserve";

183 return Name;

184}

185

189 if (F.hasFnAttribute(Attribute::NoSanitizeBounds))

190 return false;

191

197

198

199

205 if (!LI->isVolatile())

207 ObjSizeEval, IRB, SE);

209 if (SI->isVolatile())

211 DL, TLI, ObjSizeEval, IRB, SE);

213 if (!AI->isVolatile())

216 DL, TLI, ObjSizeEval, IRB, SE);

218 if (!AI->isVolatile())

220 DL, TLI, ObjSizeEval, IRB, SE);

221 }

222 if (Or) {

225 IRB.getInt1Ty(), Intrinsic::allow_ubsan_check,

226 {llvm::ConstantInt::getSigned(IRB.getInt8Ty(), *Opts.GuardKind)});

228 }

230 }

231 }

232

233 std::string Name;

234 if (Opts.Rt)

236

237

238

239

241 auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name](BuilderTy &IRB,

244 auto DebugLoc = IRB.getCurrentDebugLocation();

246

247

248

249

250 if (ReuseTrapBB)

251 return ReuseTrapBB;

252

254 IRB.SetInsertPoint(TrapBB);

255

256 bool DebugTrapBB = !Opts.Merge;

259 if (DebugTrapBB)

260 TrapCall->addFnAttr(llvm::Attribute::NoMerge);

261

264

265 bool MayReturn = Opts.Rt && Opts.Rt->MayReturn;

266 if (MayReturn) {

267 IRB.CreateBr(Cont);

268 } else {

270 IRB.CreateUnreachable();

271 }

272

273

274 if (Opts.Rt && Opts.Rt->HandlerPreserveAllRegs && MayReturn)

276 if (!MayReturn && SingleTrapBB && !DebugTrapBB)

277 ReuseTrapBB = TrapBB;

278

279 return TrapBB;

280 };

281

282 for (const auto &Entry : TrapInfo) {

286 }

287

288 return !TrapInfo.empty();

289}

290

300

304 OS, MapClassName2PassName);

305 OS << "<";

306 if (Opts.Rt) {

307 if (Opts.Rt->MinRuntime)

308 OS << "min-";

309 OS << "rt";

310 if (!Opts.Rt->MayReturn)

311 OS << "-abort";

312 } else {

313 OS << "trap";

314 }

315 if (Opts.Merge)

316 OS << ";merge";

317 if (Opts.GuardKind)

318 OS << ";guard=" << static_cast<int>(*Opts.GuardKind);

319 OS << ">";

320}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Expand Atomic instructions

static void insertBoundsCheck(Value *Or, BuilderTy &IRB, GetTrapBBT GetTrapBB)

Adds run-time bounds checks to memory accessing instructions.

Definition BoundsChecking.cpp:144

static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI, ScalarEvolution &SE, const BoundsCheckingPass::Options &Opts)

Definition BoundsChecking.cpp:186

static CallInst * InsertCall(BuilderTy &IRB, bool MayReturn, StringRef Name)

Definition BoundsChecking.cpp:124

static Value * getBoundsCheckCond(Value *Ptr, Value *InstVal, const DataLayout &DL, TargetLibraryInfo &TLI, ObjectSizeOffsetEvaluator &ObjSizeEval, BuilderTy &IRB, ScalarEvolution &SE)

Gets the conditions under which memory accessing instructions will overflow.

Definition BoundsChecking.cpp:59

static std::string getRuntimeCallName(const BoundsCheckingPass::Options::Runtime &Opts)

Definition BoundsChecking.cpp:175

static CallInst * InsertTrap(BuilderTy &IRB, bool DebugTrapBB, std::optional< int8_t > GuardKind)

Definition BoundsChecking.cpp:111

static cl::opt< bool > SingleTrapBB("bounds-checking-single-trap", cl::desc("Use one trap block per function"))

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

Definition BoundsChecking.cpp:44

BuilderTy(BasicBlock *TheBB, BasicBlock::iterator IP, TargetFolder Folder)

Definition BoundsChecking.cpp:46

bool slt(const APInt &RHS) const

Signed less than comparison.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

An instruction that atomically checks whether a specified value is in a memory location,...

an instruction that atomically reads a memory location, combines it with another value,...

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)

Creates a new BasicBlock.

LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)

Split the basic block into two basic blocks at the specified instruction.

InstListType::iterator iterator

Instruction iterators...

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

Definition BoundsChecking.cpp:291

LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)

Definition BoundsChecking.cpp:301

static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)

void setCallingConv(CallingConv::ID CC)

void addFnAttr(Attribute::AttrKind Kind)

Adds the attribute to the function.

This class represents a function call, abstracting a target machine's calling convention.

This is the shared class of boolean and integer constants.

static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)

const APInt & getValue() const

Return the constant as an APInt value reference.

A parsed version of the target data layout string in and methods for querying it.

A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

Module * getParent()

Get the module that this global value is contained inside of...

Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")

void SetNoSanitizeMetadata()

Set nosanitize metadata.

IntegerType * getInt1Ty()

Fetch the type representing a single bit.

BasicBlock::iterator GetInsertPoint() const

BasicBlock * GetInsertBlock() const

LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")

Create a call to intrinsic ID with Args, mangled using Types.

Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")

CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)

Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")

LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)

Create an expression which evaluates to the number of units in Size at runtime.

Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)

IntegerType * getInt8Ty()

Fetch the type representing an 8-bit integer.

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

IRBuilder(LLVMContext &C, TargetFolder Folder, IRBuilderDefaultInserter Inserter, MDNode *FPMathTag=nullptr, ArrayRef< OperandBundleDef > OpBundles={})

LLVM_ABI InstListType::iterator eraseFromParent()

This method unlinks 'this' from the containing basic block and deletes it.

void setDebugLoc(DebugLoc Loc)

Set the debug location information for this instruction.

This is an important class for using LLVM in a threaded context.

An instruction for reading from memory.

FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)

Look up the specified function in the module symbol table.

Evaluate the size and offset of an object pointed to by a Value*.

LLVM_ABI SizeOffsetValue compute(Value *V)

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Analysis pass that exposes the ScalarEvolution for a function.

The main scalar evolution driver.

LLVM_ABI const SCEV * getSCEV(Value *V)

Return a SCEV expression for the full generality of the specified expression.

ConstantRange getUnsignedRange(const SCEV *S)

Determine the unsigned range for a particular SCEV.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

An instruction for storing to memory.

StringRef - Represent a constant reference to a string, i.e.

TargetFolder - Create constants with target dependent folding.

Analysis pass providing the TargetLibraryInfo.

Provides information about what library functions are available for the current target.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI Type * getVoidTy(LLVMContext &C)

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

An efficient, type-erasing, non-owning reference to a callable.

const ParentTy * getParent() const

This class implements an extremely fast bulk output stream that can only output to a stream.

@ PreserveAll

Used for runtime calls that preserves (almost) all registers.

@ C

The default llvm calling convention, compatible with C.

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

bool HandlerPreserveAllRegs

std::optional< Runtime > Rt

std::optional< int8_t > GuardKind

Various options to control the behavior of getObjectSize.

Mode EvalMode

How we want to evaluate this object's size.

bool RoundToAlign

Whether to round the result up to the alignment of allocas, byval arguments, and global variables.

@ ExactUnderlyingSizeAndOffset

All branches must be known and have the same underlying size and offset to be merged.

A CRTP mix-in to automatically provide informational APIs needed for passes.