klee
SeedInfo.cpp
Go to the documentation of this file.
1//===-- SeedInfo.cpp ------------------------------------------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SeedInfo.h"
11
12#include "ExecutionState.h"
13#include "Memory.h"
14#include "TimingSolver.h"
15
16#include "klee/ADT/KTest.h"
17#include "klee/Expr/Expr.h"
18#include "klee/Expr/ExprUtil.h"
19#include "klee/ADT/KTest.h"
21
22using namespace klee;
23
24KTestObject *SeedInfo::getNextInput(const MemoryObject *mo,
25 bool byName) {
26 if (byName) {
27 unsigned i;
28
29 for (i=0; i<input->numObjects; ++i) {
30 KTestObject *obj = &input->objects[i];
31 if (std::string(obj->name) == mo->name)
32 if (used.insert(obj).second)
33 return obj;
34 }
35
36 // If first unused input matches in size then accept that as
37 // well.
38 for (i=0; i<input->numObjects; ++i)
39 if (!used.count(&input->objects[i]))
40 break;
41 if (i<input->numObjects) {
42 KTestObject *obj = &input->objects[i];
43 if (obj->numBytes == mo->size) {
44 used.insert(obj);
45 klee_warning_once(mo, "using seed input %s[%d] for: %s (no name match)",
46 obj->name, obj->numBytes, mo->name.c_str());
47 return obj;
48 }
49 }
50
51 klee_warning_once(mo, "no seed input for: %s", mo->name.c_str());
52 return 0;
53 } else {
55 return 0;
56 } else {
57 return &input->objects[inputPosition++];
58 }
59 }
60}
61
63 ref<Expr> condition,
64 TimingSolver *solver) {
65 ConstraintSet required(state.constraints);
66 ConstraintManager cm(required);
67 cm.addConstraint(condition);
68
69 // Try and patch direct reads first, this is likely to resolve the
70 // problem quickly and avoids long traversal of all seed
71 // values. There are other smart ways to do this, the nicest is if
72 // we got a minimal counterexample from STP, in which case we would
73 // just inject those values back into the seed.
74 std::set< std::pair<const Array*, unsigned> > directReads;
75 std::vector< ref<ReadExpr> > reads;
76 findReads(condition, false, reads);
77 for (std::vector< ref<ReadExpr> >::iterator it = reads.begin(),
78 ie = reads.end(); it != ie; ++it) {
79 ReadExpr *re = it->get();
80 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(re->index)) {
81 directReads.insert(std::make_pair(re->updates.root,
82 (unsigned) CE->getZExtValue(32)));
83 }
84 }
85
86 for (std::set< std::pair<const Array*, unsigned> >::iterator
87 it = directReads.begin(), ie = directReads.end(); it != ie; ++it) {
88 const Array *array = it->first;
89 unsigned i = it->second;
90 ref<Expr> read = ReadExpr::create(UpdateList(array, 0),
92
93 // If not in bindings then this can't be a violation?
94 Assignment::bindings_ty::iterator it2 = assignment.bindings.find(array);
95 if (it2 != assignment.bindings.end()) {
96 ref<Expr> isSeed = EqExpr::create(read,
97 ConstantExpr::alloc(it2->second[i],
98 Expr::Int8));
99 bool res;
100 bool success =
101 solver->mustBeFalse(required, isSeed, res, state.queryMetaData);
102 assert(success && "FIXME: Unhandled solver failure");
103 (void) success;
104 if (res) {
105 ref<ConstantExpr> value;
106 bool success =
107 solver->getValue(required, read, value, state.queryMetaData);
108 assert(success && "FIXME: Unhandled solver failure");
109 (void) success;
110 it2->second[i] = value->getZExtValue(8);
111 cm.addConstraint(EqExpr::create(
112 read, ConstantExpr::alloc(it2->second[i], Expr::Int8)));
113 } else {
114 cm.addConstraint(isSeed);
115 }
116 }
117 }
118
119 bool res;
120 bool success =
121 solver->mayBeTrue(state.constraints, assignment.evaluate(condition), res,
122 state.queryMetaData);
123 assert(success && "FIXME: Unhandled solver failure");
124 (void) success;
125 if (res)
126 return;
127
128 // We could still do a lot better than this, for example by looking at
129 // independence. But really, this shouldn't be happening often.
130 for (Assignment::bindings_ty::iterator it = assignment.bindings.begin(),
131 ie = assignment.bindings.end(); it != ie; ++it) {
132 const Array *array = it->first;
133 for (unsigned i=0; i<array->size; ++i) {
134 ref<Expr> read = ReadExpr::create(UpdateList(array, 0),
136 ref<Expr> isSeed = EqExpr::create(read,
137 ConstantExpr::alloc(it->second[i],
138 Expr::Int8));
139 bool res;
140 bool success =
141 solver->mustBeFalse(required, isSeed, res, state.queryMetaData);
142 assert(success && "FIXME: Unhandled solver failure");
143 (void) success;
144 if (res) {
145 ref<ConstantExpr> value;
146 bool success =
147 solver->getValue(required, read, value, state.queryMetaData);
148 assert(success && "FIXME: Unhandled solver failure");
149 (void) success;
150 it->second[i] = value->getZExtValue(8);
151 cm.addConstraint(EqExpr::create(
152 read, ConstantExpr::alloc(it->second[i], Expr::Int8)));
153 } else {
154 cm.addConstraint(isSeed);
155 }
156 }
157 }
158
159#ifndef NDEBUG
160 {
161 bool res;
162 bool success =
163 solver->mayBeTrue(state.constraints, assignment.evaluate(condition),
164 res, state.queryMetaData);
165 assert(success && "FIXME: Unhandled solver failure");
166 (void) success;
167 assert(res && "seed patching failed");
168 }
169#endif
170}
const unsigned size
Definition: Expr.h:489
ref< Expr > evaluate(const Array *mo, unsigned index) const
Definition: Assignment.h:69
bindings_ty bindings
Definition: Assignment.h:26
static ref< ConstantExpr > alloc(const llvm::APInt &v)
Definition: Expr.h:1065
Manages constraints, e.g. optimisation.
Definition: Constraints.h:50
void addConstraint(const ref< Expr > &constraint)
ExecutionState representing a path under exploration.
SolverQueryMetaData queryMetaData
Statistics and information.
ConstraintSet constraints
Constraints collected so far.
static const Width Int32
Definition: Expr.h:103
static const Width Int8
Definition: Expr.h:101
unsigned size
size in bytes
Definition: Memory.h:52
std::string name
Definition: Memory.h:53
Class representing a one byte read from an array.
Definition: Expr.h:565
ref< Expr > index
Definition: Expr.h:572
UpdateList updates
Definition: Expr.h:571
static ref< Expr > create(const UpdateList &updates, ref< Expr > i)
Definition: Expr.cpp:538
std::set< struct KTestObject * > used
Definition: SeedInfo.h:30
KTest * input
Definition: SeedInfo.h:28
unsigned inputPosition
Definition: SeedInfo.h:29
Assignment assignment
Definition: SeedInfo.h:27
void patchSeed(const ExecutionState &state, ref< Expr > condition, TimingSolver *solver)
Definition: SeedInfo.cpp:62
bool getValue(const ConstraintSet &, ref< Expr > expr, ref< ConstantExpr > &result, SolverQueryMetaData &metaData)
bool mustBeFalse(const ConstraintSet &, ref< Expr >, bool &result, SolverQueryMetaData &metaData)
bool mayBeTrue(const ConstraintSet &, ref< Expr >, bool &result, SolverQueryMetaData &metaData)
Class representing a complete list of updates into an array.
Definition: Expr.h:539
const Array * root
Definition: Expr.h:543
Definition: main.cpp:291
void findReads(ref< Expr > e, bool visitUpdates, std::vector< ref< ReadExpr > > &result)
Definition: ExprUtil.cpp:19
void void void void klee_warning_once(const void *id, const char *msg,...) __attribute__((format(printf
char * name
Definition: KTest.h:19
unsigned numBytes
Definition: KTest.h:20
unsigned numObjects
Definition: KTest.h:35
KTestObject * objects
Definition: KTest.h:36