Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several fixes #155

Merged
merged 7 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 7 additions & 28 deletions include/klee/Support/ModuleUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,16 @@ bool linkModules(llvm::Module *composite,
std::vector<std::unique_ptr<llvm::Module>> &modules,
const unsigned Flags, std::string &errorMsg);

#if defined(__x86_64__) || defined(__i386__)
#define addFunctionReplacement(from, to) \
{#from "f", #to "f"}, {#from "", #to ""}, { "" #from "l", #to "l" }
void replaceOrRenameFunction(llvm::Module *module, const char *old_name,
const char *new_name);

#if defined(__x86_64__) || defined(__i386__)
#define addIntrinsicReplacement(from, to) \
{"llvm." #from ".f32", #to "f"}, {"llvm." #from ".f64", #to}, { \
"llvm." #from ".f80", #to "l" \
}

#else
#define addFunctionReplacement(from, to) \
{#from "f", #to "f"}, { "" #from, "" #to }

#define addIntrinsicReplacement(from, to) \
{"llvm." #from ".f32", #to "f"}, { "llvm." #from ".f64", #to }

Expand All @@ -62,33 +59,15 @@ bool linkModules(llvm::Module *composite,
/// implementations in runtime/klee-fp, but not explicitly replaced here. Should
/// we rename them and complete the list?
const std::vector<std::pair<std::string, std::string>> floatReplacements = {
addFunctionReplacement(__isnan, klee_internal_isnan),
addFunctionReplacement(isnan, klee_internal_isnan),
addFunctionReplacement(__isinf, klee_internal_isinf),
addFunctionReplacement(isinf, klee_internal_isinf),
addFunctionReplacement(__fpclassify, klee_internal_fpclassify),
addFunctionReplacement(fpclassify, klee_internal_fpclassify),
addFunctionReplacement(__finite, klee_internal_finite),
addFunctionReplacement(finite, klee_internal_finite),
addFunctionReplacement(sqrt, klee_internal_sqrt),
addFunctionReplacement(fabs, klee_internal_fabs),
addFunctionReplacement(rint, klee_internal_rint),
addFunctionReplacement(round, klee_internal_rint),
addFunctionReplacement(__signbit, klee_internal_signbit),
addIntrinsicReplacement(sqrt, klee_internal_sqrt),
addIntrinsicReplacement(rint, klee_internal_rint),
addIntrinsicReplacement(round, klee_internal_rint),
addIntrinsicReplacement(sqrt, sqrt),
addIntrinsicReplacement(rint, rint),
addIntrinsicReplacement(round, rint),
addIntrinsicReplacement(nearbyint, nearbyint),
addIntrinsicReplacement(copysign, copysign),
addIntrinsicReplacement(floor, klee_floor),
addIntrinsicReplacement(floor, floor),
addIntrinsicReplacement(ceil, ceil)};
#undef addFunctionReplacement
#undef addIntrinsicReplacement

const std::vector<std::pair<std::string, std::string>> feRoundReplacements{
{"fegetround", "klee_internal_fegetround"},
{"fesetround", "klee_internal_fesetround"}};

/// Return the Function* target of a Call or Invoke instruction, or
/// null if it cannot be determined (should be only for indirect
/// calls, although complicated constant expressions might be
Expand Down
50 changes: 29 additions & 21 deletions lib/Core/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ llvm::Module *Executor::setModule(
kmodule = std::make_unique<KModule>();

// 1.) Link the modules together && 2.) Apply different instrumentation
kmodule->link(userModules, 0);
kmodule->link(userModules, 1);
kmodule->instrument(opts);

kmodule->link(libsModules, 2);
Expand Down Expand Up @@ -603,21 +603,28 @@ llvm::Module *Executor::setModule(
specialFunctionHandler = new SpecialFunctionHandler(*this);
specialFunctionHandler->prepare(preservedFunctions);

preservedFunctions.push_back(opts.EntryPoint.c_str());

// Preserve the free-standing library calls
preservedFunctions.push_back("memset");
preservedFunctions.push_back("memcpy");
preservedFunctions.push_back("memcmp");
preservedFunctions.push_back("memmove");

if (FunctionCallReproduce != "") {
// prevent elimination of the function
auto f = kmodule->module->getFunction(FunctionCallReproduce);
if (f)
preservedFunctions.push_back(FunctionCallReproduce.c_str());
}

// prevent elimination of the preservedFunctions functions
for (auto pf : preservedFunctions) {
auto f = kmodule->module->getFunction(pf);
if (f) {
f->addFnAttr(Attribute::OptimizeNone);
f->addFnAttr(Attribute::NoInline);
}
}

// except the entry point
preservedFunctions.push_back(opts.EntryPoint.c_str());

kmodule->optimiseAndPrepare(opts, preservedFunctions);
kmodule->checkModule();

Expand Down Expand Up @@ -2942,18 +2949,19 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
} else {
ref<Expr> v = eval(ki, 0, state).value;

if (!isa<ConstantExpr>(v) && MockExternalCalls) {
if (ki->inst->getType()->isSized()) {
prepareMockValue(state, "mockExternResult", ki);
}
} else {
ExecutionState *free = &state;
bool hasInvalid = false, first = true;

/* XXX This is wasteful, no need to do a full evaluate since we
have already got a value. But in the end the caches should
handle it for us, albeit with some overhead. */
do {
ExecutionState *free = &state;
bool hasInvalid = false, first = true;

/* XXX This is wasteful, no need to do a full evaluate since we
have already got a value. But in the end the caches should
handle it for us, albeit with some overhead. */
do {
if (!first && MockExternalCalls) {
free = nullptr;
if (ki->inst->getType()->isSized()) {
prepareMockValue(state, "mockExternResult", ki);
}
} else {
v = optimizer.optimizeExpr(v, true);
ref<ConstantExpr> value;
bool success = solver->getValue(free->constraints.cs(), v, value,
Expand Down Expand Up @@ -2986,8 +2994,8 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
first = false;
free = res.second;
timers.invoke();
} while (free && !haltExecution);
}
}
} while (free && !haltExecution);
}
break;
}
Expand Down Expand Up @@ -4142,7 +4150,7 @@ bool Executor::checkMemoryUsage() {
const auto mmapUsage = memory->getUsedDeterministicSize() >> 20U;
const auto totalUsage = mallocUsage + mmapUsage;

if (MemoryTriggerCoverOnTheFly && 3 * totalUsage <= 2 * MaxMemory) {
if (MemoryTriggerCoverOnTheFly && totalUsage > MaxMemory * 0.75) {
klee_warning_once(0,
"enabling cover-on-the-fly (close to memory cap: %luMB)",
totalUsage);
Expand Down
19 changes: 2 additions & 17 deletions lib/Module/KModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,6 @@ bool KModule::link(std::vector<std::unique_ptr<llvm::Module>> &modules,
return true;
}

void KModule::replaceFunction(const std::unique_ptr<llvm::Module> &m,
const char *original, const char *replacement) {
llvm::Function *originalFunc = m->getFunction(original);
llvm::Function *replacementFunc = m->getFunction(replacement);
if (!originalFunc)
return;
klee_message("Replacing function \"%s\" with \"%s\"", original, replacement);
assert(replacementFunc && "Replacement function not found");
assert(!(replacementFunc->isDeclaration()) && "replacement must have body");
originalFunc->replaceAllUsesWith(replacementFunc);
originalFunc->eraseFromParent();
}

void KModule::instrument(const Interpreter::ModuleOptions &opts) {
// Inject checks prior to optimization... we also perform the
// invariant transformations that we will end up doing later so that
Expand Down Expand Up @@ -301,12 +288,10 @@ void KModule::optimiseAndPrepare(
if (opts.WithFPRuntime) {
if (UseKleeFloatInternals) {
for (const auto &p : klee::floatReplacements) {
replaceFunction(module, p.first.c_str(), p.second.c_str());
replaceOrRenameFunction(module.get(), p.first.c_str(),
p.second.c_str());
}
}
for (const auto &p : klee::feRoundReplacements) {
replaceFunction(module, p.first.c_str(), p.second.c_str());
}
}

// Needs to happen after linking (since ctors/dtors can be modified)
Expand Down
16 changes: 16 additions & 0 deletions lib/Module/ModuleUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,19 @@ bool klee::loadFileAsOneModule(
}
return res;
}

void klee::replaceOrRenameFunction(llvm::Module *module, const char *old_name,
const char *new_name) {
Function *new_function, *old_function;
new_function = module->getFunction(new_name);
old_function = module->getFunction(old_name);
if (old_function) {
if (new_function) {
old_function->replaceAllUsesWith(new_function);
old_function->eraseFromParent();
} else {
old_function->setName(new_name);
assert(old_function->getName() == new_name);
}
}
}
5 changes: 3 additions & 2 deletions lib/Solver/CexCachingSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,11 @@ bool CexCachingSolver::computeInitialValues(
// FIXME: We should use smarter assignment for result so we don't
// need redundant copy.
values = std::vector<SparseStorage<unsigned char>>(objects.size());
Assignment::bindings_ty aBindings;
a->tryGetInitialValues(aBindings);

for (unsigned i = 0; i < objects.size(); ++i) {
const Array *os = objects[i];
Assignment::bindings_ty aBindings;
a->tryGetInitialValues(aBindings);
Assignment::bindings_ty::iterator it = aBindings.find(os);

if (it == aBindings.end()) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Solver/ConcretizingSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ bool ConcretizingSolver::relaxSymcreteConstraints(const Query &query,
sizeSymcrete->addressSymcrete.symcretized, newSize);
unsigned char *charAddressIterator =
reinterpret_cast<unsigned char *>(&address);
SparseStorage<unsigned char> storage(sizeof(address));
SparseStorage<unsigned char> storage(0);
storage.store(0, charAddressIterator,
charAddressIterator + sizeof(address));

Expand Down
2 changes: 1 addition & 1 deletion lib/Solver/IndependentSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ bool IndependentSolver::computeInitialValues(
dyn_cast<ConstantExpr>(retMap.evaluate(arr->size));
assert(arrayConstantSize &&
"Array of symbolic size had not receive value for size!");
SparseStorage<unsigned char> ret(arrayConstantSize->getZExtValue());
SparseStorage<unsigned char> ret(0);
values.push_back(ret);
} else {
values.push_back(retMap.bindings.at(arr));
Expand Down
12 changes: 6 additions & 6 deletions runtime/klee-fp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
set(LIB_PREFIX "RuntimeFp")
set(SRC_FILES
ceil.c
klee_copysign.c
copysign.c
exp.c
fabs.c
klee_fenv.c
klee_floor.c
fenv.c
floor.c
fpclassify.c
klee_internal_isinf.ll
klee_rint.c
isinf.ll
klee_set_rounding_mode.c
klee_signbit.ll
log.c
rint.c
round.c
signbit.ll
sqrt.c
trigonometry.c
)
Expand Down
16 changes: 8 additions & 8 deletions runtime/klee-fp/ceil.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,26 @@
//===----------------------------------------------------------------------===*/

#include "float.h"
#include "klee_floor.h"
#include "klee_rint.h"
#include "floor.h"
#include "rint.h"

float ceilf(float f) {
if (f == klee_internal_rintf(f)) {
if (f == rintf(f)) {
return f;
}
return ((f < 0.0f) ? -1 : 1) + klee_floorf(f);
return ((f < 0.0f) ? -1 : 1) + floorf(f);
}

double ceil(double f) {
if (f == klee_internal_rint(f)) {
if (f == rint(f)) {
return f;
}
return ((f < 0.0f) ? -1 : 1) + klee_floor(f);
return ((f < 0.0f) ? -1 : 1) + floor(f);
}

long double ceill(long double f) {
if (f == klee_internal_rintl(f)) {
if (f == rintl(f)) {
return f;
}
return ((f < 0.0f) ? -1 : 1) + klee_floorl(f);
return ((f < 0.0f) ? -1 : 1) + floorl(f);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*===-- klee_copysign.c ---------------------------------------------------===//
/*===-- copysign.c --------------------------------------------------------===//
//
// The KLEE Symbolic Virtual Machine
//
Expand All @@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===*/

#include "klee_copysign.h"
#include "copysign.h"
#include "ansidecl.h"
#include "klee/klee.h"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*===-- klee_copysign.h ---------------------------------------------------===//
/*===-- copysign.h --------------------------------------------------------===//
//
// The KLEE Symbolic Virtual Machine
//
Expand Down
8 changes: 3 additions & 5 deletions runtime/klee-fp/fabs.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@
//===----------------------------------------------------------------------===*/
#include "klee/klee.h"

double klee_internal_fabs(double d) { return klee_abs_double(d); }
double fabs(double d) { return klee_abs_double(d); }

float klee_internal_fabsf(float f) { return klee_abs_float(f); }
float fabsf(float f) { return klee_abs_float(f); }

#if defined(__x86_64__) || defined(__i386__)
long double klee_internal_fabsl(long double f) {
return klee_abs_long_double(f);
}
long double fabsl(long double f) { return klee_abs_long_double(f); }
#endif
8 changes: 4 additions & 4 deletions runtime/klee-fp/klee_fenv.c → runtime/klee-fp/fenv.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*===-- klee_fenv.c -------------------------------------------------------===//
/*===-- fenv.c ------------------------------------------------------------===//
//
// The KLEE Symbolic Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===*/
#include "klee_fenv.h"
#include "fenv.h"
#include "klee/klee.h"

// Define the constants. Don't include `fenv.h` here to avoid
Expand All @@ -28,7 +28,7 @@ enum {
#error Architecture not supported
#endif

int klee_internal_fegetround(void) {
int fegetround(void) {
enum KleeRoundingMode rm = klee_get_rounding_mode();
switch (rm) {
case KLEE_FP_RNE:
Expand All @@ -52,7 +52,7 @@ int klee_internal_fegetround(void) {
}
}

int klee_internal_fesetround(int rm) {
int fesetround(int rm) {
switch (rm) {
case FE_TONEAREST:
klee_set_rounding_mode(KLEE_FP_RNE);
Expand Down
4 changes: 2 additions & 2 deletions runtime/klee-fp/klee_fenv.h → runtime/klee-fp/fenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define KLEE_FENV_H
#include "klee/klee.h"

int klee_internal_fegetround(void);
int klee_internal_fesetround(int rm);
int fegetround(void);
int fesetround(int rm);

#endif // KLEE_FENV_H
Loading
Loading