Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop and test enum #2

Closed
Closed
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
90c9156
TEnum and TEnumConstant linked
CristinaCristescu Jul 12, 2013
d5a27ee
TEnum and TEnumConstant linked
CristinaCristescu Jul 12, 2013
9d2dab8
Integrate TEnum and TEnumConstant with TCling.
CristinaCristescu Jul 12, 2013
fbe1e7c
Fix enums and test TCling with enums.
CristinaCristescu Jul 16, 2013
2270680
New interface to TEnum and update in TClass and TCling
CristinaCristescu Aug 5, 2013
faae06a
Fix enum decls by pushing manually the transation.
CristinaCristescu Aug 8, 2013
091bb94
Finally: enable the asserts that assure very conservative integrity c…
vgvassilev Aug 8, 2013
ae65cac
Add another expected to pass construct for null deref.
vgvassilev Aug 8, 2013
cd0762c
Loosen the asserts due to not well-enough-understood behavior in clan…
vgvassilev Aug 8, 2013
659caed
Allow to change text of context menu items even when they are of type…
bellenot Aug 8, 2013
9d31735
Fix a problem on Windows with TContextMenu::Execute() parameters
bellenot Aug 8, 2013
b44a177
Only if I could spell C++ :)
vgvassilev Aug 8, 2013
baa7b98
Instead of check each load and store instruction, we check the usage …
sploving Aug 8, 2013
24a1203
In CLINGCXXFLAGS, put the source include dir first.
pcanal Aug 8, 2013
4326f21
Not using real SourceLocation is bad, especially in -verify mode.
vgvassilev Aug 8, 2013
956b885
Add support for per-packet max proc time
gganis Aug 7, 2013
641a1fa
Fine-tune previous patch
gganis Aug 8, 2013
cc511bf
Remove unused variable.
vgvassilev Aug 9, 2013
e653ef6
Replaced tabs with spaces in testcode
strykejern Aug 8, 2013
448e120
Replaced tabs with spaces in custom classes for tests
strykejern Aug 8, 2013
6c5b206
Added comment for one array reader interface
strykejern Aug 8, 2013
132b855
Remove a couple of gotos
bellenot Aug 9, 2013
504c91e
Remove forgotten label
bellenot Aug 9, 2013
f0473ba
Remove one more goto
bellenot Aug 9, 2013
ce8dee2
Reverting wrong changes to TTreePlayer
strykejern Aug 9, 2013
3a59f4d
Refactoring interface for incrementing the entry pointer
strykejern Aug 9, 2013
1ec1a2e
Fix unchecked NULL return in HandleEnumDecl.
CristinaCristescu Aug 12, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Instead of check each load and store instruction, we check the usage …
…of the load instruction.

Currently, there are four kinds of instruction that may use a load instruction as its argument:
load, store, GEP and call instruction. We instrument these four kinds instruction to check there
may be a null pointer dereference.
sploving authored and CristinaCristescu committed Aug 12, 2013
commit baa7b98fb7280627871788b188bba27544cb8b7b
125 changes: 70 additions & 55 deletions interpreter/cling/lib/Interpreter/NullDerefProtectionTransformer.cpp
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/InstIterator.h"

@@ -108,12 +109,12 @@ namespace cling {
runOnFunction(*F);
}

llvm::BasicBlock* NullDerefProtectionTransformer::getTrapBB() {
llvm::BasicBlock*
NullDerefProtectionTransformer::getTrapBB(llvm::BasicBlock* BB) {
llvm::Function* Fn = Inst->getParent()->getParent();
llvm::Module* Md = Fn->getParent();
llvm::LLVMContext& ctx = Fn->getContext();

llvm::BasicBlock::iterator PreInsertInst = Builder->GetInsertPoint();
FailBB = llvm::BasicBlock::Create(ctx, "FailBlock", Fn);
Builder->SetInsertPoint(FailBB);

@@ -149,57 +150,35 @@ namespace cling {

llvm::Value* TrueVl = llvm::ConstantInt::get(ctx, llvm::APInt(1, 1));
llvm::Value* RetVl = CI;
llvm::ICmpInst*Cmp
llvm::ICmpInst* Cmp
= new llvm::ICmpInst(*FailBB, llvm::CmpInst::ICMP_EQ, RetVl, TrueVl, "");

llvm::BasicBlock *HandleBB = llvm::BasicBlock::Create(ctx,"HandleBlock", Fn);
llvm::BranchInst::Create(HandleBB, Inst->getParent(), Cmp, FailBB);
llvm::BranchInst::Create(HandleBB, BB, Cmp, FailBB);

llvm::ReturnInst::Create(Fn->getContext(), HandleBB);
Builder->SetInsertPoint(PreInsertInst);
return FailBB;
}

void NullDerefProtectionTransformer::instrumentLoadInst(llvm::LoadInst *LI) {
llvm::Value* Addr = LI->getOperand(0);
if(llvm::isa<llvm::GlobalVariable>(Addr))
return;

llvm::PointerType* PTy = llvm::cast<llvm::PointerType>(Addr->getType());
llvm::Type* ElTy = PTy->getElementType();
if (!ElTy->isPointerTy()) {
llvm::BasicBlock* OldBB = LI->getParent();
llvm::ICmpInst* Cmp
= new llvm::ICmpInst(LI, llvm::CmpInst::ICMP_EQ, Addr,
llvm::Constant::getNullValue(Addr->getType()), "");

llvm::Instruction *Inst = Builder->GetInsertPoint();
llvm::BasicBlock *NewBB = OldBB->splitBasicBlock(Inst);

OldBB->getTerminator()->eraseFromParent();
llvm::BranchInst::Create(getTrapBB(), NewBB, Cmp, OldBB);
}
}

void NullDerefProtectionTransformer::instrumentStoreInst(llvm::StoreInst *SI){
llvm::Value* Addr = SI->getOperand(1);
if(llvm::isa<llvm::GlobalVariable>(Addr))
return;

llvm::PointerType* PTy = llvm::cast<llvm::PointerType>(Addr->getType());
llvm::Type* ElTy = PTy -> getElementType();
if (!ElTy->isPointerTy()) {
llvm::BasicBlock* OldBB = SI->getParent();
llvm::ICmpInst* Cmp
= new llvm::ICmpInst(SI, llvm::CmpInst::ICMP_EQ, Addr,
llvm::Constant::getNullValue(Addr->getType()), "");

llvm::Instruction* Inst = Builder->GetInsertPoint();
llvm::BasicBlock* NewBB = OldBB->splitBasicBlock(Inst);

OldBB->getTerminator()->eraseFromParent();
llvm::BranchInst::Create(getTrapBB(), NewBB, Cmp, OldBB);
}
// Insert a cmp instruction before the "Inst" instruction to check whether the
// argument "Arg" for the instruction "Inst" is null or not.
void NullDerefProtectionTransformer::instrumentInst(
llvm::Instruction* Inst, llvm::Value* Arg) {
llvm::BasicBlock* OldBB = Inst->getParent();

// Insert a cmp instruction to check whether "Arg" is null or not.
llvm::ICmpInst* Cmp
= new llvm::ICmpInst(Inst, llvm::CmpInst::ICMP_EQ, Arg,
llvm::Constant::getNullValue(Arg->getType()), "");

// The block is splited into two blocks, "OldBB" and "NewBB", by the "Inst"
// instruction. After that split, "Inst" is at the start of "NewBB". Then
// insert a branch instruction at the end of "OldBB". If "Arg" is null,
// it will jump to "FailBB" created by "getTrapBB" function. Else, it means
// jump to the "NewBB".
llvm::BasicBlock* NewBB = OldBB->splitBasicBlock(Inst);
OldBB->getTerminator()->eraseFromParent();
llvm::BranchInst::Create(getTrapBB(NewBB), NewBB, Cmp, OldBB);
}

bool NullDerefProtectionTransformer::runOnFunction(llvm::Function &F) {
@@ -209,21 +188,57 @@ namespace cling {
std::vector<llvm::Instruction*> WorkList;
for (llvm::inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
llvm::Instruction* I = &*i;
if (llvm::isa<llvm::LoadInst>(I) || llvm::isa<llvm::StoreInst>(I))
if (llvm::isa<llvm::LoadInst>(I))
WorkList.push_back(I);
}
}

for (std::vector<llvm::Instruction*>::iterator i = WorkList.begin(),
e = WorkList.end(); i != e; ++i) {
Inst = *i;

Builder->SetInsertPoint(Inst);
if (llvm::LoadInst* LI = llvm::dyn_cast<llvm::LoadInst>(Inst)) {
instrumentLoadInst(LI);
} else if (llvm::StoreInst* SI = llvm::dyn_cast<llvm::StoreInst>(Inst)) {
instrumentStoreInst(SI);
} else {
llvm_unreachable("unknown Instruction type");
llvm::LoadInst* I = llvm::cast<llvm::LoadInst>(*i);

// Find all the instructions that uses the instruction I.
for (llvm::Value::use_iterator UI = I->use_begin(), UE = I->use_end();
UI != UE; ++UI) {

// Check whether I is used as the first argument for a load instruction.
// If it is, then instrument the load instruction.
if (llvm::LoadInst* LI = llvm::dyn_cast<llvm::LoadInst>(*UI)) {
llvm::Value* Arg = LI->getOperand(0);
if (Arg == I)
instrumentInst(LI, Arg);
}

// Check whether I is used as the second argument for a store
// instruction. If it is, then instrument the store instruction.
else if (llvm::StoreInst* SI = llvm::dyn_cast<llvm::StoreInst>(*UI)) {
llvm::Value* Arg = SI->getOperand(1);
if (Arg == I)
instrumentInst(SI, Arg);
}

// Check whether I is used as the first argument for a GEP instruction.
// If it is, then instrument the GEP instruction.
else if (llvm::GetElementPtrInst* GEP = llvm::dyn_cast<
llvm::GetElementPtrInst>(*UI)) {
llvm::Value* Arg = GEP->getOperand(0);
if (Arg == I)
instrumentInst(GEP, Arg);
}

else {
// Check whether I is used as the first argument for a call instruction.
// If it is, then instrument the call instruction.
llvm::CallSite CS(*UI);
if (CS) {
llvm::CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
if (i != e) {
llvm::Value *Arg = *i;
if (Arg == I)
instrumentInst(CS.getInstruction(), Arg);
}
}
}
}
}
return true;
Original file line number Diff line number Diff line change
@@ -35,9 +35,8 @@ namespace cling {
llvm::Instruction* Inst;
llvm::OwningPtr<clang::MangleContext> m_MangleCtx;

llvm::BasicBlock* getTrapBB();
void instrumentLoadInst(llvm::LoadInst* LI);
void instrumentStoreInst(llvm::StoreInst* SI);
llvm::BasicBlock* getTrapBB(llvm::BasicBlock* BB);
void instrumentInst(llvm::Instruction* Inst, llvm::Value* Arg);
bool runOnFunction(llvm::Function& F);

public: