00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "AddressSpace.h"
00011 #include "CoreStats.h"
00012 #include "Memory.h"
00013 #include "TimingSolver.h"
00014
00015 #include "klee/Expr.h"
00016 #include "klee/TimerStatIncrementer.h"
00017
00018 using namespace klee;
00019
00021
00022 void AddressSpace::bindObject(const MemoryObject *mo, ObjectState *os) {
00023 assert(os->copyOnWriteOwner==0 && "object already has owner");
00024 os->copyOnWriteOwner = cowKey;
00025 objects = objects.replace(std::make_pair(mo, os));
00026 }
00027
00028 void AddressSpace::unbindObject(const MemoryObject *mo) {
00029 objects = objects.remove(mo);
00030 }
00031
00032 const ObjectState *AddressSpace::findObject(const MemoryObject *mo) const {
00033 const MemoryMap::value_type *res = objects.lookup(mo);
00034
00035 return res ? res->second : 0;
00036 }
00037
00038 ObjectState *AddressSpace::getWriteable(const MemoryObject *mo,
00039 const ObjectState *os) {
00040 assert(!os->readOnly);
00041
00042 if (cowKey==os->copyOnWriteOwner) {
00043 return const_cast<ObjectState*>(os);
00044 } else {
00045 ObjectState *n = new ObjectState(*os);
00046 n->copyOnWriteOwner = cowKey;
00047 objects = objects.replace(std::make_pair(mo, n));
00048 return n;
00049 }
00050 }
00051
00053
00054 bool AddressSpace::resolveOne(uint64_t addr64, ObjectPair &result) {
00055 unsigned address = (unsigned) addr64;
00056 MemoryObject hack(address);
00057
00058 if (const MemoryMap::value_type *res = objects.lookup_previous(&hack)) {
00059 const MemoryObject *mo = res->first;
00060 if ((mo->size==0 && address==mo->address) ||
00061 (address - mo->address < mo->size)) {
00062 result = *res;
00063 return true;
00064 }
00065 }
00066
00067 return false;
00068 }
00069
00070 bool AddressSpace::resolveOne(ExecutionState &state,
00071 TimingSolver *solver,
00072 ref<Expr> address,
00073 ObjectPair &result,
00074 bool &success) {
00075 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(address)) {
00076 success = resolveOne(CE->getConstantValue(), result);
00077 return true;
00078 } else {
00079 TimerStatIncrementer timer(stats::resolveTime);
00080
00081
00082
00083 ref<ConstantExpr> cex;
00084 if (!solver->getValue(state, address, cex))
00085 return false;
00086 unsigned example = (unsigned) cex->getConstantValue();
00087 MemoryObject hack(example);
00088 const MemoryMap::value_type *res = objects.lookup_previous(&hack);
00089
00090 if (res) {
00091 const MemoryObject *mo = res->first;
00092 if (example - mo->address < mo->size) {
00093 result = *res;
00094 success = true;
00095 return true;
00096 }
00097 }
00098
00099
00100
00101 MemoryMap::iterator oi = objects.upper_bound(&hack);
00102 MemoryMap::iterator begin = objects.begin();
00103 MemoryMap::iterator end = objects.end();
00104
00105 MemoryMap::iterator start = oi;
00106 while (oi!=begin) {
00107 --oi;
00108 const MemoryObject *mo = oi->first;
00109
00110 bool mayBeTrue;
00111 if (!solver->mayBeTrue(state,
00112 mo->getBoundsCheckPointer(address), mayBeTrue))
00113 return false;
00114 if (mayBeTrue) {
00115 result = *oi;
00116 success = true;
00117 return true;
00118 } else {
00119 bool mustBeTrue;
00120 if (!solver->mustBeTrue(state,
00121 UgeExpr::create(address, mo->getBaseExpr()),
00122 mustBeTrue))
00123 return false;
00124 if (mustBeTrue)
00125 break;
00126 }
00127 }
00128
00129
00130 for (oi=start; oi!=end; ++oi) {
00131 const MemoryObject *mo = oi->first;
00132
00133 bool mustBeTrue;
00134 if (!solver->mustBeTrue(state,
00135 UltExpr::create(address, mo->getBaseExpr()),
00136 mustBeTrue))
00137 return false;
00138 if (mustBeTrue) {
00139 break;
00140 } else {
00141 bool mayBeTrue;
00142
00143 if (!solver->mayBeTrue(state,
00144 mo->getBoundsCheckPointer(address),
00145 mayBeTrue))
00146 return false;
00147 if (mayBeTrue) {
00148 result = *oi;
00149 success = true;
00150 return true;
00151 }
00152 }
00153 }
00154
00155 success = false;
00156 return true;
00157 }
00158 }
00159
00160 bool AddressSpace::resolve(ExecutionState &state,
00161 TimingSolver *solver,
00162 ref<Expr> p,
00163 ResolutionList &rl,
00164 unsigned maxResolutions,
00165 double timeout) {
00166 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(p)) {
00167 ObjectPair res;
00168 if (resolveOne(CE->getConstantValue(), res))
00169 rl.push_back(res);
00170 return false;
00171 } else {
00172 TimerStatIncrementer timer(stats::resolveTime);
00173 uint64_t timeout_us = (uint64_t) (timeout*1000000.);
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 ref<ConstantExpr> cex;
00191 if (!solver->getValue(state, p, cex))
00192 return true;
00193 unsigned example = (unsigned) cex->getConstantValue();
00194 MemoryObject hack(example);
00195
00196 MemoryMap::iterator oi = objects.upper_bound(&hack);
00197 MemoryMap::iterator begin = objects.begin();
00198 MemoryMap::iterator end = objects.end();
00199
00200 MemoryMap::iterator start = oi;
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 while (oi!=begin) {
00211 --oi;
00212 const MemoryObject *mo = oi->first;
00213 if (timeout_us && timeout_us < timer.check())
00214 return true;
00215
00216
00217 ref<Expr> inBounds = mo->getBoundsCheckPointer(p);
00218 bool mayBeTrue;
00219 if (!solver->mayBeTrue(state, inBounds, mayBeTrue))
00220 return true;
00221 if (mayBeTrue) {
00222 rl.push_back(*oi);
00223
00224
00225 unsigned size = rl.size();
00226 if (size==1) {
00227 bool mustBeTrue;
00228 if (!solver->mustBeTrue(state, inBounds, mustBeTrue))
00229 return true;
00230 if (mustBeTrue)
00231 return false;
00232 } else if (size==maxResolutions) {
00233 return true;
00234 }
00235 }
00236
00237 bool mustBeTrue;
00238 if (!solver->mustBeTrue(state,
00239 UgeExpr::create(p, mo->getBaseExpr()),
00240 mustBeTrue))
00241 return true;
00242 if (mustBeTrue)
00243 break;
00244 }
00245
00246 for (oi=start; oi!=end; ++oi) {
00247 const MemoryObject *mo = oi->first;
00248 if (timeout_us && timeout_us < timer.check())
00249 return true;
00250
00251 bool mustBeTrue;
00252 if (!solver->mustBeTrue(state,
00253 UltExpr::create(p, mo->getBaseExpr()),
00254 mustBeTrue))
00255 return true;
00256 if (mustBeTrue)
00257 break;
00258
00259
00260 ref<Expr> inBounds = mo->getBoundsCheckPointer(p);
00261 bool mayBeTrue;
00262 if (!solver->mayBeTrue(state, inBounds, mayBeTrue))
00263 return true;
00264 if (mayBeTrue) {
00265 rl.push_back(*oi);
00266
00267
00268 unsigned size = rl.size();
00269 if (size==1) {
00270 bool mustBeTrue;
00271 if (!solver->mustBeTrue(state, inBounds, mustBeTrue))
00272 return true;
00273 if (mustBeTrue)
00274 return false;
00275 } else if (size==maxResolutions) {
00276 return true;
00277 }
00278 }
00279 }
00280 }
00281
00282 return false;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 void AddressSpace::copyOutConcretes() {
00292 for (MemoryMap::iterator it = objects.begin(), ie = objects.end();
00293 it != ie; ++it) {
00294 const MemoryObject *mo = it->first;
00295
00296 if (!mo->isUserSpecified) {
00297 ObjectState *os = it->second;
00298 uint8_t *address = (uint8_t*) (unsigned long) mo->address;
00299
00300 if (!os->readOnly)
00301 memcpy(address, os->concreteStore, mo->size);
00302 }
00303 }
00304 }
00305
00306 bool AddressSpace::copyInConcretes() {
00307 for (MemoryMap::iterator it = objects.begin(), ie = objects.end();
00308 it != ie; ++it) {
00309 const MemoryObject *mo = it->first;
00310
00311 if (!mo->isUserSpecified) {
00312 const ObjectState *os = it->second;
00313 uint8_t *address = (uint8_t*) (unsigned long) mo->address;
00314
00315 if (memcmp(address, os->concreteStore, mo->size)!=0) {
00316 if (os->readOnly) {
00317 return false;
00318 } else {
00319 ObjectState *wos = getWriteable(mo, os);
00320 memcpy(wos->concreteStore, address, mo->size);
00321 }
00322 }
00323 }
00324 }
00325
00326 return true;
00327 }
00328
00329
00330
00331 bool MemoryObjectLT::operator()(const MemoryObject *a, const MemoryObject *b) const {
00332 return a->address < b->address;
00333 }
00334