21#include "klee/Config/config.h"
26#include "klee/Support/Debug.h"
30#include "llvm/ADT/Twine.h"
31#include "llvm/IR/DataLayout.h"
32#include "llvm/IR/Instructions.h"
33#include "llvm/IR/Module.h"
43 ReadablePosix(
"readable-posix-inputs", cl::init(
false),
44 cl::desc(
"Prefer creation of POSIX inputs (command-line "
45 "arguments, files, etc.) with human readable bytes. "
46 "Note: option is expensive when creating lots of "
47 "tests (default=false)"),
51 SilentKleeAssume(
"silent-klee-assume", cl::init(
false),
52 cl::desc(
"Silently terminate paths with an infeasible "
53 "condition given to klee_assume() rather than "
54 "emitting an error (default=false)"),
69#define add(name, handler, ret) { name, \
70 &SpecialFunctionHandler::handler, \
72#define addDNR(name, handler) { name, \
73 &SpecialFunctionHandler::handler, \
75 addDNR(
"__assert_rtn", handleAssertFail),
76 addDNR(
"__assert_fail", handleAssertFail),
77 addDNR(
"__assert", handleAssertFail),
78 addDNR(
"_assert", handleAssert),
79 addDNR(
"abort", handleAbort),
80 addDNR(
"_exit", handleExit),
81 {
"exit", &SpecialFunctionHandler::handleExit,
true,
false,
true },
82 addDNR(
"klee_abort", handleAbort),
83 addDNR(
"klee_silent_exit", handleSilentExit),
84 addDNR(
"klee_report_error", handleReportError),
85 add(
"calloc", handleCalloc,
true),
86 add(
"free", handleFree,
false),
87 add(
"klee_assume", handleAssume,
false),
88 add(
"klee_check_memory_access", handleCheckMemoryAccess,
false),
89 add(
"klee_get_valuef", handleGetValue,
true),
90 add(
"klee_get_valued", handleGetValue,
true),
91 add(
"klee_get_valuel", handleGetValue,
true),
92 add(
"klee_get_valuell", handleGetValue,
true),
93 add(
"klee_get_value_i32", handleGetValue,
true),
94 add(
"klee_get_value_i64", handleGetValue,
true),
95 add(
"klee_define_fixed_object", handleDefineFixedObject,
false),
96 add(
"klee_get_obj_size", handleGetObjSize,
true),
97 add(
"klee_get_errno", handleGetErrno,
true),
99 add(
"__errno_location", handleErrnoLocation,
true),
101 add(
"__error", handleErrnoLocation,
true),
103 add(
"klee_is_symbolic", handleIsSymbolic,
true),
104 add(
"klee_make_symbolic", handleMakeSymbolic,
false),
105 add(
"klee_mark_global", handleMarkGlobal,
false),
106 add(
"klee_open_merge", handleOpenMerge,
false),
107 add(
"klee_close_merge", handleCloseMerge,
false),
108 add(
"klee_prefer_cex", handlePreferCex,
false),
109 add(
"klee_posix_prefer_cex", handlePosixPreferCex,
false),
110 add(
"klee_print_expr", handlePrintExpr,
false),
111 add(
"klee_print_range", handlePrintRange,
false),
112 add(
"klee_set_forking", handleSetForking,
false),
113 add(
"klee_stack_trace", handleStackTrace,
false),
114 add(
"klee_warning", handleWarning,
false),
115 add(
"klee_warning_once", handleWarningOnce,
false),
116 add(
"malloc", handleMalloc,
true),
117 add(
"memalign", handleMemalign,
true),
118 add(
"realloc", handleRealloc,
true),
120#ifdef SUPPORT_KLEE_EH_CXX
121 add(
"_klee_eh_Unwind_RaiseException_impl", handleEhUnwindRaiseExceptionImpl,
false),
122 add(
"klee_eh_typeid_for", handleEhTypeid,
true),
126 add(
"_ZdaPv", handleDeleteArray,
false),
128 add(
"_ZdlPv", handleDelete,
false),
131 add(
"_Znaj", handleNewArray,
true),
133 add(
"_Znwj", handleNew,
true),
138 add(
"_Znam", handleNewArray,
true),
140 add(
"_Znwm", handleNew,
true),
144 add(
"__ubsan_handle_add_overflow", handleAddOverflow,
false),
145 add(
"__ubsan_handle_sub_overflow", handleSubOverflow,
false),
146 add(
"__ubsan_handle_mul_overflow", handleMulOverflow,
false),
147 add(
"__ubsan_handle_divrem_overflow", handleDivRemOverflow,
false),
182 std::vector<const char *> &preservedFunctions) {
185 for (
unsigned i=0; i<N; ++i) {
192 preservedFunctions.push_back(hi.
name);
196 f->addFnAttr(Attribute::NoReturn);
200 if (!f->isDeclaration())
209 for (
unsigned i=0; i<N; ++i) {
223 handlers_ty::iterator it =
handlers.find(f);
226 bool hasReturnValue = it->second.second;
228 if (!hasReturnValue && !target->
inst->use_empty()) {
230 "expected return value from void special function");
232 (this->*h)(state, target, arguments);
248 if (!isa<ConstantExpr>(addressExpr)) {
250 state,
"Symbolic string pointer passed to one of the klee_ functions");
256 state,
"Invalid string pointer passed to one of the klee_ functions");
264 size_t offset = cast<ConstantExpr>(relativeOffset)->getZExtValue();
266 std::ostringstream buf;
268 for (
size_t i = offset; i < mo->
size; ++i) {
271 assert(isa<ConstantExpr>(cur) &&
272 "hit symbolic char while reading concrete string");
273 c = cast<ConstantExpr>(cur)->getZExtValue(8);
284 "one of the klee_ functions");
295 assert(arguments.size() == 0 &&
"invalid number of arguments to abort");
297 StateTerminationType::Abort);
303 assert(arguments.size() == 1 &&
"invalid number of arguments to exit");
307void SpecialFunctionHandler::handleSilentExit(
310 assert(arguments.size() == 1 &&
"invalid number of arguments to exit");
317 assert(arguments.size() == 3 &&
"invalid number of arguments to _assert");
320 StateTerminationType::Assert);
323void SpecialFunctionHandler::handleAssertFail(
326 assert(arguments.size() == 4 &&
327 "invalid number of arguments to __assert_fail");
330 StateTerminationType::Assert);
333void SpecialFunctionHandler::handleReportError(
336 assert(arguments.size() == 4 &&
337 "invalid number of arguments to klee_report_error");
342 StateTerminationType::ReportError,
"",
346void SpecialFunctionHandler::handleOpenMerge(
ExecutionState &state,
358 llvm::errs() <<
"open merge: " << &state <<
"\n";
361void SpecialFunctionHandler::handleCloseMerge(
ExecutionState &state,
368 Instruction *i = target->
inst;
371 llvm::errs() <<
"close merge: " << &state <<
" at [" << *i <<
"]\n";
374 std::ostringstream warning;
375 warning << &state <<
" ran into a close at " << i <<
" without a preceding open";
380 "State cannot run into close_merge while being closed");
391 assert(arguments.size()==1 &&
"invalid number of arguments to new");
403 assert(arguments.size()==1 &&
"invalid number of arguments to delete");
411 assert(arguments.size()==1 &&
"invalid number of arguments to new[]");
415void SpecialFunctionHandler::handleDeleteArray(
ExecutionState &state,
419 assert(arguments.size()==1 &&
"invalid number of arguments to delete[]");
427 assert(arguments.size()==1 &&
"invalid number of arguments to malloc");
434 if (arguments.size() != 2) {
436 "Incorrect number of arguments to memalign(size_t alignment, size_t size)");
440 std::pair<ref<Expr>,
ref<Expr>> alignmentRangeExpr =
443 ref<Expr> alignmentExpr = alignmentRangeExpr.first;
444 auto alignmentConstExpr = dyn_cast<ConstantExpr>(alignmentExpr);
446 if (!alignmentConstExpr) {
451 uint64_t alignment = alignmentConstExpr->getZExtValue();
454 if (alignmentRangeExpr.first != alignmentRangeExpr.second) {
456 0,
"Symbolic alignment for memalign. Choosing smallest alignment");
463#ifdef SUPPORT_KLEE_EH_CXX
464void SpecialFunctionHandler::handleEhUnwindRaiseExceptionImpl(
467 assert(arguments.size() == 1 &&
468 "invalid number of arguments to _klee_eh_Unwind_RaiseException_impl");
471 if (!exceptionObject.
get()) {
476 if (isa_and_nonnull<SearchPhaseUnwindingInformation>(
480 "Internal error: Unwinding restarted during an ongoing search phase");
485 std::make_unique<SearchPhaseUnwindingInformation>(exceptionObject,
486 state.
stack.size() - 1);
494 assert(arguments.size() == 1 &&
495 "invalid number of arguments to klee_eh_typeid_for");
504 assert(arguments.size()==1 &&
"invalid number of arguments to klee_assume");
514 assert(success &&
"FIXME: Unhandled solver failure");
516 if (SilentKleeAssume) {
520 state,
"invalid klee_assume call (provably false)");
527void SpecialFunctionHandler::handleIsSymbolic(
ExecutionState &state,
530 assert(arguments.size()==1 &&
"invalid number of arguments to klee_is_symbolic");
537void SpecialFunctionHandler::handlePreferCex(
ExecutionState &state,
540 assert(arguments.size()==2 &&
541 "invalid number of arguments to klee_prefex_cex");
550void SpecialFunctionHandler::handlePosixPreferCex(
ExecutionState &state,
554 return handlePreferCex(state, target, arguments);
557void SpecialFunctionHandler::handlePrintExpr(
ExecutionState &state,
560 assert(arguments.size()==2 &&
561 "invalid number of arguments to klee_print_expr");
564 llvm::errs() << msg_str <<
":" << arguments[1] <<
"\n";
567void SpecialFunctionHandler::handleSetForking(
ExecutionState &state,
570 assert(arguments.size()==1 &&
571 "invalid number of arguments to klee_set_forking");
581void SpecialFunctionHandler::handleStackTrace(
ExecutionState &state,
590 assert(arguments.size()==1 &&
"invalid number of arguments to klee_warning");
597void SpecialFunctionHandler::handleWarningOnce(
ExecutionState &state,
600 assert(arguments.size()==1 &&
601 "invalid number of arguments to klee_warning_once");
608void SpecialFunctionHandler::handlePrintRange(
ExecutionState &state,
611 assert(arguments.size()==2 &&
612 "invalid number of arguments to klee_print_range");
615 llvm::errs() << msg_str <<
":" << arguments[1];
616 if (!isa<ConstantExpr>(arguments[1])) {
621 assert(success &&
"FIXME: Unhandled solver failure");
624 EqExpr::create(arguments[1], value),
626 assert(success &&
"FIXME: Unhandled solver failure");
628 llvm::errs() <<
" == " << value;
630 llvm::errs() <<
" ~= " << value;
633 llvm::errs() <<
" (in [" << res.first <<
", " << res.second <<
"])";
636 llvm::errs() <<
"\n";
639void SpecialFunctionHandler::handleGetObjSize(
ExecutionState &state,
643 assert(arguments.size()==1 &&
644 "invalid number of arguments to klee_get_obj_size");
647 for (Executor::ExactResolutionList::iterator it = rl.begin(),
648 ie = rl.end(); it != ie; ++it) {
653 target->
inst->getType())));
661 assert(arguments.size()==0 &&
662 "invalid number of arguments to klee_get_errno");
666 int *errno_addr =
nullptr;
678void SpecialFunctionHandler::handleErrnoLocation(
682 assert(arguments.size() == 0 &&
683 "invalid number of arguments to __errno_location/__error");
688 int *errno_addr =
nullptr;
695 target->
inst->getType())));
701 assert(arguments.size()==2 &&
702 "invalid number of arguments to calloc");
713 assert(arguments.size()==2 &&
714 "invalid number of arguments to realloc");
721 if (zeroSize.first) {
724 if (zeroSize.second) {
727 BranchType::Realloc);
729 if (zeroPointer.first) {
732 if (zeroPointer.second) {
736 for (Executor::ExactResolutionList::iterator it = rl.begin(),
737 ie = rl.end(); it != ie; ++it) {
749 assert(arguments.size()==1 &&
750 "invalid number of arguments to free");
754void SpecialFunctionHandler::handleCheckMemoryAccess(
ExecutionState &state,
758 assert(arguments.size()==2 &&
759 "invalid number of arguments to klee_check_memory_access");
763 if (!isa<ConstantExpr>(address) || !isa<ConstantExpr>(
size)) {
770 "check_memory_access: memory error",
771 StateTerminationType::Ptr,
775 op.first->getBoundsCheckPointer(address,
776 cast<ConstantExpr>(
size)->getZExtValue());
779 "check_memory_access: memory error",
780 StateTerminationType::Ptr,
790 assert(arguments.size()==1 &&
791 "invalid number of arguments to klee_get_value");
796void SpecialFunctionHandler::handleDefineFixedObject(
ExecutionState &state,
799 assert(arguments.size()==2 &&
800 "invalid number of arguments to klee_define_fixed_object");
801 assert(isa<ConstantExpr>(arguments[0]) &&
802 "expect constant address argument to klee_define_fixed_object");
803 assert(isa<ConstantExpr>(arguments[1]) &&
804 "expect constant size argument to klee_define_fixed_object");
806 uint64_t address = cast<ConstantExpr>(arguments[0])->getZExtValue();
807 uint64_t
size = cast<ConstantExpr>(arguments[1])->getZExtValue();
813void SpecialFunctionHandler::handleMakeSymbolic(
ExecutionState &state,
818 if (arguments.size() != 3) {
820 "Incorrect number of arguments to klee_make_symbolic(void*, size_t, char*)");
826 if (name.length() == 0) {
828 klee_warning(
"klee_make_symbolic: renamed empty name to \"unnamed\"");
834 for (Executor::ExactResolutionList::iterator it = rl.begin(),
835 ie = rl.end(); it != ie; ++it) {
855 assert(success &&
"FIXME: Unhandled solver failure");
865void SpecialFunctionHandler::handleMarkGlobal(
ExecutionState &state,
868 assert(arguments.size()==1 &&
869 "invalid number of arguments to klee_mark_global");
874 for (Executor::ExactResolutionList::iterator it = rl.begin(),
875 ie = rl.end(); it != ie; ++it) {
882void SpecialFunctionHandler::handleAddOverflow(
886 StateTerminationType::Overflow);
889void SpecialFunctionHandler::handleSubOverflow(
893 StateTerminationType::Overflow);
896void SpecialFunctionHandler::handleMulOverflow(
900 StateTerminationType::Overflow);
903void SpecialFunctionHandler::handleDivRemOverflow(
907 StateTerminationType::Overflow);
void *__dso_handle __attribute__((__weak__))
Implementation of the region based merging.
#define addDNR(name, handler)
static SpecialFunctionHandler::HandlerInfo handlerInfo[]
#define add(name, handler, ret)
bool resolveOne(const ref< ConstantExpr > &address, ObjectPair &result) const
static ref< ConstantExpr > create(uint64_t v, Width w)
static ref< ConstantExpr > alloc(const llvm::APInt &v)
Expr::Width getPointerWidth() const
Returns width of the pointer in bits.
static const Context & get()
get - Return the global singleton instance of the Context.
ExecutionState representing a path under exploration.
stack_ty stack
Stack representing the current instruction stream.
std::unique_ptr< UnwindingInformation > unwindingInformation
Keep track of unwinding state while unwinding, otherwise empty.
bool forkDisabled
Disables forking for this state. Set by user code.
SolverQueryMetaData queryMetaData
Statistics and information.
ConstraintSet constraints
Constraints collected so far.
std::vector< ref< MergeHandler > > openMergeStack
The objects handling the klee_open_merge calls this state ran through.
AddressSpace addressSpace
Address space used by this state (e.g. Global and Heap)
void dumpStack(llvm::raw_ostream &out) const
void addCexPreference(const ref< Expr > &cond)
KInstIterator prevPC
Pointer to instruction which is currently executed.
void terminateStateOnExit(ExecutionState &state)
void addConstraint(ExecutionState &state, ref< Expr > condition)
std::string getAddressInfo(ExecutionState &state, ref< Expr > address) const
Get textual information regarding a memory address.
ObjectState * bindObjectInState(ExecutionState &state, const MemoryObject *mo, bool isLocal, const Array *array=0)
ref< ConstantExpr > getEhTypeidFor(ref< Expr > type_info)
Return the typeid corresponding to a certain type_info
std::vector< std::pair< std::pair< const MemoryObject *, const ObjectState * >, ExecutionState * > > ExactResolutionList
StatePair fork(ExecutionState ¤t, ref< Expr > condition, bool isInternal, BranchType reason)
ref< Expr > toUnique(const ExecutionState &state, ref< Expr > &e)
void terminateState(ExecutionState &state)
Remove state from queue and delete state.
void executeAlloc(ExecutionState &state, ref< Expr > size, bool isLocal, KInstruction *target, bool zeroMemory=false, const ObjectState *reallocFrom=0, size_t allocationAlignment=0)
void bindLocal(KInstruction *target, ExecutionState &state, ref< Expr > value)
void terminateStateEarly(ExecutionState &state, const llvm::Twine &message, StateTerminationType terminationType)
std::pair< ExecutionState *, ExecutionState * > StatePair
void terminateStateOnExecError(ExecutionState &state, const llvm::Twine &message, const llvm::Twine &info="")
void executeMakeSymbolic(ExecutionState &state, const MemoryObject *mo, const std::string &name)
std::unique_ptr< KModule > kmodule
void terminateStateOnUserError(ExecutionState &state, const llvm::Twine &message)
void resolveExact(ExecutionState &state, ref< Expr > p, ExactResolutionList &results, const std::string &name)
MergingSearcher * mergingSearcher
void executeGetValue(ExecutionState &state, ref< Expr > e, KInstruction *target)
void unwindToNextLandingpad(ExecutionState &state)
void executeFree(ExecutionState &state, ref< Expr > address, KInstruction *target=0)
void terminateStateOnError(ExecutionState &state, const llvm::Twine &message, StateTerminationType terminationType, const llvm::Twine &longMessage="", const char *suffix=nullptr)
int * getErrnoLocation(const ExecutionState &state) const
Returns the errno location in memory of the state.
static ref< Expr > createIsZero(ref< Expr > e)
virtual Width getWidth() const =0
bool isTrue() const
isTrue - Is this the true expression.
MemoryObject * allocateFixed(uint64_t address, uint64_t size, const llvm::Value *allocSite)
void setName(std::string name) const
unsigned size
size in bytes
ref< ConstantExpr > getSizeExpr() const
ref< Expr > getOffsetExpr(ref< Expr > pointer) const
Represents one klee_open_merge() call. Handles merging of states that branched from it.
std::set< ExecutionState * > inCloseMerge
ref< Expr > read8(unsigned offset) const
const_iterator & operator++()
void(SpecialFunctionHandler::* Handler)(ExecutionState &state, KInstruction *target, std::vector< ref< Expr > > &arguments)
class Executor & executor
static const_iterator end()
std::string readStringAtAddress(ExecutionState &state, ref< Expr > address)
SpecialFunctionHandler(Executor &_executor)
bool handle(ExecutionState &state, llvm::Function *f, KInstruction *target, std::vector< ref< Expr > > &arguments)
void prepare(std::vector< const char * > &preservedFunctions)
bool getValue(const ConstraintSet &, ref< Expr > expr, ref< ConstantExpr > &result, SolverQueryMetaData &metaData)
bool mustBeFalse(const ConstraintSet &, ref< Expr >, bool &result, SolverQueryMetaData &metaData)
bool mustBeTrue(const ConstraintSet &, ref< Expr >, bool &result, SolverQueryMetaData &metaData)
std::pair< ref< Expr >, ref< Expr > > getRange(const ConstraintSet &, ref< Expr > query, SolverQueryMetaData &metaData)
llvm::cl::OptionCategory TestGenCat
llvm::cl::opt< bool > UseMerge
llvm::cl::opt< bool > DebugLogMerge
void void void void klee_warning_once(const void *id, const char *msg,...) __attribute__((format(printf
llvm::cl::OptionCategory TerminationCat
void void void klee_warning(const char *msg,...) __attribute__((format(printf
std::pair< const MemoryObject *, const ObjectState * > ObjectPair
SpecialFunctionHandler::Handler handler
bool hasReturnValue
Intrinsic terminates the process.
bool doNotOverride
Intrinsic has a return value.