Skip to content

Commit f5f7574

Browse files
Columpiomisonijnik
authored andcommitted
[fix] Tests for states with mocks
1 parent 390866f commit f5f7574

File tree

5 files changed

+70
-36
lines changed

5 files changed

+70
-36
lines changed

lib/Core/ExecutionState.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -363,26 +363,6 @@ void ExecutionState::addUniquePointerResolution(ref<Expr> address,
363363
}
364364
}
365365

366-
bool ExecutionState::resolveOnSymbolics(const ref<ConstantExpr> &addr,
367-
IDType &result) const {
368-
uint64_t address = addr->getZExtValue();
369-
370-
for (const auto &res : symbolics) {
371-
const auto &mo = res.memoryObject;
372-
// Check if the provided address is between start and end of the object
373-
// [mo->address, mo->address + mo->size) or the object is a 0-sized object.
374-
ref<ConstantExpr> size = cast<ConstantExpr>(
375-
constraints.cs().concretization().evaluate(mo->getSizeExpr()));
376-
if ((size->getZExtValue() == 0 && address == mo->address) ||
377-
(address - mo->address < size->getZExtValue())) {
378-
result = mo->id;
379-
return true;
380-
}
381-
}
382-
383-
return false;
384-
}
385-
386366
/**/
387367

388368
llvm::raw_ostream &klee::operator<<(llvm::raw_ostream &os,

lib/Core/ExecutionState.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,6 @@ class ExecutionState {
428428
unsigned size = 0);
429429
void addUniquePointerResolution(ref<Expr> address, const MemoryObject *mo,
430430
unsigned size = 0);
431-
bool resolveOnSymbolics(const ref<ConstantExpr> &addr, IDType &result) const;
432431

433432
void addConstraint(ref<Expr> e, const Assignment &c);
434433
void addCexPreference(const ref<Expr> &cond);

lib/Core/Executor.cpp

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6949,19 +6949,43 @@ void Executor::logState(const ExecutionState &state, int id,
69496949
}
69506950
}
69516951

6952-
void Executor::setInitializationGraph(const ExecutionState &state,
6953-
const Assignment &model, KTest &ktest) {
6952+
bool resolveOnSymbolics(const std::vector<klee::Symbolic> &symbolics,
6953+
const Assignment &assn,
6954+
const ref<klee::ConstantExpr> &addr, IDType &result) {
6955+
uint64_t address = addr->getZExtValue();
6956+
6957+
for (const auto &res : symbolics) {
6958+
const auto &mo = res.memoryObject;
6959+
// Check if the provided address is between start and end of the object
6960+
// [mo->address, mo->address + mo->size) or the object is a 0-sized object.
6961+
ref<klee::ConstantExpr> size =
6962+
cast<klee::ConstantExpr>(assn.evaluate(mo->getSizeExpr()));
6963+
if ((size->getZExtValue() == 0 && address == mo->address) ||
6964+
(address - mo->address < size->getZExtValue())) {
6965+
result = mo->id;
6966+
return true;
6967+
}
6968+
}
6969+
6970+
return false;
6971+
}
6972+
6973+
void Executor::setInitializationGraph(
6974+
const ExecutionState &state, const std::vector<klee::Symbolic> &symbolics,
6975+
const Assignment &model, KTest &ktest) {
69546976
std::map<size_t, std::vector<Pointer>> pointers;
69556977
std::map<size_t, std::map<unsigned, std::pair<unsigned, unsigned>>> s;
69566978
ExprHashMap<std::pair<IDType, ref<Expr>>> resolvedPointers;
69576979

69586980
std::unordered_map<IDType, ref<const MemoryObject>> idToSymbolics;
6959-
for (const auto &symbolic : state.symbolics) {
6981+
for (const auto &symbolic : symbolics) {
69606982
ref<const MemoryObject> mo = symbolic.memoryObject;
69616983
idToSymbolics[mo->id] = mo;
69626984
}
69636985

6964-
for (const auto &symbolic : state.symbolics) {
6986+
const klee::Assignment &assn = state.constraints.cs().concretization();
6987+
6988+
for (const auto &symbolic : symbolics) {
69656989
KType *symbolicType = symbolic.type;
69666990
if (!symbolicType->getRawType()) {
69676991
continue;
@@ -6989,7 +7013,7 @@ void Executor::setInitializationGraph(const ExecutionState &state,
69897013
ref<ConstantExpr> constantAddress = cast<ConstantExpr>(addressInModel);
69907014
IDType idResult;
69917015

6992-
if (state.resolveOnSymbolics(constantAddress, idResult)) {
7016+
if (resolveOnSymbolics(symbolics, assn, constantAddress, idResult)) {
69937017
ref<const MemoryObject> mo = idToSymbolics[idResult];
69947018
resolvedPointers[address] =
69957019
std::make_pair(idResult, mo->getOffsetExpr(address));
@@ -7024,12 +7048,12 @@ void Executor::setInitializationGraph(const ExecutionState &state,
70247048
// The objects have to be symbolic
70257049
bool pointerFound = false, pointeeFound = false;
70267050
size_t pointerIndex = 0, pointeeIndex = 0;
7027-
for (size_t i = 0; i < state.symbolics.size(); i++) {
7028-
if (state.symbolics[i].memoryObject == pointerResolution.first) {
7051+
for (size_t i = 0; i < symbolics.size(); i++) {
7052+
if (symbolics[i].memoryObject == pointerResolution.first) {
70297053
pointerIndex = i;
70307054
pointerFound = true;
70317055
}
7032-
if (state.symbolics[i].memoryObject->id == pointer.second.first) {
7056+
if (symbolics[i].memoryObject->id == pointer.second.first) {
70337057
pointeeIndex = i;
70347058
pointeeFound = true;
70357059
}
@@ -7081,6 +7105,16 @@ Assignment Executor::computeConcretization(const ConstraintSet &constraints,
70817105
return concretization;
70827106
}
70837107

7108+
bool isReproducible(const klee::Symbolic &symb) {
7109+
auto arr = symb.array;
7110+
bool bad = IrreproducibleSource::classof(arr->source.get());
7111+
if (bad)
7112+
klee_warning_once(arr->source.get(),
7113+
"A irreproducible symbolic %s reaches a test",
7114+
arr->getIdentifier().c_str());
7115+
return !bad;
7116+
}
7117+
70847118
bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
70857119
solver->setTimeout(coreSolverTimeout);
70867120

@@ -7117,10 +7151,14 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
71177151
}
71187152
}
71197153

7154+
std::vector<klee::Symbolic> symbolics;
7155+
std::copy_if(state.symbolics.begin(), state.symbolics.end(),
7156+
std::back_inserter(symbolics), isReproducible);
7157+
71207158
std::vector<SparseStorage<unsigned char>> values;
71217159
std::vector<const Array *> objects;
7122-
for (unsigned i = 0; i != state.symbolics.size(); ++i)
7123-
objects.push_back(state.symbolics[i].array);
7160+
for (unsigned i = 0; i != symbolics.size(); ++i)
7161+
objects.push_back(symbolics[i].array);
71247162
bool success = solver->getInitialValues(extendedConstraints.cs(), objects,
71257163
values, state.queryMetaData);
71267164
solver->setTimeout(time::Span());
@@ -7131,11 +7169,11 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
71317169
return false;
71327170
}
71337171

7134-
res.objects = new KTestObject[state.symbolics.size()];
7135-
res.numObjects = state.symbolics.size();
7172+
res.objects = new KTestObject[symbolics.size()];
7173+
res.numObjects = symbolics.size();
71367174

7137-
for (unsigned i = 0; i != state.symbolics.size(); ++i) {
7138-
auto mo = state.symbolics[i].memoryObject;
7175+
for (unsigned i = 0; i != symbolics.size(); ++i) {
7176+
auto mo = symbolics[i].memoryObject;
71397177
KTestObject *o = &res.objects[i];
71407178
o->name = const_cast<char *>(mo->name.c_str());
71417179
o->address = mo->address;
@@ -7151,7 +7189,7 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
71517189
model.bindings.insert(binding);
71527190
}
71537191

7154-
setInitializationGraph(state, model, res);
7192+
setInitializationGraph(state, symbolics, model, res);
71557193

71567194
return true;
71577195
}

lib/Core/Executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ class Executor : public Interpreter {
793793
Interpreter::LogType logFormat = Interpreter::STP) override;
794794

795795
void setInitializationGraph(const ExecutionState &state,
796+
const std::vector<klee::Symbolic> &symbolics,
796797
const Assignment &model, KTest &tc);
797798

798799
void logState(const ExecutionState &state, int id,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Darwin does not support section attribute: `argument to 'section' attribute is not valid for this target: mach-o section specifier requires a segment whose length is between 1 and 16 characters`
2+
// REQUIRES: not-darwin
3+
// RUN: %clang %s -g -emit-llvm %O0opt -c -o %t1.bc
4+
// RUN: rm -rf %t.klee-out
5+
// RUN: %klee --mock-all-externals --write-xml-tests --output-dir=%t.klee-out %t1.bc
6+
// RUN: FileCheck --input-file %t.klee-out/test000001.xml %s
7+
8+
extern void *__crc_mc44s803_attach __attribute__((__weak__));
9+
static unsigned long const __kcrctab_mc44s803_attach __attribute__((__used__, __unused__,
10+
__section__("___kcrctab+mc44s803_attach"))) = (unsigned long const)((unsigned long)(&__crc_mc44s803_attach));
11+
12+
int main() {
13+
return 0;
14+
}
15+
16+
// CHECK-NOT: <input

0 commit comments

Comments
 (0)