aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Core')
-rw-r--r--lib/Core/Executor.cpp7
-rw-r--r--lib/Core/Executor.h7
-rw-r--r--lib/Core/SpecialFunctionHandler.cpp35
-rw-r--r--lib/Core/SpecialFunctionHandler.h1
4 files changed, 47 insertions, 3 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index e4f9388e..7cb01e5c 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -3286,11 +3286,14 @@ void Executor::executeAlloc(ExecutionState &state,
bool isLocal,
KInstruction *target,
bool zeroMemory,
- const ObjectState *reallocFrom) {
+ const ObjectState *reallocFrom,
+ size_t allocationAlignment) {
size = toUnique(state, size);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(size)) {
const llvm::Value *allocSite = state.prevPC->inst;
- size_t allocationAlignment = getAllocationAlignment(allocSite);
+ if (allocationAlignment == 0) {
+ allocationAlignment = getAllocationAlignment(allocSite);
+ }
MemoryObject *mo =
memory->allocate(CE->getZExtValue(), isLocal, /*isGlobal=*/false,
allocSite, allocationAlignment);
diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h
index 180c9140..66a28ba8 100644
--- a/lib/Core/Executor.h
+++ b/lib/Core/Executor.h
@@ -301,12 +301,17 @@ private:
/// done (realloc semantics). The initialized bytes will be the
/// minimum of the size of the old and new objects, with remaining
/// bytes initialized as specified by zeroMemory.
+ ///
+ /// \param allocationAlignment If non-zero, the given alignment is
+ /// used. Otherwise, the alignment is deduced via
+ /// Executor::getAllocationAlignment
void executeAlloc(ExecutionState &state,
ref<Expr> size,
bool isLocal,
KInstruction *target,
bool zeroMemory=false,
- const ObjectState *reallocFrom=0);
+ const ObjectState *reallocFrom=0,
+ size_t allocationAlignment=0);
/// Free the given address with checking for errors. If target is
/// given it will be bound to 0 in the resulting states (this is a
diff --git a/lib/Core/SpecialFunctionHandler.cpp b/lib/Core/SpecialFunctionHandler.cpp
index 8752c2c8..6f887a43 100644
--- a/lib/Core/SpecialFunctionHandler.cpp
+++ b/lib/Core/SpecialFunctionHandler.cpp
@@ -111,6 +111,7 @@ static SpecialFunctionHandler::HandlerInfo handlerInfo[] = {
add("klee_warning_once", handleWarningOnce, false),
add("klee_alias_function", handleAliasFunction, false),
add("malloc", handleMalloc, true),
+ add("memalign", handleMemalign, true),
add("realloc", handleRealloc, true),
// operator delete[](void*)
@@ -427,6 +428,40 @@ void SpecialFunctionHandler::handleMalloc(ExecutionState &state,
executor.executeAlloc(state, arguments[0], false, target);
}
+void SpecialFunctionHandler::handleMemalign(ExecutionState &state,
+ KInstruction *target,
+ std::vector<ref<Expr>> &arguments) {
+ if (arguments.size() != 2) {
+ executor.terminateStateOnError(state,
+ "Incorrect number of arguments to memalign(size_t alignment, size_t size)",
+ Executor::User);
+ return;
+ }
+
+ std::pair<ref<Expr>, ref<Expr>> alignmentRangeExpr =
+ executor.solver->getRange(state, arguments[0]);
+ ref<Expr> alignmentExpr = alignmentRangeExpr.first;
+ auto alignmentConstExpr = dyn_cast<ConstantExpr>(alignmentExpr);
+
+ if (!alignmentConstExpr) {
+ executor.terminateStateOnError(state,
+ "Could not determine size of symbolic alignment",
+ Executor::User);
+ return;
+ }
+
+ uint64_t alignment = alignmentConstExpr->getZExtValue();
+
+ // Warn, if the expression has more than one solution
+ if (alignmentRangeExpr.first != alignmentRangeExpr.second) {
+ klee_warning_once(
+ 0, "Symbolic alignment for memalign. Choosing smallest alignment");
+ }
+
+ executor.executeAlloc(state, arguments[1], false, target, false, 0,
+ alignment);
+}
+
void SpecialFunctionHandler::handleAssume(ExecutionState &state,
KInstruction *target,
std::vector<ref<Expr> > &arguments) {
diff --git a/lib/Core/SpecialFunctionHandler.h b/lib/Core/SpecialFunctionHandler.h
index f99a212f..fdb6b6de 100644
--- a/lib/Core/SpecialFunctionHandler.h
+++ b/lib/Core/SpecialFunctionHandler.h
@@ -119,6 +119,7 @@ namespace klee {
HANDLER(handleIsSymbolic);
HANDLER(handleMakeSymbolic);
HANDLER(handleMalloc);
+ HANDLER(handleMemalign);
HANDLER(handleMarkGlobal);
HANDLER(handleOpenMerge);
HANDLER(handleCloseMerge);