void SpecialFunctionHandler::handleGetObjSize(ExecutionState &state, KInstruction *target, std::vector<ref<Expr> > &arguments) { // XXX should type check args assert(arguments.size()==1 && "invalid number of arguments to klee_get_obj_size"); Executor::ExactResolutionList rl; executor.resolveExact(state, arguments[0], rl, "klee_get_obj_size"); for (Executor::ExactResolutionList::iterator it = rl.begin(), ie = rl.end(); it != ie; ++it) { executor.bindLocal(target, *it->second, ConstantExpr::create(it->first.first->size, Expr::Int32)); } }
void SpecialFunctionHandler::handleMakeLengthSymbolic(ExecutionState &state, KInstruction *target, std::vector<ref<Expr> > &arguments) { std::string name; assert(arguments.size()==3 && "invalid number of arguments to klee_make_symbolic"); name = readStringAtAddress(state, arguments[2]); //std::cerr << "make_length_symbolic called len_rl.size=" << len_rl.size() << " \n"; Executor::ExactResolutionList rl; executor.resolveExact(state, arguments[0], rl, "make_symbolic"); for (Executor::ExactResolutionList::iterator it = rl.begin(), ie = rl.end(); it != ie; ++it) { const ObjectState *old = it->first.second; ExecutionState *s = it->second; //allocate space for len_mo MemoryObject *len_mo = executor.executeNoBindAlloc(*s, 4); //4-byte int len_mo->setName(name + "_len"); len_mo->onlyTrackLength = 0; len_mo->isALength = 1; executor.executeMakeSymbolic(*s, len_mo); MemoryObject *mo = (MemoryObject*) it->first.first; mo->setName(name); mo->onlyTrackLength = 1; mo->isALength = 0; mo->length = len_mo; //important! makes len_mo track mo->length if (old->readOnly) { executor.terminateStateOnError(*s, "cannot make readonly object symbolic", "user.err"); return; } // FIXME: Type coercion should be done consistently somewhere. bool res; bool success = executor.solver->mustBeTrue(*s,EqExpr::create(ZExtExpr::create(arguments[1], Context::get().getPointerWidth()), mo->getSizeExpr()), res); assert(success && "FIXME: Unhandled solver failure"); if (res) { executor.executeMakeSymbolic(*s, mo); } else { executor.terminateStateOnError(*s, "wrong size given to klee_make_symbolic[_name]", "user.err"); } } }
void SpecialFunctionHandler::handleMarkGlobal(ExecutionState &state, KInstruction *target, std::vector<ref<Expr> > &arguments) { assert( arguments.size() == 1 && "invalid number of arguments to klee_mark_global"); Executor::ExactResolutionList rl; executor.resolveExact(state, arguments[0], rl, "mark_global"); for (Executor::ExactResolutionList::iterator it = rl.begin(), ie = rl.end(); it != ie; ++it) { const MemoryObject *mo = it->first.first; assert(!mo->isLocal); mo->isGlobal = true; } }
void SpecialFunctionHandler::handleRealloc(ExecutionState &state, KInstruction *target, std::vector<ref<Expr> > &arguments) { // XXX should type check args assert(arguments.size()==2 && "invalid number of arguments to realloc"); ref<Expr> address = arguments[0]; ref<Expr> size = arguments[1]; Executor::StatePair zeroSize = executor.fork(state, Expr::createIsZero(size), true); if (zeroSize.first) { // size == 0 executor.executeFree(*zeroSize.first, address, target); } if (zeroSize.second) { // size != 0 Executor::StatePair zeroPointer = executor.fork(*zeroSize.second, Expr::createIsZero(address), true); if (zeroPointer.first) { // address == 0 executor.executeAlloc(*zeroPointer.first, size, false, target); } if (zeroPointer.second) { // address != 0 Executor::ExactResolutionList rl; executor.resolveExact(*zeroPointer.second, address, rl, "realloc"); for (Executor::ExactResolutionList::iterator it = rl.begin(), ie = rl.end(); it != ie; ++it) { executor.executeAlloc(*it->second, size, false, target, false, it->first.second); } } } }