@@ -6949,19 +6949,43 @@ void Executor::logState(const ExecutionState &state, int id,
6949
6949
}
6950
6950
}
6951
6951
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) {
6954
6976
std::map<size_t , std::vector<Pointer>> pointers;
6955
6977
std::map<size_t , std::map<unsigned , std::pair<unsigned , unsigned >>> s;
6956
6978
ExprHashMap<std::pair<IDType, ref<Expr>>> resolvedPointers;
6957
6979
6958
6980
std::unordered_map<IDType, ref<const MemoryObject>> idToSymbolics;
6959
- for (const auto &symbolic : state. symbolics ) {
6981
+ for (const auto &symbolic : symbolics) {
6960
6982
ref<const MemoryObject> mo = symbolic.memoryObject ;
6961
6983
idToSymbolics[mo->id ] = mo;
6962
6984
}
6963
6985
6964
- for (const auto &symbolic : state.symbolics ) {
6986
+ const klee::Assignment &assn = state.constraints .cs ().concretization ();
6987
+
6988
+ for (const auto &symbolic : symbolics) {
6965
6989
KType *symbolicType = symbolic.type ;
6966
6990
if (!symbolicType->getRawType ()) {
6967
6991
continue ;
@@ -6989,7 +7013,7 @@ void Executor::setInitializationGraph(const ExecutionState &state,
6989
7013
ref<ConstantExpr> constantAddress = cast<ConstantExpr>(addressInModel);
6990
7014
IDType idResult;
6991
7015
6992
- if (state. resolveOnSymbolics (constantAddress, idResult)) {
7016
+ if (resolveOnSymbolics (symbolics, assn, constantAddress, idResult)) {
6993
7017
ref<const MemoryObject> mo = idToSymbolics[idResult];
6994
7018
resolvedPointers[address] =
6995
7019
std::make_pair (idResult, mo->getOffsetExpr (address));
@@ -7024,12 +7048,12 @@ void Executor::setInitializationGraph(const ExecutionState &state,
7024
7048
// The objects have to be symbolic
7025
7049
bool pointerFound = false , pointeeFound = false ;
7026
7050
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 ) {
7029
7053
pointerIndex = i;
7030
7054
pointerFound = true ;
7031
7055
}
7032
- if (state. symbolics [i].memoryObject ->id == pointer.second .first ) {
7056
+ if (symbolics[i].memoryObject ->id == pointer.second .first ) {
7033
7057
pointeeIndex = i;
7034
7058
pointeeFound = true ;
7035
7059
}
@@ -7081,6 +7105,16 @@ Assignment Executor::computeConcretization(const ConstraintSet &constraints,
7081
7105
return concretization;
7082
7106
}
7083
7107
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
+
7084
7118
bool Executor::getSymbolicSolution (const ExecutionState &state, KTest &res) {
7085
7119
solver->setTimeout (coreSolverTimeout);
7086
7120
@@ -7117,10 +7151,14 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
7117
7151
}
7118
7152
}
7119
7153
7154
+ std::vector<klee::Symbolic> symbolics;
7155
+ std::copy_if (state.symbolics .begin (), state.symbolics .end (),
7156
+ std::back_inserter (symbolics), isReproducible);
7157
+
7120
7158
std::vector<SparseStorage<unsigned char >> values;
7121
7159
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 );
7124
7162
bool success = solver->getInitialValues (extendedConstraints.cs (), objects,
7125
7163
values, state.queryMetaData );
7126
7164
solver->setTimeout (time::Span ());
@@ -7131,11 +7169,11 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
7131
7169
return false ;
7132
7170
}
7133
7171
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 ();
7136
7174
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 ;
7139
7177
KTestObject *o = &res.objects [i];
7140
7178
o->name = const_cast <char *>(mo->name .c_str ());
7141
7179
o->address = mo->address ;
@@ -7151,7 +7189,7 @@ bool Executor::getSymbolicSolution(const ExecutionState &state, KTest &res) {
7151
7189
model.bindings .insert (binding);
7152
7190
}
7153
7191
7154
- setInitializationGraph (state, model, res);
7192
+ setInitializationGraph (state, symbolics, model, res);
7155
7193
7156
7194
return true ;
7157
7195
}
0 commit comments