SpecialFunctionHandler.cpp

Go to the documentation of this file.
00001 //===-- SpecialFunctionHandler.cpp ----------------------------------------===//
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 #include "Common.h"
00011 
00012 #include "Memory.h"
00013 #include "SpecialFunctionHandler.h"
00014 #include "TimingSolver.h"
00015 
00016 #include "klee/ExecutionState.h"
00017 
00018 #include "klee/Internal/Module/KInstruction.h"
00019 #include "klee/Internal/Module/KModule.h"
00020 
00021 #include "Executor.h"
00022 #include "MemoryManager.h"
00023 
00024 #include "llvm/Module.h"
00025 
00026 #include <errno.h>
00027 
00028 using namespace llvm;
00029 using namespace klee;
00030 
00033 
00035 
00036 struct HandlerInfo {
00037   const char *name;
00038   SpecialFunctionHandler::Handler handler;
00039   bool doesNotReturn; 
00040   bool hasReturnValue; 
00041   bool doNotOverride; 
00042 };
00043 
00044 // FIXME: We are more or less committed to requiring an intrinsic
00045 // library these days. We can move some of this stuff there,
00046 // especially things like realloc which have complicated semantics
00047 // w.r.t. forking. Among other things this makes delayed query
00048 // dispatch easier to implement.
00049 HandlerInfo handlerInfo[] = {
00050 #define add(name, handler, ret) { name, \
00051                                   &SpecialFunctionHandler::handler, \
00052                                   false, ret, false }
00053 #define addDNR(name, handler) { name, \
00054                                 &SpecialFunctionHandler::handler, \
00055                                 true, false, false }
00056   addDNR("__assert_rtn", handleAssertFail),
00057   addDNR("__assert_fail", handleAssertFail),
00058   addDNR("_assert", handleAssert),
00059   addDNR("abort", handleAbort),
00060   addDNR("_exit", handleExit),
00061   { "exit", &SpecialFunctionHandler::handleExit, true, false, true },
00062   addDNR("klee_abort", handleAbort),
00063   addDNR("klee_silent_exit", handleSilentExit),  
00064   addDNR("klee_report_error", handleReportError),
00065 
00066   add("calloc", handleCalloc, true),
00067   add("free", handleFree, false),
00068   add("klee_assume", handleAssume, false),
00069   add("klee_check_memory_access", handleCheckMemoryAccess, false),
00070   add("klee_get_value", handleGetValue, true),
00071   add("klee_define_fixed_object", handleDefineFixedObject, false),
00072   add("klee_get_obj_size", handleGetObjSize, true),
00073   add("klee_get_errno", handleGetErrno, true),
00074   add("klee_is_symbolic", handleIsSymbolic, true),
00075   add("klee_make_symbolic", handleMakeSymbolic, false),
00076   add("klee_mark_global", handleMarkGlobal, false),
00077   add("klee_merge", handleMerge, false),
00078   add("klee_prefer_cex", handlePreferCex, false),
00079   add("klee_print_expr", handlePrintExpr, false),
00080   add("klee_print_range", handlePrintRange, false),
00081   add("klee_set_forking", handleSetForking, false),
00082   add("klee_warning", handleWarning, false),
00083   add("klee_warning_once", handleWarningOnce, false),
00084   add("klee_under_constrained", handleUnderConstrained, false),
00085   add("klee_alias_function", handleAliasFunction, false),
00086   add("malloc", handleMalloc, true),
00087   add("realloc", handleRealloc, true),
00088 
00089   // operator delete[](void*)
00090   add("_ZdaPv", handleDeleteArray, false),
00091   // operator delete(void*)
00092   add("_ZdlPv", handleDelete, false),
00093 
00094   // operator new[](unsigned int)
00095   add("_Znaj", handleNewArray, true),
00096   // operator new(unsigned int)
00097   add("_Znwj", handleNew, true),
00098 
00099   // FIXME-64: This is wrong for 64-bit long...
00100 
00101   // operator new[](unsigned long)
00102   add("_Znam", handleNewArray, true),
00103   // operator new(unsigned long)
00104   add("_Znwm", handleNew, true),
00105 
00106 #undef addDNR
00107 #undef add  
00108 };
00109 
00110 SpecialFunctionHandler::SpecialFunctionHandler(Executor &_executor) 
00111   : executor(_executor) {}
00112 
00113 
00114 void SpecialFunctionHandler::prepare() {
00115   unsigned N = sizeof(handlerInfo)/sizeof(handlerInfo[0]);
00116 
00117   for (unsigned i=0; i<N; ++i) {
00118     HandlerInfo &hi = handlerInfo[i];
00119     Function *f = executor.kmodule->module->getFunction(hi.name);
00120     
00121     // No need to create if the function doesn't exist, since it cannot
00122     // be called in that case.
00123   
00124     if (f && (!hi.doNotOverride || f->isDeclaration())) {
00125       // Make sure NoReturn attribute is set, for optimization and
00126       // coverage counting.
00127       if (hi.doesNotReturn)
00128         f->addFnAttr(Attribute::NoReturn);
00129 
00130       // Change to a declaration since we handle internally (simplifies
00131       // module and allows deleting dead code).
00132       if (!f->isDeclaration())
00133         f->deleteBody();
00134     }
00135   }
00136 }
00137 
00138 void SpecialFunctionHandler::bind() {
00139   unsigned N = sizeof(handlerInfo)/sizeof(handlerInfo[0]);
00140 
00141   for (unsigned i=0; i<N; ++i) {
00142     HandlerInfo &hi = handlerInfo[i];
00143     Function *f = executor.kmodule->module->getFunction(hi.name);
00144     
00145     if (f && (!hi.doNotOverride || f->isDeclaration()))
00146       handlers[f] = std::make_pair(hi.handler, hi.hasReturnValue);
00147   }
00148 }
00149 
00150 
00151 bool SpecialFunctionHandler::handle(ExecutionState &state, 
00152                                     Function *f,
00153                                     KInstruction *target,
00154                                     std::vector< ref<Expr> > &arguments) {
00155   handlers_ty::iterator it = handlers.find(f);
00156   if (it != handlers.end()) {    
00157     Handler h = it->second.first;
00158     bool hasReturnValue = it->second.second;
00159      // FIXME: Check this... add test?
00160     if (!hasReturnValue && !target->inst->use_empty()) {
00161       executor.terminateStateOnExecError(state, 
00162                                          "expected return value from void special function");
00163     } else {
00164       (this->*h)(state, target, arguments);
00165     }
00166     return true;
00167   } else {
00168     return false;
00169   }
00170 }
00171 
00172 /****/
00173 
00174 // reads a concrete string from memory
00175 std::string 
00176 SpecialFunctionHandler::readStringAtAddress(ExecutionState &state, 
00177                                             ref<Expr> addressExpr) {
00178   ObjectPair op;
00179   addressExpr = executor.toUnique(state, addressExpr);
00180   ref<ConstantExpr> address = cast<ConstantExpr>(addressExpr);
00181   if (!state.addressSpace.resolveOne(address->getConstantValue(), op))
00182     assert(0 && "XXX out of bounds / multiple resolution unhandled");
00183   bool res;
00184   assert(executor.solver->mustBeTrue(state, 
00185                                      EqExpr::create(address, 
00186                                                     op.first->getBaseExpr()),
00187                                      res) &&
00188          res &&
00189          "XXX interior pointer unhandled");
00190   const MemoryObject *mo = op.first;
00191   const ObjectState *os = op.second;
00192 
00193   char *buf = new char[mo->size];
00194 
00195   unsigned i;
00196   for (i = 0; i < mo->size - 1; i++) {
00197     ref<Expr> cur = os->read8(i);
00198     cur = executor.toUnique(state, cur);
00199     assert(isa<ConstantExpr>(cur) && 
00200            "hit symbolic char while reading concrete string");
00201     buf[i] = cast<ConstantExpr>(cur)->getConstantValue();
00202   }
00203   buf[i] = 0;
00204   
00205   std::string result(buf);
00206   delete[] buf;
00207   return result;
00208 }
00209 
00210 /****/
00211 
00212 void SpecialFunctionHandler::handleAbort(ExecutionState &state,
00213                            KInstruction *target,
00214                            std::vector<ref<Expr> > &arguments) {
00215   assert(arguments.size()==0 && "invalid number of arguments to abort");
00216 
00217   //XXX:DRE:TAINT
00218   if(state.underConstrained) {
00219     llvm::cerr << "TAINT: skipping abort fail\n";
00220     executor.terminateState(state);
00221   } else {
00222     executor.terminateStateOnError(state, "abort failure", "abort.err");
00223   }
00224 }
00225 
00226 void SpecialFunctionHandler::handleExit(ExecutionState &state,
00227                            KInstruction *target,
00228                            std::vector<ref<Expr> > &arguments) {
00229   assert(arguments.size()==1 && "invalid number of arguments to exit");
00230   executor.terminateStateOnExit(state);
00231 }
00232 
00233 void SpecialFunctionHandler::handleSilentExit(ExecutionState &state,
00234                                               KInstruction *target,
00235                                               std::vector<ref<Expr> > &arguments) {
00236   assert(arguments.size()==1 && "invalid number of arguments to exit");
00237   executor.terminateState(state);
00238 }
00239 
00240 void SpecialFunctionHandler::handleAliasFunction(ExecutionState &state,
00241                                                  KInstruction *target,
00242                                                  std::vector<ref<Expr> > &arguments) {
00243   assert(arguments.size()==2 && 
00244          "invalid number of arguments to klee_alias_function");
00245   std::string old_fn = readStringAtAddress(state, arguments[0]);
00246   std::string new_fn = readStringAtAddress(state, arguments[1]);
00247   //llvm::cerr << "Replacing " << old_fn << "() with " << new_fn << "()\n";
00248   if (old_fn == new_fn)
00249     state.removeFnAlias(old_fn);
00250   else state.addFnAlias(old_fn, new_fn);
00251 }
00252 
00253 void SpecialFunctionHandler::handleAssert(ExecutionState &state,
00254                                           KInstruction *target,
00255                                           std::vector<ref<Expr> > &arguments) {
00256   assert(arguments.size()==3 && "invalid number of arguments to _assert");  
00257   
00258   //XXX:DRE:TAINT
00259   if(state.underConstrained) {
00260     llvm::cerr << "TAINT: skipping assertion:" 
00261                << readStringAtAddress(state, arguments[0]) << "\n";
00262     executor.terminateState(state);
00263   } else
00264     executor.terminateStateOnError(state, 
00265                                    "ASSERTION FAIL: " + readStringAtAddress(state, arguments[0]),
00266                                    "assert.err");
00267 }
00268 
00269 void SpecialFunctionHandler::handleAssertFail(ExecutionState &state,
00270                                               KInstruction *target,
00271                                               std::vector<ref<Expr> > &arguments) {
00272   assert(arguments.size()==4 && "invalid number of arguments to __assert_fail");
00273   
00274   //XXX:DRE:TAINT
00275   if(state.underConstrained) {
00276     llvm::cerr << "TAINT: skipping assertion:" 
00277                << readStringAtAddress(state, arguments[0]) << "\n";
00278     executor.terminateState(state);
00279   } else
00280     executor.terminateStateOnError(state, 
00281                                    "ASSERTION FAIL: " + readStringAtAddress(state, arguments[0]),
00282                                    "assert.err");
00283 }
00284 
00285 void SpecialFunctionHandler::handleReportError(ExecutionState &state,
00286                                                KInstruction *target,
00287                                                std::vector<ref<Expr> > &arguments) {
00288   assert(arguments.size()==4 && "invalid number of arguments to klee_report_error");
00289   
00290   // arguments[0], arguments[1] are file, line
00291   
00292   //XXX:DRE:TAINT
00293   if(state.underConstrained) {
00294     llvm::cerr << "TAINT: skipping klee_report_error:"
00295                << readStringAtAddress(state, arguments[2]) << ":"
00296                << readStringAtAddress(state, arguments[3]) << "\n";
00297     executor.terminateState(state);
00298   } else
00299     executor.terminateStateOnError(state, 
00300                                    readStringAtAddress(state, arguments[2]),
00301                                    readStringAtAddress(state, arguments[3]));
00302 }
00303 
00304 void SpecialFunctionHandler::handleMerge(ExecutionState &state,
00305                            KInstruction *target,
00306                            std::vector<ref<Expr> > &arguments) {
00307   // nop
00308 }
00309 
00310 void SpecialFunctionHandler::handleNew(ExecutionState &state,
00311                          KInstruction *target,
00312                          std::vector<ref<Expr> > &arguments) {
00313   // XXX should type check args
00314   assert(arguments.size()==1 && "invalid number of arguments to new");
00315 
00316   executor.executeAlloc(state, arguments[0], false, target);
00317 }
00318 
00319 void SpecialFunctionHandler::handleDelete(ExecutionState &state,
00320                             KInstruction *target,
00321                             std::vector<ref<Expr> > &arguments) {
00322   // XXX should type check args
00323   assert(arguments.size()==1 && "invalid number of arguments to delete");
00324   executor.executeFree(state, arguments[0]);
00325 }
00326 
00327 void SpecialFunctionHandler::handleNewArray(ExecutionState &state,
00328                               KInstruction *target,
00329                               std::vector<ref<Expr> > &arguments) {
00330   // XXX should type check args
00331   assert(arguments.size()==1 && "invalid number of arguments to new[]");
00332   executor.executeAlloc(state, arguments[0], false, target);
00333 }
00334 
00335 void SpecialFunctionHandler::handleDeleteArray(ExecutionState &state,
00336                                  KInstruction *target,
00337                                  std::vector<ref<Expr> > &arguments) {
00338   // XXX should type check args
00339   assert(arguments.size()==1 && "invalid number of arguments to delete[]");
00340   executor.executeFree(state, arguments[0]);
00341 }
00342 
00343 void SpecialFunctionHandler::handleMalloc(ExecutionState &state,
00344                                   KInstruction *target,
00345                                   std::vector<ref<Expr> > &arguments) {
00346   // XXX should type check args
00347   assert(arguments.size()==1 && "invalid number of arguments to malloc");
00348   executor.executeAlloc(state, arguments[0], false, target);
00349 }
00350 
00351 void SpecialFunctionHandler::handleAssume(ExecutionState &state,
00352                             KInstruction *target,
00353                             std::vector<ref<Expr> > &arguments) {
00354   assert(arguments.size()==1 && "invalid number of arguments to klee_assume");
00355   
00356   ref<Expr> e = arguments[0];
00357   
00358   if (e->getWidth() != Expr::Bool)
00359     e = NeExpr::create(e, ConstantExpr::create(0, e->getWidth()));
00360   
00361   bool res;
00362   bool success = executor.solver->mustBeFalse(state, e, res);
00363   assert(success && "FIXME: Unhandled solver failure");
00364   if (res) {
00365     executor.terminateStateOnError(state, 
00366                                    "invalid klee_assume call (provably false)",
00367                                    "user.err");
00368   } else {
00369     executor.addConstraint(state, e);
00370   }
00371 }
00372 
00373 void SpecialFunctionHandler::handleIsSymbolic(ExecutionState &state,
00374                                 KInstruction *target,
00375                                 std::vector<ref<Expr> > &arguments) {
00376   assert(arguments.size()==1 && "invalid number of arguments to klee_is_symbolic");
00377 
00378   executor.bindLocal(target, state, 
00379                      ConstantExpr::create(!isa<ConstantExpr>(arguments[0]),
00380                                           Expr::Int32));
00381 }
00382 
00383 void SpecialFunctionHandler::handlePreferCex(ExecutionState &state,
00384                                              KInstruction *target,
00385                                              std::vector<ref<Expr> > &arguments) {
00386   assert(arguments.size()==2 &&
00387          "invalid number of arguments to klee_prefex_cex");
00388 
00389   ref<Expr> cond = arguments[1];
00390   if (cond->getWidth() != Expr::Bool)
00391     cond = NeExpr::create(cond, ConstantExpr::alloc(0, cond->getWidth()));
00392 
00393   Executor::ExactResolutionList rl;
00394   executor.resolveExact(state, arguments[0], rl, "prefex_cex");
00395   
00396   assert(rl.size() == 1 &&
00397          "prefer_cex target must resolve to precisely one object");
00398 
00399   rl[0].first.first->cexPreferences.push_back(cond);
00400 }
00401 
00402 void SpecialFunctionHandler::handlePrintExpr(ExecutionState &state,
00403                                   KInstruction *target,
00404                                   std::vector<ref<Expr> > &arguments) {
00405   assert(arguments.size()==2 &&
00406          "invalid number of arguments to klee_print_expr");
00407 
00408   std::string msg_str = readStringAtAddress(state, arguments[0]);
00409   llvm::cerr << msg_str << ":" << arguments[1] << "\n";
00410 }
00411 
00412 
00413 void SpecialFunctionHandler::handleUnderConstrained(ExecutionState &state,
00414                                   KInstruction *target,
00415                                   std::vector<ref<Expr> > &arguments) {
00416   // XXX should type check args
00417   assert(arguments.size()==1 &&
00418          "invalid number of arguments to klee_under_constrained().");
00419   assert(isa<ConstantExpr>(arguments[0]) &&
00420          "symbolic argument given to klee_under_constrained!");
00421 
00422   unsigned v = cast<ConstantExpr>(arguments[0])->getConstantValue();
00423   llvm::cerr << "argument = " << v << " under=" << state.underConstrained << "\n";
00424   if(v) {
00425     assert(state.underConstrained == false &&
00426          "Bogus call to klee_under_constrained().");
00427     state.underConstrained = v;
00428     llvm::cerr << "turning on under!\n";
00429   } else {
00430     assert(state.underConstrained != 0 && "Bogus call to klee_taint_end()");
00431     state.underConstrained = 0;
00432     llvm::cerr << "turning off under!\n";
00433   }
00434 }
00435 
00436 void SpecialFunctionHandler::handleSetForking(ExecutionState &state,
00437                                               KInstruction *target,
00438                                               std::vector<ref<Expr> > &arguments) {
00439   assert(arguments.size()==1 &&
00440          "invalid number of arguments to klee_set_forking");
00441   ref<Expr> value = executor.toUnique(state, arguments[0]);
00442   
00443   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(value)) {
00444     state.forkDisabled = !CE->getConstantValue();
00445   } else {
00446     executor.terminateStateOnError(state, 
00447                                    "klee_set_forking requires a constant arg",
00448                                    "user.err");
00449   }
00450 }
00451 
00452 void SpecialFunctionHandler::handleWarning(ExecutionState &state,
00453                                            KInstruction *target,
00454                                            std::vector<ref<Expr> > &arguments) {
00455   assert(arguments.size()==1 && "invalid number of arguments to klee_warning");
00456 
00457   std::string msg_str = readStringAtAddress(state, arguments[0]);
00458   klee_warning("%s: %s", state.stack.back().kf->function->getName().c_str(), 
00459                msg_str.c_str());
00460 }
00461 
00462 void SpecialFunctionHandler::handleWarningOnce(ExecutionState &state,
00463                                                KInstruction *target,
00464                                                std::vector<ref<Expr> > &arguments) {
00465   assert(arguments.size()==1 &&
00466          "invalid number of arguments to klee_warning_once");
00467 
00468   std::string msg_str = readStringAtAddress(state, arguments[0]);
00469   klee_warning_once(0, "%s: %s", state.stack.back().kf->function->getName().c_str(), 
00470                     msg_str.c_str());
00471 }
00472 
00473 void SpecialFunctionHandler::handlePrintRange(ExecutionState &state,
00474                                   KInstruction *target,
00475                                   std::vector<ref<Expr> > &arguments) {
00476   assert(arguments.size()==2 &&
00477          "invalid number of arguments to klee_print_range");
00478 
00479   std::string msg_str = readStringAtAddress(state, arguments[0]);
00480   llvm::cerr << msg_str << ":" << arguments[1];
00481   if (!isa<ConstantExpr>(arguments[1])) {
00482     // FIXME: Pull into a unique value method?
00483     ref<ConstantExpr> value;
00484     bool success = executor.solver->getValue(state, arguments[1], value);
00485     assert(success && "FIXME: Unhandled solver failure");
00486     bool res;
00487     success = executor.solver->mustBeTrue(state, 
00488                                           EqExpr::create(arguments[1], value), 
00489                                           res);
00490     assert(success && "FIXME: Unhandled solver failure");
00491     if (res) {
00492       llvm::cerr << " == " << value;
00493     } else { 
00494       llvm::cerr << " ~= " << value;
00495       std::pair< ref<Expr>, ref<Expr> > res =
00496         executor.solver->getRange(state, arguments[1]);
00497       llvm::cerr << " (in [" << res.first << ", " << res.second <<"])";
00498     }
00499   }
00500   llvm::cerr << "\n";
00501 }
00502 
00503 void SpecialFunctionHandler::handleGetObjSize(ExecutionState &state,
00504                                   KInstruction *target,
00505                                   std::vector<ref<Expr> > &arguments) {
00506   // XXX should type check args
00507   assert(arguments.size()==1 &&
00508          "invalid number of arguments to klee_get_obj_size");
00509   Executor::ExactResolutionList rl;
00510   executor.resolveExact(state, arguments[0], rl, "klee_get_obj_size");
00511   for (Executor::ExactResolutionList::iterator it = rl.begin(), 
00512          ie = rl.end(); it != ie; ++it) {
00513     executor.bindLocal(target, *it->second, 
00514                        ConstantExpr::create(it->first.first->size, Expr::Int32));
00515   }
00516 }
00517 
00518 void SpecialFunctionHandler::handleGetErrno(ExecutionState &state,
00519                                             KInstruction *target,
00520                                             std::vector<ref<Expr> > &arguments) {
00521   // XXX should type check args
00522   assert(arguments.size()==0 &&
00523          "invalid number of arguments to klee_get_obj_size");
00524   executor.bindLocal(target, state,
00525                      ConstantExpr::create(errno, Expr::Int32));
00526 }
00527 
00528 void SpecialFunctionHandler::handleCalloc(ExecutionState &state,
00529                             KInstruction *target,
00530                             std::vector<ref<Expr> > &arguments) {
00531   // XXX should type check args
00532   assert(arguments.size()==2 &&
00533          "invalid number of arguments to calloc");
00534 
00535   ref<Expr> size = MulExpr::create(arguments[0],
00536                                    arguments[1]);
00537   executor.executeAlloc(state, size, false, target, true);
00538 }
00539 
00540 void SpecialFunctionHandler::handleRealloc(ExecutionState &state,
00541                             KInstruction *target,
00542                             std::vector<ref<Expr> > &arguments) {
00543   // XXX should type check args
00544   assert(arguments.size()==2 &&
00545          "invalid number of arguments to realloc");
00546   ref<Expr> address = arguments[0];
00547   ref<Expr> size = arguments[1];
00548 
00549   Executor::StatePair zeroSize = executor.fork(state, 
00550                                                Expr::createIsZero(size), 
00551                                                true);
00552   
00553   if (zeroSize.first) { // size == 0
00554     executor.executeFree(*zeroSize.first, address, target);   
00555   }
00556   if (zeroSize.second) { // size != 0
00557     Executor::StatePair zeroPointer = executor.fork(*zeroSize.second, 
00558                                                     Expr::createIsZero(address), 
00559                                                     true);
00560     
00561     if (zeroPointer.first) { // address == 0
00562       executor.executeAlloc(*zeroPointer.first, size, false, target);
00563     } 
00564     if (zeroPointer.second) { // address != 0
00565       Executor::ExactResolutionList rl;
00566       executor.resolveExact(*zeroPointer.second, address, rl, "realloc");
00567       
00568       for (Executor::ExactResolutionList::iterator it = rl.begin(), 
00569              ie = rl.end(); it != ie; ++it) {
00570         executor.executeAlloc(*it->second, size, false, target, false, 
00571                               it->first.second);
00572       }
00573     }
00574   }
00575 }
00576 
00577 void SpecialFunctionHandler::handleFree(ExecutionState &state,
00578                           KInstruction *target,
00579                           std::vector<ref<Expr> > &arguments) {
00580   // XXX should type check args
00581   assert(arguments.size()==1 &&
00582          "invalid number of arguments to free");
00583   executor.executeFree(state, arguments[0]);
00584 }
00585 
00586 void SpecialFunctionHandler::handleCheckMemoryAccess(ExecutionState &state,
00587                                                      KInstruction *target,
00588                                                      std::vector<ref<Expr> > 
00589                                                        &arguments) {
00590   assert(arguments.size()==2 &&
00591          "invalid number of arguments to klee_check_memory_access");
00592 
00593   ref<Expr> address = executor.toUnique(state, arguments[0]);
00594   ref<Expr> size = executor.toUnique(state, arguments[1]);
00595   if (!isa<ConstantExpr>(address) || !isa<ConstantExpr>(size)) {
00596     executor.terminateStateOnError(state, 
00597                                    "check_memory_access requires constant args",
00598                                    "user.err");
00599   } else {
00600     ObjectPair op;
00601 
00602     if (!state.addressSpace.resolveOne(cast<ConstantExpr>(address)->getConstantValue(), op)) {
00603       executor.terminateStateOnError(state,
00604                                      "check_memory_access: memory error",
00605                                      "ptr.err",
00606                                      executor.getAddressInfo(state, address));
00607     } else {
00608       ref<Expr> chk = op.first->getBoundsCheckPointer(address, 
00609                                                       cast<ConstantExpr>(size)->getConstantValue());
00610       if (!cast<ConstantExpr>(chk)->getConstantValue()) {
00611         executor.terminateStateOnError(state,
00612                                        "check_memory_access: memory error",
00613                                        "ptr.err",
00614                                        executor.getAddressInfo(state, address));
00615       }
00616     }
00617   }
00618 }
00619 
00620 void SpecialFunctionHandler::handleGetValue(ExecutionState &state,
00621                                             KInstruction *target,
00622                                             std::vector<ref<Expr> > &arguments) {
00623   assert(arguments.size()==1 &&
00624          "invalid number of arguments to klee_get_value");
00625 
00626   executor.executeGetValue(state, arguments[0], target);
00627 }
00628 
00629 void SpecialFunctionHandler::handleDefineFixedObject(ExecutionState &state,
00630                                                      KInstruction *target,
00631                                                      std::vector<ref<Expr> > &arguments) {
00632   assert(arguments.size()==2 &&
00633          "invalid number of arguments to klee_define_fixed_object");
00634   assert(isa<ConstantExpr>(arguments[0]) &&
00635          "expect constant address argument to klee_define_fixed_object");
00636   assert(isa<ConstantExpr>(arguments[1]) &&
00637          "expect constant size argument to klee_define_fixed_object");
00638   
00639   uint64_t address = cast<ConstantExpr>(arguments[0])->getConstantValue();
00640   uint64_t size = cast<ConstantExpr>(arguments[1])->getConstantValue();
00641   MemoryObject *mo = executor.memory->allocateFixed(address, size, state.prevPC->inst);
00642   executor.bindObjectInState(state, mo, false);
00643   mo->isUserSpecified = true; // XXX hack;
00644 }
00645 
00646 void SpecialFunctionHandler::handleMakeSymbolic(ExecutionState &state,
00647                                                 KInstruction *target,
00648                                                 std::vector<ref<Expr> > &arguments) {
00649   std::string name;
00650 
00651   // FIXME: For backwards compatibility, we should eventually enforce the
00652   // correct arguments.
00653   if (arguments.size() == 2) {
00654     name = "unnamed";
00655   } else {
00656     // FIXME: Should be a user.err, not an assert.
00657     assert(arguments.size()==3 &&
00658            "invalid number of arguments to klee_make_symbolic");  
00659     name = readStringAtAddress(state, arguments[2]);
00660   }
00661 
00662   Executor::ExactResolutionList rl;
00663   executor.resolveExact(state, arguments[0], rl, "make_symbolic");
00664   
00665   for (Executor::ExactResolutionList::iterator it = rl.begin(), 
00666          ie = rl.end(); it != ie; ++it) {
00667     MemoryObject *mo = (MemoryObject*) it->first.first;
00668     mo->setName(name);
00669     
00670     const ObjectState *old = it->first.second;
00671     ExecutionState *s = it->second;
00672     
00673     if (old->readOnly) {
00674       executor.terminateStateOnError(*s, 
00675                                      "cannot make readonly object symbolic", 
00676                                      "user.err");
00677       return;
00678     } 
00679 
00680     bool res;
00681     bool success =
00682       executor.solver->mustBeTrue(*s, EqExpr::create(arguments[1],
00683                                                      mo->getSizeExpr()),
00684                                   res);
00685     assert(success && "FIXME: Unhandled solver failure");
00686     
00687     if (res) {
00688       executor.executeMakeSymbolic(*s, mo);
00689     } else {      
00690       executor.terminateStateOnError(*s, 
00691                                      "wrong size given to klee_make_symbolic[_name]", 
00692                                      "user.err");
00693     }
00694   }
00695 }
00696 
00697 void SpecialFunctionHandler::handleMarkGlobal(ExecutionState &state,
00698                                               KInstruction *target,
00699                                               std::vector<ref<Expr> > &arguments) {
00700   assert(arguments.size()==1 &&
00701          "invalid number of arguments to klee_mark_global");  
00702 
00703   Executor::ExactResolutionList rl;
00704   executor.resolveExact(state, arguments[0], rl, "mark_global");
00705   
00706   for (Executor::ExactResolutionList::iterator it = rl.begin(), 
00707          ie = rl.end(); it != ie; ++it) {
00708     MemoryObject *mo = (MemoryObject*) it->first.first;
00709     assert(!mo->isLocal);
00710     mo->isGlobal = true;
00711   }
00712 }

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