Skip to content

Commit 8f9b33c

Browse files
committed
[wip] Add persistent list workaround
1 parent a84c6ce commit 8f9b33c

File tree

4 files changed

+121
-31
lines changed

4 files changed

+121
-31
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ else()
302302
message(STATUS "TCMalloc support disabled")
303303
endif()
304304

305+
306+
list(APPEND KLEE_COMPONENT_CXX_FLAGS "-gdwarf-4")
307+
305308
################################################################################
306309
# Detect SQLite3
307310
################################################################################

lib/Core/ExecutionState.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ InfoStackFrame::InfoStackFrame(const InfoStackFrame &s)
123123
/***/
124124
ExecutionState::ExecutionState()
125125
: initPC(nullptr), pc(nullptr), prevPC(nullptr), incomingBBIndex(-1),
126-
depth(0), ptreeNode(nullptr), steppedInstructions(0),
126+
depth(0), ptreeNode(nullptr), symbolics(std::make_shared<PList>()), steppedInstructions(0),
127127
steppedMemoryInstructions(0), instsSinceCovNew(0),
128128
roundingMode(llvm::APFloat::rmNearestTiesToEven), coveredNew(false),
129129
forkDisabled(false), prevHistory_(TargetsHistory::create()),
@@ -133,7 +133,7 @@ ExecutionState::ExecutionState()
133133

134134
ExecutionState::ExecutionState(KFunction *kf)
135135
: initPC(kf->instructions), pc(initPC), prevPC(pc), incomingBBIndex(-1),
136-
depth(0), ptreeNode(nullptr), steppedInstructions(0),
136+
depth(0), ptreeNode(nullptr), symbolics(std::make_shared<PList>()), steppedInstructions(0),
137137
steppedMemoryInstructions(0), instsSinceCovNew(0),
138138
roundingMode(llvm::APFloat::rmNearestTiesToEven), coveredNew(false),
139139
forkDisabled(false), prevHistory_(TargetsHistory::create()),
@@ -144,7 +144,7 @@ ExecutionState::ExecutionState(KFunction *kf)
144144

145145
ExecutionState::ExecutionState(KFunction *kf, KBlock *kb)
146146
: initPC(kb->instructions), pc(initPC), prevPC(pc), incomingBBIndex(-1),
147-
depth(0), ptreeNode(nullptr), steppedInstructions(0),
147+
depth(0), ptreeNode(nullptr), symbolics(std::make_shared<PList>()), steppedInstructions(0),
148148
steppedMemoryInstructions(0), instsSinceCovNew(0),
149149
roundingMode(llvm::APFloat::rmNearestTiesToEven), coveredNew(false),
150150
forkDisabled(false), prevHistory_(TargetsHistory::create()),
@@ -194,8 +194,8 @@ ExecutionState *ExecutionState::branch() {
194194
}
195195

196196
bool ExecutionState::inSymbolics(const MemoryObject *mo) const {
197-
for (auto i : symbolics) {
198-
if (mo->id == i.memoryObject->id) {
197+
for (auto &symbolic : *symbolics) {
198+
if (mo->id == symbolic.memoryObject->id) {
199199
return true;
200200
}
201201
}
@@ -255,13 +255,12 @@ void ExecutionState::popFrame() {
255255

256256
void ExecutionState::addSymbolic(const MemoryObject *mo, const Array *array,
257257
KType *type) {
258-
symbolics.emplace_back(ref<const MemoryObject>(mo), array, type);
258+
symbolics->emplace_back(mo, array, type);
259259
}
260260

261261
ref<const MemoryObject>
262262
ExecutionState::findMemoryObject(const Array *array) const {
263-
for (unsigned i = 0; i != symbolics.size(); ++i) {
264-
const auto &symbolic = symbolics[i];
263+
for (const auto &symbolic : *symbolics) {
265264
if (array == symbolic.array) {
266265
return symbolic.memoryObject;
267266
}
@@ -368,7 +367,7 @@ bool ExecutionState::resolveOnSymbolics(const ref<ConstantExpr> &addr,
368367
IDType &result) const {
369368
uint64_t address = addr->getZExtValue();
370369

371-
for (const auto &res : symbolics) {
370+
for (const auto &res : *symbolics) {
372371
const auto &mo = res.memoryObject;
373372
// Check if the provided address is between start and end of the object
374373
// [mo->address, mo->address + mo->size) or the object is a 0-sized object.

lib/Core/ExecutionState.h

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ DISABLE_WARNING_POP
4141
#include <utility>
4242
#include <vector>
4343

44+
#include <list>
45+
4446
namespace klee {
4547
class Array;
4648
class CallPathNode;
@@ -223,6 +225,85 @@ struct Symbolic {
223225
}
224226
};
225227

228+
struct PList {
229+
private:
230+
std::shared_ptr<const PList> prev;
231+
size_t prev_len;
232+
std::vector<Symbolic> curr;
233+
234+
public:
235+
size_t size() const { return prev_len + curr.size(); }
236+
237+
struct iterator {
238+
const PList *curr;
239+
std::unique_ptr<iterator> it;
240+
size_t get;
241+
242+
public:
243+
explicit iterator(const PList *p) : curr(p), it(nullptr), get(0) {
244+
if (curr->prev.get()) {
245+
it = std::make_unique<iterator>(curr->prev.get());
246+
}
247+
}
248+
249+
bool operator==(const iterator &b) const {
250+
return curr == b.curr && get == b.get;
251+
}
252+
bool operator!=(const iterator &b) const { return !(*this == b); }
253+
254+
iterator &operator++() {
255+
++get;
256+
if (get < curr->prev_len) {
257+
return it->operator++();
258+
}
259+
return *this;
260+
}
261+
262+
const Symbolic &operator*() const {
263+
if (get < curr->prev_len) {
264+
return it->operator*();
265+
}
266+
return curr->curr[get - curr->prev_len];
267+
}
268+
269+
const Symbolic &operator->() const { return **this; }
270+
};
271+
272+
[[nodiscard]] iterator begin() const { return iterator(this); }
273+
274+
[[nodiscard]] iterator end() const {
275+
auto it = iterator(this);
276+
it.get = size();
277+
return it;
278+
}
279+
280+
[[nodiscard]] iterator begin() { return iterator(this); }
281+
282+
[[nodiscard]] iterator end() {
283+
auto it = iterator(this);
284+
it.get = size();
285+
return it;
286+
}
287+
288+
void emplace_back(const MemoryObject *mo, const Array *array, KType *type) {
289+
curr.emplace_back(ref<const MemoryObject>(mo), array, type);
290+
}
291+
292+
PList() : prev(nullptr), prev_len(0), curr(){};
293+
PList(std::shared_ptr<const PList> pr) : curr() {
294+
while (pr && pr->prev && pr->prev_len == pr->prev->prev_len) {
295+
pr = pr->prev;
296+
}
297+
if (pr && pr->size()) {
298+
prev = pr;
299+
prev_len = pr->size();
300+
} else {
301+
prev = nullptr;
302+
prev_len = 0;
303+
}
304+
}
305+
};
306+
226307
struct MemorySubobject {
227308
ref<Expr> address;
228309
unsigned size;
@@ -326,7 +407,7 @@ class ExecutionState {
326407
/// @brief Ordered list of symbolics: used to generate test cases.
327408
//
328409
// FIXME: Move to a shared list structure (not critical).
329-
std::vector<Symbolic> symbolics;
410+
std::shared_ptr<PList> symbolics;
330411

331412
/// @brief map from memory accesses to accessed objects and access offsets.
332413
ExprHashMap<std::set<IDType>> resolvedPointers;

lib/Core/Executor.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6900,10 +6900,10 @@ void Executor::logState(const ExecutionState &state, int id,
69006900
*f << "Address memory object: " << object.first->address << "\n";
69016901
*f << "Memory object size: " << object.first->size << "\n";
69026902
}
6903-
*f << state.symbolics.size() << " symbolics total. "
6903+
*f << state.symbolics->size() << " symbolics total. "
69046904
<< "Symbolics:\n";
69056905
size_t sc = 0;
6906-
for (auto &symbolic : state.symbolics) {
6906+
for (auto &symbolic : *state.symbolics) {
69076907
*f << "Symbolic number " << sc++ << "\n";
69086908
*f << "Associated memory object: " << symbolic.memoryObject.get()->id
69096909
<< "\n";
@@ -6924,12 +6924,12 @@ void Executor::setInitializationGraph(const ExecutionState &state,
69246924
ExprHashMap<std::pair<IDType, ref<Expr>>> resolvedPointers;
69256925

69266926
std::unordered_map<IDType, ref<const MemoryObject>> idToSymbolics;
6927-
for (const auto &symbolic : state.symbolics) {
6927+
for (const auto &symbolic : *state.symbolics) {
69286928
ref<const MemoryObject> mo = symbolic.memoryObject;
69296929
idToSymbolics[mo->id] = mo;
69306930
}
69316931

6932-
for (const auto &symbolic : state.symbolics) {
6932+
for (const auto &symbolic : *state.symbolics) {
69336933
KType *symbolicType = symbolic.type;
69346934
if (!symbolicType->getRawType()) {
69356935
continue;
@@ -6992,15 +6992,17 @@ void Executor::setInitializationGraph(const ExecutionState &state,
69926992
// The objects have to be symbolic
69936993
bool pointerFound = false, pointeeFound = false;
69946994
size_t pointerIndex = 0, pointeeIndex = 0;
6995-
for (size_t i = 0; i < state.symbolics.size(); i++) {
6996-
if (state.symbolics[i].memoryObject == pointerResolution.first) {
6995+
size_t i = 0;
6996+
for (auto &symbolic : *state.symbolics) {
6997+
if (symbolic.memoryObject == pointerResolution.first) {
69976998
pointerIndex = i;
69986999
pointerFound = true;
69997000
}
7000-
if (state.symbolics[i].memoryObject->id == pointer.second.first) {
7001+
if (symbolic.memoryObject->id == pointer.second.first) {
70017002
pointeeIndex = i;
70027003
pointeeFound = true;
70037004
}
7005+
++i;
70047006
}
70057007
if (pointerFound && pointeeFound) {
70067008
ref<ConstantExpr> offset = model.evaluate(pointerResolution.second);
@@ -7087,8 +7089,9 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
70877089

70887090
std::vector<SparseStorage<unsigned char>> values;
70897091
std::vector<const Array *> objects;
7090-
for (unsigned i = 0; i != state.symbolics.size(); ++i)
7091-
objects.push_back(state.symbolics[i].array);
7092+
for (auto &symbolic : *state.symbolics) {
7093+
objects.push_back(symbolic.array);
7094+
}
70927095
bool success = solver->getInitialValues(extendedConstraints.cs(), objects,
70937096
values, state.queryMetaData);
70947097
solver->setTimeout(time::Span());
@@ -7099,19 +7102,23 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
70997102
return false;
71007103
}
71017104

7102-
res.objects = new KTestObject[state.symbolics.size()];
7103-
res.numObjects = state.symbolics.size();
7105+
res.numObjects = state.symbolics->size();
7106+
res.objects = new KTestObject[res.numObjects];
71047107

7105-
for (unsigned i = 0; i != state.symbolics.size(); ++i) {
7106-
auto mo = state.symbolics[i].memoryObject;
7107-
KTestObject *o = &res.objects[i];
7108-
o->name = const_cast<char *>(mo->name.c_str());
7109-
o->address = mo->address;
7110-
o->numBytes = values[i].size();
7111-
o->bytes = new unsigned char[o->numBytes];
7112-
std::copy(values[i].begin(), values[i].end(), o->bytes);
7113-
o->numPointers = 0;
7114-
o->pointers = nullptr;
7108+
{
7109+
size_t i = 0;
7110+
for (auto &symbolic : *state.symbolics) {
7111+
auto mo = symbolic.memoryObject;
7112+
KTestObject *o = &res.objects[i];
7113+
o->name = const_cast<char *>(mo->name.c_str());
7114+
o->address = mo->address;
7115+
o->numBytes = values[i].size();
7116+
o->bytes = new unsigned char[o->numBytes];
7117+
std::copy(values[i].begin(), values[i].end(), o->bytes);
7118+
o->numPointers = 0;
7119+
o->pointers = nullptr;
7120+
++i;
7121+
}
71157122
}
71167123

71177124
Assignment model = Assignment(objects, values, true);

0 commit comments

Comments
 (0)