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) {
126 bool BoundsChecking::instrument(
Value *Ptr,
Value *InstVal,
129 DEBUG(
dbgs() <<
"Instrument " << *Ptr <<
" for " <<
Twine(NeededSize)
134 if (!ObjSizeEval->bothKnown(SizeOffset)) {
139 Value *Size = SizeOffset.first;
140 Value *Offset = SizeOffset.second;
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;
188 for (std::vector<Instruction*>::iterator i = WorkList.begin(),
189 e = WorkList.end(); i != e; ++i) {
192 Builder->SetInsertPoint(Inst);
193 if (
LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
194 MadeChange |= instrument(LI->getPointerOperand(), LI, DL);
195 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
197 instrument(
SI->getPointerOperand(),
SI->getValueOperand(), DL);
200 instrument(AI->getPointerOperand(), AI->getCompareOperand(), DL);
201 }
else if (
AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(Inst)) {
203 instrument(AI->getPointerOperand(), AI->getValOperand(), DL);
212 return new BoundsChecking();
iplist< Instruction >::iterator eraseFromParent()
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")
AtomicCmpXchgInst - an instruction that atomically checks whether a specified value is in a memory lo...
CallInst - This class represents a function call, abstracting a target machine's calling convention...
LoadInst - an instruction for reading from memory.
AtomicRMWInst - an instruction that atomically reads a memory location, combines it with another valu...
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
StoreInst - 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.
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...
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::pair< Value *, Value * > SizeOffsetEvalType
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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...
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.
C - The default llvm calling convention, compatible with C.
inst_iterator inst_end(Function *F)
IRBuilder< true, TargetFolder > BuilderTy
const BasicBlock * getParent() const
void initializeBoundsCheckingPass(PassRegistry &)