00001
00002
00003
00004
00005
00006
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
00045
00046
00047
00048
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
00090 add("_ZdaPv", handleDeleteArray, false),
00091
00092 add("_ZdlPv", handleDelete, false),
00093
00094
00095 add("_Znaj", handleNewArray, true),
00096
00097 add("_Znwj", handleNew, true),
00098
00099
00100
00101
00102 add("_Znam", handleNewArray, true),
00103
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
00122
00123
00124 if (f && (!hi.doNotOverride || f->isDeclaration())) {
00125
00126
00127 if (hi.doesNotReturn)
00128 f->addFnAttr(Attribute::NoReturn);
00129
00130
00131
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
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
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
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
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
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
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
00291
00292
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
00308 }
00309
00310 void SpecialFunctionHandler::handleNew(ExecutionState &state,
00311 KInstruction *target,
00312 std::vector<ref<Expr> > &arguments) {
00313
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
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
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
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
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
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
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
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
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
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
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) {
00554 executor.executeFree(*zeroSize.first, address, target);
00555 }
00556 if (zeroSize.second) {
00557 Executor::StatePair zeroPointer = executor.fork(*zeroSize.second,
00558 Expr::createIsZero(address),
00559 true);
00560
00561 if (zeroPointer.first) {
00562 executor.executeAlloc(*zeroPointer.first, size, false, target);
00563 }
00564 if (zeroPointer.second) {
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
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;
00644 }
00645
00646 void SpecialFunctionHandler::handleMakeSymbolic(ExecutionState &state,
00647 KInstruction *target,
00648 std::vector<ref<Expr> > &arguments) {
00649 std::string name;
00650
00651
00652
00653 if (arguments.size() == 2) {
00654 name = "unnamed";
00655 } else {
00656
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 }