diff options
| author | Mikhail <mishok2503@mail.ru> | 2022-06-08 16:36:28 +0300 |
|---|---|---|
| committer | MartinNowack <2443641+MartinNowack@users.noreply.github.com> | 2022-07-04 22:20:00 +0100 |
| commit | 99c522b14dbbf6b26be35b6e7bb8da7b29070287 (patch) | |
| tree | 49fb535d7beda87188b878c053b1b3241e07fc3f /lib/Core/Executor.cpp | |
| parent | 3d0033f099c907bcd5d4d2c2a7562037071ec2bf (diff) | |
| download | klee-99c522b14dbbf6b26be35b6e7bb8da7b29070287.tar.gz | |
Inline asm external call
Diffstat (limited to 'lib/Core/Executor.cpp')
| -rw-r--r-- | lib/Core/Executor.cpp | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 11ad902e..42405982 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -37,6 +37,7 @@ #include "klee/Expr/ExprUtil.h" #include "klee/Module/Cell.h" #include "klee/Module/InstructionInfoTable.h" +#include "klee/Module/KCallable.h" #include "klee/Module/KInstruction.h" #include "klee/Module/KModule.h" #include "klee/Solver/Common.h" @@ -59,6 +60,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" +#include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" @@ -1658,10 +1660,11 @@ void Executor::executeCall(ExecutionState &state, KInstruction *ki, Function *f, return; if (f && f->isDeclaration()) { switch (f->getIntrinsicID()) { - case Intrinsic::not_intrinsic: + case Intrinsic::not_intrinsic: { // state may be destroyed by this call, cannot touch - callExternalFunction(state, ki, f, arguments); + callExternalFunction(state, ki, kmodule->functionMap[f], arguments); break; + } case Intrinsic::fabs: { ref<ConstantExpr> arg = toConstant(state, arguments[0], "floating point"); @@ -2399,10 +2402,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { unsigned numArgs = cb.arg_size(); Function *f = getTargetFunction(fp, state); - if (isa<InlineAsm>(fp)) { - terminateStateOnExecError(state, "inline assembly is unsupported"); - break; - } // evaluate arguments std::vector< ref<Expr> > arguments; arguments.reserve(numArgs); @@ -2410,6 +2409,16 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { for (unsigned j=0; j<numArgs; ++j) arguments.push_back(eval(ki, j+1, state).value); + if (auto* asmValue = dyn_cast<InlineAsm>(fp)) { //TODO: move to `executeCall` + if (ExternalCalls != ExternalCallPolicy::None) { + KInlineAsm callable(asmValue); + callExternalFunction(state, ki, &callable, arguments); + } else { + terminateStateOnExecError(state, "external calls disallowed (in particular inline asm)"); + } + break; + } + if (f) { const FunctionType *fType = dyn_cast<FunctionType>(cast<PointerType>(f->getType())->getElementType()); @@ -3784,16 +3793,18 @@ static std::set<std::string> okExternals(okExternalsList, void Executor::callExternalFunction(ExecutionState &state, KInstruction *target, - Function *function, + KCallable *callable, std::vector< ref<Expr> > &arguments) { // check if specialFunctionHandler wants it - if (specialFunctionHandler->handle(state, function, target, arguments)) - return; + if (const auto *func = dyn_cast<KFunction>(callable)) { + if (specialFunctionHandler->handle(state, func->function, target, arguments)) + return; + } if (ExternalCalls == ExternalCallPolicy::None && - !okExternals.count(function->getName().str())) { + !okExternals.count(callable->getName().str())) { klee_warning("Disallowed call to external function: %s\n", - function->getName().str().c_str()); + callable->getName().str().c_str()); terminateStateOnUserError(state, "external calls disallowed"); return; } @@ -3835,7 +3846,7 @@ void Executor::callExternalFunction(ExecutionState &state, } else { terminateStateOnExecError(state, "external call with symbolic argument: " + - function->getName()); + callable->getName()); return; } } @@ -3856,7 +3867,7 @@ void Executor::callExternalFunction(ExecutionState &state, if (!errnoValue) { terminateStateOnExecError(state, "external call with errno value symbolic: " + - function->getName()); + callable->getName()); return; } @@ -3868,7 +3879,7 @@ void Executor::callExternalFunction(ExecutionState &state, std::string TmpStr; llvm::raw_string_ostream os(TmpStr); - os << "calling external: " << function->getName().str() << "("; + os << "calling external: " << callable->getName().str() << "("; for (unsigned i=0; i<arguments.size(); i++) { os << arguments[i]; if (i != arguments.size()-1) @@ -3879,12 +3890,12 @@ void Executor::callExternalFunction(ExecutionState &state, if (AllExternalWarnings) klee_warning("%s", os.str().c_str()); else - klee_warning_once(function, "%s", os.str().c_str()); + klee_warning_once(callable->getValue(), "%s", os.str().c_str()); } - bool success = externalDispatcher->executeCall(function, target->inst, args); + bool success = externalDispatcher->executeCall(callable, target->inst, args); if (!success) { - terminateStateOnError(state, "failed external call: " + function->getName(), + terminateStateOnError(state, "failed external call: " + callable->getName(), StateTerminationType::External); return; } @@ -3903,7 +3914,7 @@ void Executor::callExternalFunction(ExecutionState &state, #endif Type *resultType = target->inst->getType(); - if (resultType != Type::getVoidTy(function->getContext())) { + if (resultType != Type::getVoidTy(kmodule->module->getContext())) { ref<Expr> e = ConstantExpr::fromMemory((void*) args, getWidthForLLVMType(resultType)); bindLocal(target, state, e); |
