void Executor::executeGep(Instruction *i) { if (DisabledSymbolicExeCurRun) { return; } assert(i && "Expecting an instruction!"); GetElementPtrInst *gep = (GetElementPtrInst*) i; assert(gep->getNumIndices()<=2 && "Unsupported gep instruction"); if(AllocaInst *a = dyn_cast<AllocaInst>(gep->getPointerOperand())) { Type *ty = a->getAllocatedType(); if (ty->isIntegerTy()) { // Incompleteness: pointer dereferencement on symbolic value AllLocDefinite = false; return; } } unsigned idx = 0; Type *subTy = NULL; Type *ptrOpTy = gep->getPointerOperandType(); if (ptrOpTy && ptrOpTy->getNumContainedTypes()==1) { subTy = ptrOpTy->getContainedType(0); } if (subTy && subTy->getNumContainedTypes()>0) { idx = 1; } else { assert("Unsupported gep instruction!"); } Value *ptr = (Value*) i; if(gep->hasIndices()) { Value *index = gep->getOperand(idx+1); if (SMAP->contains(index)) { // P[v->sv] // sv is a new symbolic value // Value *a = gep->getPointerOperand(); // ptr = (a index) //SymbolPtr Sindex = SMAP->get(index); //PMAP->createGepOp(ptr, a, Sindex); // Incompleteness: pointer dereferencement on symbolic value AllLocDefinite = false; } else { // P = P - ptr PMAP->remove(ptr); } } // Global allocation /*else if(isa<GlobalVariable>(ptr)) { // ptr in domain(P) if (PMAP->contains(ptr)) { SymbolPtr Pptr = PMAP->get(ptr); // P' = P[ptr->S(val)] PMAP->update(ptr, Pptr); } else { // P = P - ptr PMAP->remove(ptr); } }*/ }
// This is the main body of our code. virtual bool runOnFunction(Function &F){ errs() << " ----- Starting Range Checking Pass on Function " << F.getName() << " ------ \n\n"; //Module* M = F.getParent(); //DataLayout* dl = M->getDataLayout(); RAFlowFunction raf = RAFlowFunction(); std::map<Value*, ConstantRange*> representation; /* errs() << "We are dealing with the following function \n"; F.print(errs()); errs() << "Our analysis returned the following \n"; */ RALatticePoint* bottom = new RALatticePoint(true, false, representation); std::map<Instruction *, LatticePoint *> result = Analysis::analyze(F, bottom, &raf); int i = 1; bool has_range_warnings = false; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I){ Instruction* current_instruction = &*I; LatticePoint* lp = result[current_instruction]; RALatticePoint* rlp = dyn_cast<RALatticePoint>(lp); if (isa<GetElementPtrInst>(current_instruction)) { GetElementPtrInst* gep = cast<GetElementPtrInst>(current_instruction); Type* pt = gep->getPointerOperandType(); PointerType* pointer_type = dyn_cast<PointerType>(pt); Type* elm_type = pointer_type->getElementType(); if (isa<ArrayType>(elm_type)) { ArrayType* arr_type = cast<ArrayType>(elm_type); //errs() << " number of elements is " << arr_type->getNumElements(); int size = arr_type->getNumElements(); Value* index = helper::getGEPIndex(*gep); if (rlp->representation.count(index) > 0) { APInt* max_size = new APInt(32, size); APInt* zero = new APInt(32, 0); ConstantRange* arr_range = new ConstantRange(*zero, *max_size); ConstantRange* index_range = rlp->representation[index]; if (!arr_range->contains(*index_range)) { has_range_warnings = true; errs() << "Warning: possible out of bounds array access at line " << i; errs() << "\n-Instruction: "; gep->print(errs()); errs() << "\n--- Valid array possitions: "; arr_range->print(errs()); errs() << "\n--- Index has possible range: "; index_range->print(errs()); errs() << "\n"; } } else if (isa<ConstantInt>(index)){ ConstantInt* index_value = cast<ConstantInt>(index); ConstantRange* index_range = new ConstantRange(index_value->getValue()); APInt* max_size = new APInt(index_value->getBitWidth(), size - 1); APInt* zero = new APInt(index_value->getBitWidth(), 0); ConstantRange* arr_range = new ConstantRange(*zero, *max_size); if (!arr_range->contains(*index_range)) { has_range_warnings = true; errs() << "Warning: possible out of bounds array access at line " << i; errs() << "\n-Instruction: "; gep->print(errs()); errs() << "\n--- Valid array possitions: "; arr_range->print(errs()); errs() << "\n--- Index has possible range: "; index_range->print(errs()); errs() << "\n"; } } } } i++; } if (has_range_warnings) { errs() << "\nDone with range checking. Exited with warnings!\n\n"; } else{ errs() << "\nDone with range checking. Exited with no warnings.\n\n"; } errs() << " ----- Ending Range Checking Pass on Function " << F.getName() << " ------ \n"; return false; }