Executor.h

Go to the documentation of this file.
00001 //===-- Executor.h ----------------------------------------------*- C++ -*-===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Class to perform actual execution, hides implementation details from external
00011 // interpreter.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef KLEE_EXECUTOR_H
00016 #define KLEE_EXECUTOR_H
00017 
00018 #include "klee/ExecutionState.h"
00019 #include "klee/Interpreter.h"
00020 #include "klee/Internal/Module/Cell.h"
00021 #include "klee/Internal/Module/KInstruction.h"
00022 #include "klee/Internal/Module/KModule.h"
00023 #include "llvm/Support/CallSite.h"
00024 #include <vector>
00025 #include <string>
00026 #include <map>
00027 #include <set>
00028 
00029 struct KTest;
00030 
00031 namespace llvm {
00032   class BasicBlock;
00033   class BranchInst;
00034   class CallInst;
00035   class Constant;
00036   class ConstantExpr;
00037   class Function;
00038   class GlobalValue;
00039   class Instruction;
00040   class TargetData;
00041   class Value;
00042 }
00043 
00044 namespace klee {  
00045   class Cell;
00046   class ExecutionState;
00047   class ExternalDispatcher;
00048   class Expr;
00049   class InstructionInfoTable;
00050   class KFunction;
00051   class KInstruction;
00052   class KInstIterator;
00053   class KModule;
00054   class MemoryManager;
00055   class MemoryObject;
00056   class ObjectState;
00057   class PTree;
00058   class Searcher;
00059   class SeedInfo;
00060   class SpecialFunctionHandler;
00061   class StackFrame;
00062   class StatsTracker;
00063   class TimingSolver;
00064   class TreeStreamWriter;
00065   template<class T> class ref;
00066 
00070 
00071 class Executor : public Interpreter {
00072   friend class BumpMergingSearcher;
00073   friend class MergingSearcher;
00074   friend class RandomPathSearcher;
00075   friend class OwningSearcher;
00076   friend class WeightedRandomSearcher;
00077   friend class SpecialFunctionHandler;
00078   friend class StatsTracker;
00079 
00080 public:
00081   class Timer {
00082   public:
00083     Timer();
00084     virtual ~Timer();
00085 
00087     virtual void run() = 0;
00088   };
00089 
00090   typedef std::pair<ExecutionState*,ExecutionState*> StatePair;
00091 
00092 private:
00093   class TimerInfo;
00094 
00095   KModule *kmodule;
00096   InterpreterHandler *interpreterHandler;
00097   Searcher *searcher;
00098 
00099   ExternalDispatcher *externalDispatcher;
00100   TimingSolver *solver;
00101   MemoryManager *memory;
00102   std::set<ExecutionState*> states;
00103   StatsTracker *statsTracker;
00104   TreeStreamWriter *pathWriter, *symPathWriter;
00105   SpecialFunctionHandler *specialFunctionHandler;
00106   std::vector<TimerInfo*> timers;
00107   PTree *processTree;
00108 
00113   std::set<ExecutionState*> addedStates;
00118   std::set<ExecutionState*> removedStates;
00119 
00127   std::map<ExecutionState*, std::vector<SeedInfo> > seedMap;
00128   
00130   std::map<const llvm::GlobalValue*, MemoryObject*> globalObjects;
00131 
00134   std::map<const llvm::GlobalValue*, ref<Expr> > globalAddresses;
00135 
00138   std::set<void*> legalFunctions;
00139 
00142   const struct KTest *replayOut;
00144   const std::vector<bool> *replayPath;
00147   unsigned replayPosition;
00148 
00151   const std::vector<struct KTest *> *usingSeeds;  
00152 
00155   bool atMemoryLimit;
00156 
00158   bool inhibitForking;
00159 
00162   bool haltExecution;  
00163 
00166   bool ivcEnabled;
00167 
00169   double stpTimeout;  
00170 
00171   llvm::Function* getCalledFunction(llvm::CallSite &cs, ExecutionState &state);
00172   
00173   void executeInstruction(ExecutionState &state, KInstruction *ki);
00174 
00175   void printFileLine(ExecutionState &state, KInstruction *ki);
00176 
00177   void run(ExecutionState &initialState);
00178 
00179   // Given a concrete object in our [klee's] address space, add it to 
00180   // objects checked code can reference.
00181   MemoryObject *addExternalObject(ExecutionState &state, void *addr, 
00182                                   unsigned size, bool isReadOnly);
00183 
00184   void initializeGlobalObject(ExecutionState &state, ObjectState *os, 
00185                               llvm::Constant *c,
00186                               unsigned offset);
00187   void initializeGlobals(ExecutionState &state);
00188 
00189   void stepInstruction(ExecutionState &state);
00190   void updateStates(ExecutionState *current);
00191   void transferToBasicBlock(llvm::BasicBlock *dst, 
00192                             llvm::BasicBlock *src,
00193                             ExecutionState &state);
00194 
00195   void callExternalFunction(ExecutionState &state,
00196                             KInstruction *target,
00197                             llvm::Function *function,
00198                             std::vector< ref<Expr> > &arguments);
00199 
00200   ObjectState *bindObjectInState(ExecutionState &state, const MemoryObject *mo,
00201                                  bool isLocal);
00202 
00211   typedef std::vector< std::pair<std::pair<const MemoryObject*, const ObjectState*>, 
00212                                  ExecutionState*> > ExactResolutionList;
00213   void resolveExact(ExecutionState &state,
00214                     ref<Expr> p,
00215                     ExactResolutionList &results,
00216                     const std::string &name);
00217 
00233   void executeAlloc(ExecutionState &state,
00234                     ref<Expr> size,
00235                     bool isLocal,
00236                     KInstruction *target,
00237                     bool zeroMemory=false,
00238                     const ObjectState *reallocFrom=0);
00239 
00245   void executeFree(ExecutionState &state,
00246                    ref<Expr> address,
00247                    KInstruction *target = 0);
00248   
00249   void executeCall(ExecutionState &state, 
00250                    KInstruction *ki,
00251                    llvm::Function *f,
00252                    std::vector< ref<Expr> > &arguments);
00253                    
00254   // do address resolution / object binding / out of bounds checking
00255   // and perform the operation
00256   void executeMemoryOperation(ExecutionState &state,
00257                               bool isWrite,
00258                               ref<Expr> address,
00259                               ref<Expr> value /* undef if read */,
00260                               KInstruction *target /* undef if write */);
00261 
00262   void executeMakeSymbolic(ExecutionState &state, const MemoryObject *mo);
00263 
00268   void branch(ExecutionState &state, 
00269               const std::vector< ref<Expr> > &conditions,
00270               std::vector<ExecutionState*> &result);
00271 
00272   // Fork current and return states in which condition holds / does
00273   // not hold, respectively. One of the states is necessarily the
00274   // current state, and one of the states may be null.
00275   StatePair fork(ExecutionState &current, ref<Expr> condition, bool isInternal);
00276 
00281   void addConstraint(ExecutionState &state, ref<Expr> condition);
00282 
00283   // Called on [for now] concrete reads, replaces constant with a symbolic
00284   // Used for testing.
00285   ref<Expr> replaceReadWithSymbolic(ExecutionState &state, ref<Expr> e);
00286 
00287   const Cell& eval(KInstruction *ki, unsigned index, 
00288                    ExecutionState &state) const;
00289 
00290   Cell& getArgumentCell(ExecutionState &state,
00291                         KFunction *kf,
00292                         unsigned index) {
00293     return state.stack.back().locals[kf->getArgRegister(index)];
00294   }
00295 
00296   Cell& getDestCell(ExecutionState &state,
00297                     KInstruction *target) {
00298     return state.stack.back().locals[target->dest];
00299   }
00300 
00301   void bindLocal(KInstruction *target, 
00302                  ExecutionState &state, 
00303                  ref<Expr> value);
00304   void bindArgument(KFunction *kf, 
00305                     unsigned index,
00306                     ExecutionState &state,
00307                     ref<Expr> value);
00308 
00309   ref<Expr> evalConstantExpr(llvm::ConstantExpr *ce);
00310 
00314   ref<Expr> toUnique(const ExecutionState &state, ref<Expr> &e);
00315 
00322   ref<klee::ConstantExpr> toConstant(ExecutionState &state, ref<Expr> e, 
00323                                      const char *purpose);
00324 
00327   void executeGetValue(ExecutionState &state, ref<Expr> e, KInstruction *target);
00328 
00330   std::string getAddressInfo(ExecutionState &state, ref<Expr> address) const;
00331 
00332   // remove state from queue and delete
00333   void terminateState(ExecutionState &state);
00334   // call exit handler and terminate state
00335   void terminateStateEarly(ExecutionState &state, std::string message);
00336   // call exit handler and terminate state
00337   void terminateStateOnExit(ExecutionState &state);
00338   // call error handler and terminate state
00339   void terminateStateOnError(ExecutionState &state, 
00340                              const std::string &message,
00341                              const std::string &suffix,
00342                              const std::string &longMessage="");
00343 
00344   // call error handler and terminate state, for execution errors
00345   // (things that should not be possible, like illegal instruction or
00346   // unlowered instrinsic, or are unsupported, like inline assembly)
00347   void terminateStateOnExecError(ExecutionState &state, 
00348                                  const std::string &message,
00349                                  const std::string &info="") {
00350     terminateStateOnError(state, message, "exec.err", info);
00351   }
00352 
00354   void bindModuleConstants();
00355 
00358   void bindInstructionConstants(KInstruction *KI);
00359 
00360   void handlePointsToObj(ExecutionState &state, 
00361                          KInstruction *target, 
00362                          const std::vector<ref<Expr> > &arguments);
00363 
00364   void doImpliedValueConcretization(ExecutionState &state,
00365                                     ref<Expr> e,
00366                                     ref<ConstantExpr> value);
00367 
00372   void addTimer(Timer *timer, double rate);
00373 
00374   void initTimers();
00375   void processTimers(ExecutionState *current,
00376                      double maxInstTime);
00377                 
00378 public:
00379   Executor(const InterpreterOptions &opts, InterpreterHandler *ie);
00380   virtual ~Executor();
00381 
00382   const InterpreterHandler& getHandler() {
00383     return *interpreterHandler;
00384   }
00385 
00386   // XXX should just be moved out to utility module
00387   ref<Expr> evalConstant(llvm::Constant *c);
00388 
00389   virtual void setPathWriter(TreeStreamWriter *tsw) {
00390     pathWriter = tsw;
00391   }
00392   virtual void setSymbolicPathWriter(TreeStreamWriter *tsw) {
00393     symPathWriter = tsw;
00394   }      
00395 
00396   virtual void setReplayOut(const struct KTest *out) {
00397     assert(!replayPath && "cannot replay both buffer and path");
00398     replayOut = out;
00399     replayPosition = 0;
00400   }
00401 
00402   virtual void setReplayPath(const std::vector<bool> *path) {
00403     assert(!replayOut && "cannot replay both buffer and path");
00404     replayPath = path;
00405     replayPosition = 0;
00406   }
00407 
00408   virtual const llvm::Module *
00409   setModule(llvm::Module *module, const ModuleOptions &opts);
00410 
00411   virtual void useSeeds(const std::vector<struct KTest *> *seeds) { 
00412     usingSeeds = seeds;
00413   }
00414 
00415   virtual void runFunctionAsMain(llvm::Function *f,
00416                                  int argc,
00417                                  char **argv,
00418                                  char **envp);
00419 
00420   /*** Runtime options ***/
00421   
00422   virtual void setHaltExecution(bool value) {
00423     haltExecution = value;
00424   }
00425 
00426   virtual void setInhibitForking(bool value) {
00427     inhibitForking = value;
00428   }
00429 
00430   /*** State accessor methods ***/
00431 
00432   virtual unsigned getPathStreamID(const ExecutionState &state);
00433 
00434   virtual unsigned getSymbolicPathStreamID(const ExecutionState &state);
00435 
00436   virtual void getConstraintLog(const ExecutionState &state,
00437                                 std::string &res,
00438                                 bool asCVC = false);
00439 
00440   virtual bool getSymbolicSolution(const ExecutionState &state, 
00441                                    std::vector< 
00442                                    std::pair<std::string,
00443                                    std::vector<unsigned char> > >
00444                                    &res);
00445 
00446   virtual void getCoveredLines(const ExecutionState &state,
00447                                std::map<const std::string*, std::set<unsigned> > &res);
00448 };
00449   
00450 } // End klee namespace
00451 
00452 #endif

Generated on Fri Jun 5 03:31:31 2009 for klee by  doxygen 1.5.8