From: Martin Nowack Date: Thu, 12 Oct 2017 21:57:03 +0200 Subject: Add support for modelling errno_location Patch-mainline: no Signed-off-by: Jiri Slaby --- lib/Core/SpecialFunctionHandler.cpp | 46 ++++++++++++++++++++++++++++++++++--- lib/Core/SpecialFunctionHandler.h | 1 + tools/klee/main.cpp | 2 ++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/Core/SpecialFunctionHandler.cpp b/lib/Core/SpecialFunctionHandler.cpp index 88e0d1a034bd..a019a09486c1 100644 --- a/lib/Core/SpecialFunctionHandler.cpp +++ b/lib/Core/SpecialFunctionHandler.cpp @@ -89,6 +89,8 @@ static SpecialFunctionHandler::HandlerInfo handlerInfo[] = { add("klee_define_fixed_object", handleDefineFixedObject, false), add("klee_get_obj_size", handleGetObjSize, true), add("klee_get_errno", handleGetErrno, true), + add("__errno_location", handleErrnoLocation, true), + add("__error", handleErrnoLocation, true), add("klee_is_symbolic", handleIsSymbolic, true), add("klee_make_symbolic", handleMakeSymbolic, false), add("klee_mark_global", handleMarkGlobal, false), @@ -537,10 +539,48 @@ void SpecialFunctionHandler::handleGetErrno(ExecutionState &state, // XXX should type check args assert(arguments.size()==0 && "invalid number of arguments to klee_get_errno"); - executor.bindLocal(target, state, - ConstantExpr::create(errno, Expr::Int32)); +#ifndef WINDOWS +#ifndef __APPLE__ + int *errno_addr = __errno_location(); +#else + int *errno_addr = __error(); +#endif +#else + int *errno_addr = nullptr; +#endif + + // Retrieve the memory object of the errno variable + ObjectPair result; + bool resolved = state.addressSpace.resolveOne( + ConstantExpr::create((uint64_t)errno_addr, Expr::Int64), result); + if (!resolved) + executor.terminateStateOnError(state, "Could not resolve address for errno", + Executor::User); + executor.bindLocal(target, state, result.second->read(0, Expr::Int32)); +} + +void SpecialFunctionHandler::handleErrnoLocation( + ExecutionState &state, KInstruction *target, + std::vector > &arguments) { + // Returns the address of the errno variable + assert(arguments.size() == 0 && + "invalid number of arguments to __errno_location"); + +#ifndef WINDOWS +#ifndef __APPLE__ + int *errno_addr = __errno_location(); +#else + int *errno_addr = __error(); +#endif +#else + int *errno_addr = nullptr; +#endif + executor.bindLocal( + target, state, + ConstantExpr::create((uint64_t)errno_addr, + executor.kmodule->targetData->getTypeSizeInBits( + target->inst->getType()))); } - void SpecialFunctionHandler::handleCalloc(ExecutionState &state, KInstruction *target, std::vector > &arguments) { diff --git a/lib/Core/SpecialFunctionHandler.h b/lib/Core/SpecialFunctionHandler.h index 394b649aff72..5e58ede4f328 100644 --- a/lib/Core/SpecialFunctionHandler.h +++ b/lib/Core/SpecialFunctionHandler.h @@ -107,6 +107,7 @@ namespace klee { HANDLER(handleDelete); HANDLER(handleDeleteArray); HANDLER(handleExit); + HANDLER(handleErrnoLocation); HANDLER(handleAliasFunction); HANDLER(handleFree); HANDLER(handleGetErrno); diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index f1def38c90e5..4a820578bf16 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -698,6 +698,8 @@ static const char *modelledExternals[] = { "_assert", "__assert_fail", "__assert_rtn", + "__errno_location", + "__error", "calloc", "_exit", "exit", -- 2.15.0