ExecutionState.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef KLEE_EXECUTIONSTATE_H
00011 #define KLEE_EXECUTIONSTATE_H
00012
00013 #include "klee/Constraints.h"
00014 #include "klee/Expr.h"
00015 #include "klee/Internal/ADT/TreeStream.h"
00016
00017
00018 #include "../../lib/Core/AddressSpace.h"
00019 #include "klee/Internal/Module/KInstIterator.h"
00020
00021 #include <map>
00022 #include <set>
00023 #include <vector>
00024
00025 namespace klee {
00026 class CallPathNode;
00027 class Cell;
00028 class KFunction;
00029 class KInstruction;
00030 class MemoryObject;
00031 class PTreeNode;
00032 class InstructionInfo;
00033 class ExecutionTraceEvent;
00034
00035 std::ostream &operator<<(std::ostream &os, const MemoryMap &mm);
00036
00037 struct StackFrame {
00038 KInstIterator caller;
00039 KFunction *kf;
00040 CallPathNode *callPathNode;
00041
00042 std::vector<const MemoryObject*> allocas;
00043 Cell *locals;
00044
00050 unsigned minDistToUncoveredOnReturn;
00051
00052
00053
00054
00055
00056
00057 MemoryObject *varargs;
00058
00059 StackFrame(KInstIterator caller, KFunction *kf);
00060 StackFrame(const StackFrame &s);
00061 ~StackFrame();
00062 };
00063
00064
00065
00066
00067
00068 class ExecutionTraceManager {
00069 public:
00070 ExecutionTraceManager() : hasSeenUserMain(false) {}
00071
00072 void addEvent(ExecutionTraceEvent* evt);
00073 void printAllEvents(std::ostream &os) const;
00074
00075 private:
00076
00077
00078
00079 bool hasSeenUserMain;
00080
00081
00082
00083
00084
00085
00086 std::vector<ExecutionTraceEvent*> events;
00087 };
00088
00089
00090 class ExecutionState {
00091 public:
00092 typedef std::vector<StackFrame> stack_ty;
00093
00094 private:
00095
00096 ExecutionState &operator=(const ExecutionState&);
00097 std::map< std::string, std::string > fnAliases;
00098
00099 public:
00100 bool fakeState;
00101
00102
00103 unsigned underConstrained;
00104 unsigned depth;
00105
00106
00107 KInstIterator pc, prevPC;
00108 stack_ty stack;
00109 ConstraintManager constraints;
00110 mutable double queryCost;
00111 double weight;
00112 AddressSpace addressSpace;
00113 TreeOStream pathOS, symPathOS;
00114 unsigned instsSinceCovNew;
00115 bool coveredNew;
00116
00117
00118 ExecutionTraceManager exeTraceMgr;
00119
00121 bool forkDisabled;
00122
00123 std::map<const std::string*, std::set<unsigned> > coveredLines;
00124 PTreeNode *ptreeNode;
00125
00127
00128
00129 std::vector<const MemoryObject*> symbolics;
00130
00131
00132
00133 MemoryMap shadowObjects;
00134
00135 unsigned incomingBBIndex;
00136
00137 std::string getFnAlias(std::string fn);
00138 void addFnAlias(std::string old_fn, std::string new_fn);
00139 void removeFnAlias(std::string fn);
00140
00141 private:
00142 ExecutionState() : fakeState(false), underConstrained(0), ptreeNode(0) {};
00143
00144 public:
00145 ExecutionState(KFunction *kf);
00146
00147
00148
00149 ExecutionState(const std::vector<ref<Expr> > &assumptions);
00150
00151 ~ExecutionState();
00152
00153 ExecutionState *branch();
00154
00155 void pushFrame(KInstIterator caller, KFunction *kf);
00156 void popFrame();
00157
00158 void addSymbolic(const MemoryObject *mo) {
00159 symbolics.push_back(mo);
00160 }
00161 void addConstraint(ref<Expr> e) {
00162 constraints.addConstraint(e);
00163 }
00164
00165
00166 ObjectState *cloneObject(ObjectState *os, MemoryObject *mo);
00167
00168
00169
00170 bool merge(const ExecutionState &b);
00171 };
00172
00173
00174
00175
00176
00177 class ExecutionTraceEvent {
00178 public:
00179
00180 std::string file;
00181 unsigned line;
00182 std::string funcName;
00183 unsigned stackDepth;
00184
00185 unsigned consecutiveCount;
00186
00187
00188 ExecutionTraceEvent()
00189 : file("global"), line(0), funcName("global_def"),
00190 consecutiveCount(1) {}
00191
00192 ExecutionTraceEvent(ExecutionState& state, KInstruction* ki);
00193
00194 virtual ~ExecutionTraceEvent() {}
00195
00196 void print(std::ostream &os) const;
00197
00198
00199
00200 virtual bool ignoreMe() const;
00201
00202 private:
00203 virtual void printDetails(std::ostream &os) const = 0;
00204 };
00205
00206
00207 class FunctionCallTraceEvent : public ExecutionTraceEvent {
00208 public:
00209 std::string calleeFuncName;
00210
00211 FunctionCallTraceEvent(ExecutionState& state, KInstruction* ki,
00212 const std::string& _calleeFuncName)
00213 : ExecutionTraceEvent(state, ki), calleeFuncName(_calleeFuncName) {}
00214
00215 private:
00216 virtual void printDetails(std::ostream &os) const {
00217 os << "CALL " << calleeFuncName;
00218 }
00219
00220 };
00221
00222 class FunctionReturnTraceEvent : public ExecutionTraceEvent {
00223 public:
00224 FunctionReturnTraceEvent(ExecutionState& state, KInstruction* ki)
00225 : ExecutionTraceEvent(state, ki) {}
00226
00227 private:
00228 virtual void printDetails(std::ostream &os) const {
00229 os << "RETURN";
00230 }
00231 };
00232
00233 class BranchTraceEvent : public ExecutionTraceEvent {
00234 public:
00235 bool trueTaken;
00236 bool canForkGoBothWays;
00237
00238 BranchTraceEvent(ExecutionState& state, KInstruction* ki,
00239 bool _trueTaken, bool _isTwoWay)
00240 : ExecutionTraceEvent(state, ki),
00241 trueTaken(_trueTaken),
00242 canForkGoBothWays(_isTwoWay) {}
00243
00244 private:
00245 virtual void printDetails(std::ostream &os) const;
00246 };
00247
00248 }
00249
00250 #endif