30 #define DEBUG_TYPE "bounds-checking"
33 cl::desc(
"Use one trap block per function"));
35 STATISTIC(ChecksAdded,
"Bounds checks added");
36 STATISTIC(ChecksSkipped,
"Bounds checks skipped");
37 STATISTIC(ChecksUnable,
"Bounds checks unable to add");
63 void emitBranchToTrap(
Value *Cmp =
nullptr);
82 Builder->SetInsertPoint(TrapBB);
85 CallInst *TrapCall = Builder->CreateCall(F, {});
87 TrapCall->setDoesNotThrow();
88 TrapCall->setDebugLoc(Inst->getDebugLoc());
89 Builder->CreateUnreachable();
97 void BoundsChecking::emitBranchToTrap(
Value *Cmp) {
129 DEBUG(
dbgs() <<
"Instrument " << *Ptr <<
" for " <<
Twine(NeededSize)
134 if (!ObjSizeEval->bothKnown(SizeOffset)) {
139 Value *Size = SizeOffset.first;
153 Value *ObjSize = Builder->CreateSub(Size, Offset);
154 Value *Cmp2 = Builder->CreateICmpULT(Size, Offset);
155 Value *Cmp3 = Builder->CreateICmpULT(ObjSize, NeededSizeVal);
156 Value *
Or = Builder->CreateOr(Cmp2, Cmp3);
159 Or = Builder->CreateOr(Cmp1, Or);
161 emitBranchToTrap(Or);
166 bool BoundsChecking::runOnFunction(
Function &
F) {
168 TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
172 Builder = &TheBuilder;
175 ObjSizeEval = &TheObjSizeEval;
179 std::vector<Instruction*> WorkList;
182 if (isa<LoadInst>(I) || isa<StoreInst>(
I) || isa<AtomicCmpXchgInst>(I) ||
183 isa<AtomicRMWInst>(
I))
184 WorkList.push_back(I);
187 bool MadeChange =
false;
191 Builder->SetInsertPoint(Inst);
192 if (
LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
193 MadeChange |= instrument(LI->getPointerOperand(), LI, DL);
194 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
196 instrument(
SI->getPointerOperand(),
SI->getValueOperand(), DL);
199 instrument(AI->getPointerOperand(), AI->getCompareOperand(), DL);
200 }
else if (
AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(Inst)) {
202 instrument(AI->getPointerOperand(), AI->getValOperand(), DL);
211 return new BoundsChecking();
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
FunctionPass * createBoundsCheckingPass()
STATISTIC(NumFunctions,"Total number of functions")
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
This class represents a function call, abstracting a target machine's calling convention.
An instruction for reading from memory.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
AnalysisUsage & addRequired()
inst_iterator inst_begin(Function *F)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const APInt & getValue() const
Return the constant as an APInt value reference.
static cl::opt< bool > SingleTrapBB("bounds-checking-single-trap", cl::desc("Use one trap block per function"))
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Evaluate the size and offset of an object pointed to by a Value*.
TargetFolder - Create constants with target dependent folding.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
An instruction for storing to memory.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
Represent the analysis usage information of a pass.
INITIALIZE_PASS(BoundsChecking,"bounds-checking","Run-time bounds checking", false, false) BasicBlock *BoundsChecking
getTrapBB - create a basic block that traps.
FunctionPass class - This class is used to implement most global optimizations.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
IRBuilder< TargetFolder > BuilderTy
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
bool slt(const APInt &RHS) const
Signed less than comparison.
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::pair< Value *, Value * > SizeOffsetEvalType
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
inst_iterator inst_end(Function *F)
void initializeBoundsCheckingPass(PassRegistry &)