00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Common.h"
00011
00012 #include "Memory.h"
00013 #include "SeedInfo.h"
00014 #include "TimingSolver.h"
00015
00016 #include "klee/ExecutionState.h"
00017 #include "klee/Expr.h"
00018 #include "klee/util/ExprUtil.h"
00019 #include "klee/Internal/ADT/KTest.h"
00020
00021 using namespace klee;
00022
00023 KTestObject *SeedInfo::getNextInput(const MemoryObject *mo,
00024 bool byName) {
00025 if (byName) {
00026 unsigned i;
00027
00028 for (i=0; i<input->numObjects; ++i) {
00029 KTestObject *obj = &input->objects[i];
00030 if (std::string(obj->name) == mo->name)
00031 if (used.insert(obj).second)
00032 return obj;
00033 }
00034
00035
00036
00037 for (i=0; i<input->numObjects; ++i)
00038 if (!used.count(&input->objects[i]))
00039 break;
00040 if (i<input->numObjects) {
00041 KTestObject *obj = &input->objects[i];
00042 if (obj->numBytes == mo->size) {
00043 used.insert(obj);
00044 klee_warning_once(mo, "using seed input %s[%d] for: %s (no name match)",
00045 obj->name, obj->numBytes, mo->name.c_str());
00046 return obj;
00047 }
00048 }
00049
00050 klee_warning_once(mo, "no seed input for: %s", mo->name.c_str());
00051 return 0;
00052 } else {
00053 if (inputPosition >= input->numObjects) {
00054 return 0;
00055 } else {
00056 return &input->objects[inputPosition++];
00057 }
00058 }
00059 }
00060
00061 void SeedInfo::patchSeed(const ExecutionState &state,
00062 ref<Expr> condition,
00063 TimingSolver *solver) {
00064 std::vector< ref<Expr> > required(state.constraints.begin(),
00065 state.constraints.end());
00066 ExecutionState tmp(required);
00067 tmp.addConstraint(condition);
00068
00069
00070
00071
00072
00073
00074 std::set< std::pair<const Array*, unsigned> > directReads;
00075 std::vector< ref<ReadExpr> > reads;
00076 findReads(condition, false, reads);
00077 for (std::vector< ref<ReadExpr> >::iterator it = reads.begin(),
00078 ie = reads.end(); it != ie; ++it) {
00079 ReadExpr *re = it->get();
00080 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(re->index)) {
00081 directReads.insert(std::make_pair(re->updates.root,
00082 (unsigned) CE->getConstantValue()));
00083 }
00084 }
00085
00086 for (std::set< std::pair<const Array*, unsigned> >::iterator
00087 it = directReads.begin(), ie = directReads.end(); it != ie; ++it) {
00088 const Array *array = it->first;
00089 unsigned i = it->second;
00090 ref<Expr> read = ReadExpr::create(UpdateList(array, true, 0),
00091 ConstantExpr::alloc(i, Expr::Int32));
00092
00093
00094 Assignment::bindings_ty::iterator it2 = assignment.bindings.find(array);
00095 if (it2 != assignment.bindings.end()) {
00096 ref<Expr> isSeed = EqExpr::create(read, ConstantExpr::alloc(it2->second[i], Expr::Int8));
00097 bool res;
00098 bool success = solver->mustBeFalse(tmp, isSeed, res);
00099 assert(success && "FIXME: Unhandled solver failure");
00100 (void) success;
00101 if (res) {
00102 ref<ConstantExpr> value;
00103 bool success = solver->getValue(tmp, read, value);
00104 assert(success && "FIXME: Unhandled solver failure");
00105 (void) success;
00106 it2->second[i] = value->getConstantValue();
00107 tmp.addConstraint(EqExpr::create(read, ConstantExpr::alloc(it2->second[i], Expr::Int8)));
00108 } else {
00109 tmp.addConstraint(isSeed);
00110 }
00111 }
00112 }
00113
00114 bool res;
00115 bool success = solver->mayBeTrue(state, assignment.evaluate(condition), res);
00116 assert(success && "FIXME: Unhandled solver failure");
00117 (void) success;
00118 if (res)
00119 return;
00120
00121
00122
00123 for (Assignment::bindings_ty::iterator it = assignment.bindings.begin(),
00124 ie = assignment.bindings.end(); it != ie; ++it) {
00125 const Array *array = it->first;
00126 for (unsigned i=0; i<array->size; ++i) {
00127 ref<Expr> read = ReadExpr::create(UpdateList(array, true, 0),
00128 ConstantExpr::alloc(i, Expr::Int32));
00129 ref<Expr> isSeed = EqExpr::create(read, ConstantExpr::alloc(it->second[i], Expr::Int8));
00130 bool res;
00131 bool success = solver->mustBeFalse(tmp, isSeed, res);
00132 assert(success && "FIXME: Unhandled solver failure");
00133 (void) success;
00134 if (res) {
00135 ref<ConstantExpr> value;
00136 bool success = solver->getValue(tmp, read, value);
00137 assert(success && "FIXME: Unhandled solver failure");
00138 (void) success;
00139 it->second[i] = value->getConstantValue();
00140 tmp.addConstraint(EqExpr::create(read, ConstantExpr::alloc(it->second[i], Expr::Int8)));
00141 } else {
00142 tmp.addConstraint(isSeed);
00143 }
00144 }
00145 }
00146
00147 #ifndef NDEBUG
00148 {
00149 bool res;
00150 bool success =
00151 solver->mayBeTrue(state, assignment.evaluate(condition), res);
00152 assert(success && "FIXME: Unhandled solver failure");
00153 (void) success;
00154 assert(res && "seed patching failed");
00155 }
00156 #endif
00157 }