@@ -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+
70847118bool 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}
0 commit comments