Memory.cpp

Go to the documentation of this file.
00001 //===-- Memory.cpp --------------------------------------------------------===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "Common.h"
00011 
00012 #include "Memory.h"
00013 
00014 #include "klee/Expr.h"
00015 #include "klee/Machine.h"
00016 #include "klee/Solver.h"
00017 #include "klee/util/BitArray.h"
00018 
00019 #include "ObjectHolder.h"
00020 
00021 #include <llvm/Function.h>
00022 #include <llvm/Instruction.h>
00023 #include <llvm/Value.h>
00024 
00025 #include <iostream>
00026 #include <cassert>
00027 #include <sstream>
00028 
00029 using namespace llvm;
00030 using namespace klee;
00031 
00032 /***/
00033 
00034 ObjectHolder::ObjectHolder(const ObjectHolder &b) : os(b.os) { 
00035   if (os) ++os->refCount; 
00036 }
00037 
00038 ObjectHolder::ObjectHolder(ObjectState *_os) : os(_os) { 
00039   if (os) ++os->refCount; 
00040 }
00041 
00042 ObjectHolder::~ObjectHolder() { 
00043   if (os && --os->refCount==0) delete os; 
00044 }
00045   
00046 ObjectHolder &ObjectHolder::operator=(const ObjectHolder &b) {
00047   if (b.os) ++b.os->refCount;
00048   if (os && --os->refCount==0) delete os;
00049   os = b.os;
00050   return *this;
00051 }
00052 
00053 /***/
00054 
00055 int MemoryObject::counter = 0;
00056 
00057 extern "C" void vc_DeleteExpr(void*);
00058 
00059 MemoryObject::~MemoryObject() {
00060   // FIXME: This shouldn't be necessary. Array's should be ref-counted
00061   // just like everything else, and the interaction with the STP array
00062   // should hide at least inside the Expr/Solver layers.
00063   if (array) {
00064     if (array->stpInitialArray) {
00065       ::vc_DeleteExpr(array->stpInitialArray);
00066       array->stpInitialArray = 0;
00067     }
00068     delete array;
00069   }
00070 }
00071 
00072 void MemoryObject::getAllocInfo(std::string &result) const {
00073   std::ostringstream info;
00074 
00075   info << "MO" << id << "[" << size << "]";
00076 
00077   if (allocSite) {
00078     info << " allocated at ";
00079     if (const Instruction *i = dyn_cast<Instruction>(allocSite)) {
00080       info << i->getParent()->getParent()->getName() << "():";
00081       info << *i;
00082     } else if (const GlobalValue *gv = dyn_cast<GlobalValue>(allocSite)) {
00083       info << "global:" << gv->getName();
00084     } else {
00085       info << "value:" << *allocSite;
00086     }
00087   } else {
00088     info << " (no allocation info)";
00089   }
00090   
00091   result = info.str();
00092 }
00093 
00094 /***/
00095 
00096 ObjectState::ObjectState(const MemoryObject *mo, unsigned _size)
00097   : copyOnWriteOwner(0),
00098     refCount(0),
00099     object(mo),
00100     concreteStore(new uint8_t[_size]),
00101     concreteMask(0),
00102     flushMask(0),
00103     knownSymbolics(0),
00104     size(_size),
00105     updates(mo->array, false, 0),
00106     readOnly(false) {
00107 }
00108 
00109 ObjectState::ObjectState(const ObjectState &os) 
00110   : copyOnWriteOwner(0),
00111     refCount(0),
00112     object(os.object),
00113     concreteStore(new uint8_t[os.size]),
00114     concreteMask(os.concreteMask ? new BitArray(*os.concreteMask, os.size) : 0),
00115     flushMask(os.flushMask ? new BitArray(*os.flushMask, os.size) : 0),
00116     knownSymbolics(0),
00117     size(os.size),
00118     updates(os.updates),
00119     readOnly(false) {
00120   assert(!os.readOnly && "no need to copy read only object?");
00121 
00122   if (os.knownSymbolics) {
00123     knownSymbolics = new ref<Expr>[size];
00124     for (unsigned i=0; i<size; i++)
00125       knownSymbolics[i] = os.knownSymbolics[i];
00126   }
00127 
00128   memcpy(concreteStore, os.concreteStore, size*sizeof(*concreteStore));
00129 }
00130 
00131 ObjectState::~ObjectState() {
00132   if (concreteMask) delete concreteMask;
00133   if (flushMask) delete flushMask;
00134   if (knownSymbolics) delete[] knownSymbolics;
00135   delete[] concreteStore;
00136 }
00137 
00138 /***/
00139 
00140 void ObjectState::makeConcrete() {
00141   if (concreteMask) delete concreteMask;
00142   if (flushMask) delete flushMask;
00143   if (knownSymbolics) delete[] knownSymbolics;
00144   concreteMask = 0;
00145   flushMask = 0;
00146   knownSymbolics = 0;
00147 }
00148 
00149 void ObjectState::makeSymbolic() {
00150   assert(!updates.head &&
00151          "XXX makeSymbolic of objects with symbolic values is unsupported");
00152   updates.isRooted = true;
00153 
00154   // XXX simplify this, can just delete various arrays I guess
00155   for (unsigned i=0; i<size; i++) {
00156     markByteSymbolic(i);
00157     setKnownSymbolic(i, 0);
00158     markByteFlushed(i);
00159   }
00160 }
00161 
00162 void ObjectState::initializeToZero() {
00163   makeConcrete();
00164   memset(concreteStore, 0, size);
00165 }
00166 
00167 void ObjectState::initializeToRandom() {  
00168   makeConcrete();
00169   for (unsigned i=0; i<size; i++) {
00170     // randomly selected by 256 sided die
00171     concreteStore[i] = 0xAB;
00172   }
00173 }
00174 
00175 /*
00176 Cache Invariants
00177 --
00178 isByteKnownSymbolic(i) => !isByteConcrete(i)
00179 isByteConcrete(i) => !isByteKnownSymbolic(i)
00180 !isByteFlushed(i) => (isByteConcrete(i) || isByteKnownSymbolic(i))
00181  */
00182 
00183 void ObjectState::fastRangeCheckOffset(ref<Expr> offset,
00184                                        unsigned *base_r,
00185                                        unsigned *size_r) const {
00186   *base_r = 0;
00187   *size_r = size;
00188 }
00189 
00190 void ObjectState::flushRangeForRead(unsigned rangeBase, 
00191                                     unsigned rangeSize) const {
00192   if (!flushMask) flushMask = new BitArray(size, true);
00193  
00194   for (unsigned offset=rangeBase; offset<rangeBase+rangeSize; offset++) {
00195     if (!isByteFlushed(offset)) {
00196       if (isByteConcrete(offset)) {
00197         updates.extend(ConstantExpr::create(offset, kMachinePointerType),
00198                        ConstantExpr::create(concreteStore[offset], Expr::Int8));
00199       } else {
00200         assert(isByteKnownSymbolic(offset) && "invalid bit set in flushMask");
00201         updates.extend(ConstantExpr::create(offset, kMachinePointerType),
00202                        knownSymbolics[offset]);
00203       }
00204 
00205       flushMask->unset(offset);
00206     }
00207   } 
00208 }
00209 
00210 void ObjectState::flushRangeForWrite(unsigned rangeBase, 
00211                                      unsigned rangeSize) {
00212   if (!flushMask) flushMask = new BitArray(size, true);
00213 
00214   for (unsigned offset=rangeBase; offset<rangeBase+rangeSize; offset++) {
00215     if (!isByteFlushed(offset)) {
00216       if (isByteConcrete(offset)) {
00217         updates.extend(ConstantExpr::create(offset, kMachinePointerType),
00218                        ConstantExpr::create(concreteStore[offset], Expr::Int8));
00219         markByteSymbolic(offset);
00220       } else {
00221         assert(isByteKnownSymbolic(offset) && "invalid bit set in flushMask");
00222         updates.extend(ConstantExpr::create(offset, kMachinePointerType),
00223                        knownSymbolics[offset]);
00224         setKnownSymbolic(offset, 0);
00225       }
00226 
00227       flushMask->unset(offset);
00228     } else {
00229       // flushed bytes that are written over still need
00230       // to be marked out
00231       if (isByteConcrete(offset)) {
00232         markByteSymbolic(offset);
00233       } else if (isByteKnownSymbolic(offset)) {
00234         setKnownSymbolic(offset, 0);
00235       }
00236     }
00237   } 
00238 }
00239 
00240 bool ObjectState::isByteConcrete(unsigned offset) const {
00241   return !concreteMask || concreteMask->get(offset);
00242 }
00243 
00244 bool ObjectState::isByteFlushed(unsigned offset) const {
00245   return flushMask && !flushMask->get(offset);
00246 }
00247 
00248 bool ObjectState::isByteKnownSymbolic(unsigned offset) const {
00249   return knownSymbolics && knownSymbolics[offset].get();
00250 }
00251 
00252 void ObjectState::markByteConcrete(unsigned offset) {
00253   if (concreteMask)
00254     concreteMask->set(offset);
00255 }
00256 
00257 void ObjectState::markByteSymbolic(unsigned offset) {
00258   if (!concreteMask)
00259     concreteMask = new BitArray(size, true);
00260   concreteMask->unset(offset);
00261 }
00262 
00263 void ObjectState::markByteUnflushed(unsigned offset) {
00264   if (flushMask)
00265     flushMask->set(offset);
00266 }
00267 
00268 void ObjectState::markByteFlushed(unsigned offset) {
00269   if (!flushMask) {
00270     flushMask = new BitArray(size, false);
00271   } else {
00272     flushMask->unset(offset);
00273   }
00274 }
00275 
00276 void ObjectState::setKnownSymbolic(unsigned offset, 
00277                                    Expr *value /* can be null */) {
00278   if (knownSymbolics) {
00279     knownSymbolics[offset] = value;
00280   } else {
00281     if (value) {
00282       knownSymbolics = new ref<Expr>[size];
00283       knownSymbolics[offset] = value;
00284     }
00285   }
00286 }
00287 
00288 /***/
00289 
00290 ref<Expr> ObjectState::read8(unsigned offset) const {
00291   if (isByteConcrete(offset)) {
00292     return ConstantExpr::create(concreteStore[offset], Expr::Int8);
00293   } else if (isByteKnownSymbolic(offset)) {
00294     return knownSymbolics[offset];
00295   } else {
00296     assert(isByteFlushed(offset) && "unflushed byte without cache value");
00297     
00298     return ReadExpr::create(updates, 
00299                             ConstantExpr::create(offset, kMachinePointerType));
00300   }    
00301 }
00302 
00303 ref<Expr> ObjectState::read8(ref<Expr> offset) const {
00304   assert(!isa<ConstantExpr>(offset) && "constant offset passed to symbolic read8");
00305   unsigned base, size;
00306   fastRangeCheckOffset(offset, &base, &size);
00307   flushRangeForRead(base, size);
00308 
00309   if (size>4096) {
00310     std::string allocInfo;
00311     object->getAllocInfo(allocInfo);
00312     klee_warning_once(0, "flushing %d bytes on read, may be slow and/or crash: %s", 
00313                       size,
00314                       allocInfo.c_str());
00315   }
00316   
00317   return ReadExpr::create(updates, offset);
00318 }
00319 
00320 void ObjectState::write8(unsigned offset, uint8_t value) {
00321   //assert(read_only == false && "writing to read-only object!");
00322   concreteStore[offset] = value;
00323   setKnownSymbolic(offset, 0);
00324 
00325   markByteConcrete(offset);
00326   markByteUnflushed(offset);
00327 }
00328 
00329 void ObjectState::write8(unsigned offset, ref<Expr> value) {
00330   // can happen when ExtractExpr special cases
00331   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(value)) {
00332     write8(offset, (uint8_t) CE->getConstantValue());
00333   } else {
00334     setKnownSymbolic(offset, value.get());
00335       
00336     markByteSymbolic(offset);
00337     markByteUnflushed(offset);
00338   }
00339 }
00340 
00341 void ObjectState::write8(ref<Expr> offset, ref<Expr> value) {
00342   assert(!isa<ConstantExpr>(offset) && "constant offset passed to symbolic write8");
00343   unsigned base, size;
00344   fastRangeCheckOffset(offset, &base, &size);
00345   flushRangeForWrite(base, size);
00346 
00347   if (size>4096) {
00348     std::string allocInfo;
00349     object->getAllocInfo(allocInfo);
00350     klee_warning_once(0, "flushing %d bytes on read, may be slow and/or crash: %s", 
00351                       size,
00352                       allocInfo.c_str());
00353   }
00354   
00355   updates.extend(offset, value);
00356 }
00357 
00358 /***/
00359 
00360 ref<Expr> ObjectState::read(ref<Expr> offset, Expr::Width width) const {
00361   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(offset)) {
00362     return read((unsigned) CE->getConstantValue(), width);
00363   } else { 
00364     switch (width) {
00365     default: assert(0 && "invalid type");
00366     case  Expr::Bool: return  read1(offset);
00367     case  Expr::Int8: return  read8(offset);
00368     case Expr::Int16: return read16(offset);
00369     case Expr::Int32: return read32(offset);
00370     case Expr::Int64: return read64(offset);
00371     }
00372   }
00373 }
00374 
00375 ref<Expr> ObjectState::read(unsigned offset, Expr::Width width) const {
00376   switch (width) {
00377   default: assert(0 && "invalid type");
00378   case  Expr::Bool: return  read1(offset);
00379   case  Expr::Int8: return  read8(offset);
00380   case Expr::Int16: return read16(offset);
00381   case Expr::Int32: return read32(offset);
00382   case Expr::Int64: return read64(offset);
00383   }
00384 }
00385 
00386 ref<Expr> ObjectState::read1(unsigned offset) const {
00387   return ExtractExpr::createByteOff(read8(offset), 0, Expr::Bool);
00388 }
00389 
00390 ref<Expr> ObjectState::read1(ref<Expr> offset) const {
00391   return ExtractExpr::createByteOff(read8(offset), 0, Expr::Bool);
00392 }
00393 
00394 ref<Expr> ObjectState::read16(unsigned offset) const {
00395   if (kMachineByteOrder == machine::MSB) {
00396     return ConcatExpr::create(read8(offset+0),
00397                               read8(offset+1));
00398   } else {
00399     return ConcatExpr::create(read8(offset+1),
00400                               read8(offset+0));
00401   }
00402 }
00403 
00404 ref<Expr> ObjectState::read16(ref<Expr> offset) const {
00405   if (kMachineByteOrder == machine::MSB) {
00406     return ConcatExpr::create
00407       (read8(AddExpr::create(offset,
00408                              ConstantExpr::create(0,
00409                                                   kMachinePointerType))),
00410        read8(AddExpr::create(offset,
00411                              ConstantExpr::create(1,
00412                                                   kMachinePointerType))));
00413   } else {
00414     return ConcatExpr::create
00415       (read8(AddExpr::create(offset,
00416                              ConstantExpr::create(1,
00417                                                   kMachinePointerType))),
00418        read8(AddExpr::create(offset,
00419                              ConstantExpr::create(0,
00420                                                   kMachinePointerType))));
00421   }
00422 }
00423 
00424 ref<Expr> ObjectState::read32(unsigned offset) const {
00425   if (kMachineByteOrder == machine::MSB) {
00426     return ConcatExpr::create4(read8(offset+0),
00427                                read8(offset+1),
00428                                read8(offset+2),
00429                                read8(offset+3));
00430   } else {
00431     return ConcatExpr::create4(read8(offset+3),
00432                                read8(offset+2),
00433                                read8(offset+1),
00434                                read8(offset+0));
00435   }
00436 }
00437 
00438 ref<Expr> ObjectState::read32(ref<Expr> offset) const {
00439   if (kMachineByteOrder == machine::MSB) {
00440     return ConcatExpr::create4
00441       (read8(AddExpr::create(offset,
00442                              ConstantExpr::create(0,
00443                                                   kMachinePointerType))),
00444        read8(AddExpr::create(offset,
00445                              ConstantExpr::create(1,
00446                                                   kMachinePointerType))),
00447        read8(AddExpr::create(offset,
00448                              ConstantExpr::create(2,
00449                                                   kMachinePointerType))),
00450        read8(AddExpr::create(offset,
00451                              ConstantExpr::create(3,
00452                                                   kMachinePointerType))));
00453   } else {
00454     return ConcatExpr::create4
00455       (read8(AddExpr::create(offset,
00456                              ConstantExpr::create(3,
00457                                                   kMachinePointerType))),
00458        read8(AddExpr::create(offset,
00459                              ConstantExpr::create(2,
00460                                                   kMachinePointerType))),
00461        read8(AddExpr::create(offset,
00462                              ConstantExpr::create(1,
00463                                                   kMachinePointerType))),
00464        read8(AddExpr::create(offset,
00465                              ConstantExpr::create(0,
00466                                                   kMachinePointerType))));
00467   }
00468 }
00469 
00470 ref<Expr> ObjectState::read64(unsigned offset) const {
00471   if (kMachineByteOrder == machine::MSB) {
00472     return ConcatExpr::create8(read8(offset+0),
00473                                read8(offset+1),
00474                                read8(offset+2),
00475                                read8(offset+3),
00476                                read8(offset+4),
00477                                read8(offset+5),
00478                                read8(offset+6),
00479                                read8(offset+7));
00480   } else {
00481     return ConcatExpr::create8(read8(offset+7),
00482                                read8(offset+6),
00483                                read8(offset+5),
00484                                read8(offset+4),
00485                                read8(offset+3),
00486                                read8(offset+2),
00487                                read8(offset+1),
00488                                read8(offset+0));
00489   }
00490 }
00491 
00492 ref<Expr> ObjectState::read64(ref<Expr> offset) const {
00493   if (kMachineByteOrder == machine::MSB) {
00494     return ConcatExpr::create8
00495       (read8(AddExpr::create(offset,
00496                              ConstantExpr::create(0,
00497                                                   kMachinePointerType))),
00498        read8(AddExpr::create(offset,
00499                              ConstantExpr::create(1,
00500                                                   kMachinePointerType))),
00501        read8(AddExpr::create(offset,
00502                              ConstantExpr::create(2,
00503                                                   kMachinePointerType))),
00504        read8(AddExpr::create(offset,
00505                              ConstantExpr::create(3,
00506                                                   kMachinePointerType))),
00507        read8(AddExpr::create(offset,
00508                              ConstantExpr::create(4,
00509                                                   kMachinePointerType))),
00510        read8(AddExpr::create(offset,
00511                              ConstantExpr::create(5,
00512                                                   kMachinePointerType))),
00513        read8(AddExpr::create(offset,
00514                              ConstantExpr::create(6,
00515                                                   kMachinePointerType))),
00516        read8(AddExpr::create(offset,
00517                              ConstantExpr::create(7,
00518                                                   kMachinePointerType))));
00519   } else {
00520     return ConcatExpr::create8
00521       (read8(AddExpr::create(offset,
00522                              ConstantExpr::create(7,
00523                                                   kMachinePointerType))),
00524        read8(AddExpr::create(offset,
00525                              ConstantExpr::create(6,
00526                                                   kMachinePointerType))),
00527        read8(AddExpr::create(offset,
00528                              ConstantExpr::create(5,
00529                                                   kMachinePointerType))),
00530        read8(AddExpr::create(offset,
00531                              ConstantExpr::create(4,
00532                                                   kMachinePointerType))),
00533        read8(AddExpr::create(offset,
00534                              ConstantExpr::create(3,
00535                                                   kMachinePointerType))),
00536        read8(AddExpr::create(offset,
00537                              ConstantExpr::create(2,
00538                                                   kMachinePointerType))),
00539        read8(AddExpr::create(offset,
00540                              ConstantExpr::create(1,
00541                                                   kMachinePointerType))),
00542        read8(AddExpr::create(offset,
00543                              ConstantExpr::create(0,
00544                                                   kMachinePointerType))));
00545   }
00546 }
00547 
00548 void ObjectState::write(ref<Expr> offset, ref<Expr> value) {
00549   Expr::Width w = value->getWidth();
00550   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(offset)) {
00551     write(CE->getConstantValue(), value);
00552   } else {
00553     switch(w) {
00554     case  Expr::Bool:  write1(offset, value); break;
00555     case  Expr::Int8:  write8(offset, value); break;
00556     case Expr::Int16: write16(offset, value); break;
00557     case Expr::Int32: write32(offset, value); break;
00558     case Expr::Int64: write64(offset, value); break;
00559     default: assert(0 && "invalid number of bytes in write");
00560     }
00561   }
00562 }
00563 
00564 void ObjectState::write(unsigned offset, ref<Expr> value) {
00565   Expr::Width w = value->getWidth();
00566   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(value)) {
00567     uint64_t val = CE->getConstantValue();
00568     switch(w) {
00569     case  Expr::Bool:
00570     case  Expr::Int8:  write8(offset, val); break;
00571     case Expr::Int16: write16(offset, val); break;
00572     case Expr::Int32: write32(offset, val); break;
00573     case Expr::Int64: write64(offset, val); break;
00574     default: assert(0 && "invalid number of bytes in write");
00575     }
00576   } else {
00577     switch(w) {
00578     case  Expr::Bool:  write1(offset, value); break;
00579     case  Expr::Int8:  write8(offset, value); break;
00580     case Expr::Int16: write16(offset, value); break;
00581     case Expr::Int32: write32(offset, value); break;
00582     case Expr::Int64: write64(offset, value); break;
00583     default: assert(0 && "invalid number of bytes in write");
00584     }
00585   }
00586 }
00587 
00588 void ObjectState::write1(unsigned offset, ref<Expr> value) {
00589   write8(offset, ZExtExpr::create(value, Expr::Int8));
00590 }
00591 
00592 void ObjectState::write1(ref<Expr> offset, ref<Expr> value) {
00593   write8(offset, ZExtExpr::create(value, Expr::Int8));
00594 }
00595 
00596 void ObjectState::write16(unsigned offset, uint16_t value) {
00597   if (kMachineByteOrder == machine::MSB) {
00598     write8(offset+0, (uint8_t) (value >>  8));
00599     write8(offset+1, (uint8_t) (value >>  0));
00600   } else {
00601     write8(offset+1, (uint8_t) (value >>  8));
00602     write8(offset+0, (uint8_t) (value >>  0));
00603   }
00604 }
00605 
00606 void ObjectState::write16(unsigned offset, ref<Expr> value) {
00607   if (kMachineByteOrder == machine::MSB) {
00608     write8(offset+0, ExtractExpr::createByteOff(value, 1));
00609     write8(offset+1, ExtractExpr::createByteOff(value, 0));
00610   } else {
00611     write8(offset+1, ExtractExpr::createByteOff(value, 1));
00612     write8(offset+0, ExtractExpr::createByteOff(value, 0));
00613   }
00614 }
00615 
00616 
00617 void ObjectState::write16(ref<Expr> offset, ref<Expr> value) {
00618   if (kMachineByteOrder == machine::MSB) {
00619     write8(AddExpr::create(offset,
00620                            ConstantExpr::create(0, kMachinePointerType)), 
00621            ExtractExpr::createByteOff(value,1));
00622     write8(AddExpr::create(offset,
00623                            ConstantExpr::create(0, kMachinePointerType)), 
00624            ExtractExpr::createByteOff(value,0));
00625   } else {
00626     write8(AddExpr::create(offset,
00627                            ConstantExpr::create(1, kMachinePointerType)), 
00628            ExtractExpr::createByteOff(value,1));
00629     write8(AddExpr::create(offset,
00630                            ConstantExpr::create(0, kMachinePointerType)), 
00631            ExtractExpr::createByteOff(value,0));
00632   }
00633 }
00634 
00635 void ObjectState::write32(unsigned offset, uint32_t value) {
00636   if (kMachineByteOrder == machine::MSB) {
00637     write8(offset+0, (uint8_t) (value >>  24));
00638     write8(offset+1, (uint8_t) (value >>  16));
00639     write8(offset+2, (uint8_t) (value >>  8));
00640     write8(offset+3, (uint8_t) (value >>  0));
00641   } else {
00642     write8(offset+3, (uint8_t) (value >>  24));
00643     write8(offset+2, (uint8_t) (value >>  16));
00644     write8(offset+1, (uint8_t) (value >>  8));
00645     write8(offset+0, (uint8_t) (value >>  0));
00646   }
00647 }
00648 
00649 void ObjectState::write32(unsigned offset, ref<Expr> value) {
00650   if (kMachineByteOrder == machine::MSB) {
00651     write8(offset+0, ExtractExpr::createByteOff(value, 3));
00652     write8(offset+1, ExtractExpr::createByteOff(value, 2));
00653     write8(offset+2, ExtractExpr::createByteOff(value, 1));
00654     write8(offset+3, ExtractExpr::createByteOff(value, 0));
00655   } else {
00656     write8(offset+3, ExtractExpr::createByteOff(value, 3));
00657     write8(offset+2, ExtractExpr::createByteOff(value, 2));
00658     write8(offset+1, ExtractExpr::createByteOff(value, 1));
00659     write8(offset+0, ExtractExpr::createByteOff(value, 0));
00660   }
00661 }
00662 
00663 void ObjectState::write32(ref<Expr> offset, ref<Expr> value) {
00664   if (kMachineByteOrder == machine::MSB) {
00665     write8(AddExpr::create(offset,
00666                            ConstantExpr::create(0, kMachinePointerType)), 
00667            ExtractExpr::createByteOff(value,3));
00668     write8(AddExpr::create(offset,
00669                            ConstantExpr::create(1, kMachinePointerType)), 
00670            ExtractExpr::createByteOff(value,2));
00671     write8(AddExpr::create(offset,
00672                            ConstantExpr::create(2, kMachinePointerType)), 
00673            ExtractExpr::createByteOff(value,1));
00674     write8(AddExpr::create(offset,
00675                            ConstantExpr::create(3, kMachinePointerType)), 
00676            ExtractExpr::createByteOff(value,0));
00677   } else {
00678     write8(AddExpr::create(offset,
00679                            ConstantExpr::create(3, kMachinePointerType)), 
00680            ExtractExpr::createByteOff(value,3));
00681     write8(AddExpr::create(offset,
00682                            ConstantExpr::create(2, kMachinePointerType)), 
00683            ExtractExpr::createByteOff(value,2));
00684     write8(AddExpr::create(offset,
00685                            ConstantExpr::create(1, kMachinePointerType)), 
00686            ExtractExpr::createByteOff(value,1));
00687     write8(AddExpr::create(offset,
00688                            ConstantExpr::create(0, kMachinePointerType)), 
00689            ExtractExpr::createByteOff(value,0));
00690   }
00691 }
00692 
00693 void ObjectState::write64(unsigned offset, uint64_t value) {
00694   if (kMachineByteOrder == machine::MSB) {
00695     write8(offset+0, (uint8_t) (value >>  56));
00696     write8(offset+1, (uint8_t) (value >>  48));
00697     write8(offset+2, (uint8_t) (value >>  40));
00698     write8(offset+3, (uint8_t) (value >>  32));
00699     write8(offset+4, (uint8_t) (value >>  24));
00700     write8(offset+5, (uint8_t) (value >>  16));
00701     write8(offset+6, (uint8_t) (value >>  8));
00702     write8(offset+7, (uint8_t) (value >>  0));
00703   } else {
00704     write8(offset+7, (uint8_t) (value >>  56));
00705     write8(offset+6, (uint8_t) (value >>  48));
00706     write8(offset+5, (uint8_t) (value >>  40));
00707     write8(offset+4, (uint8_t) (value >>  32));
00708     write8(offset+3, (uint8_t) (value >>  24));
00709     write8(offset+2, (uint8_t) (value >>  16));
00710     write8(offset+1, (uint8_t) (value >>  8));
00711     write8(offset+0, (uint8_t) (value >>  0));
00712   }
00713 }
00714 
00715 void ObjectState::write64(unsigned offset, ref<Expr> value) {
00716   if (kMachineByteOrder == machine::MSB) {
00717     write8(offset+0, ExtractExpr::createByteOff(value, 7));
00718     write8(offset+1, ExtractExpr::createByteOff(value, 6));
00719     write8(offset+2, ExtractExpr::createByteOff(value, 5));
00720     write8(offset+3, ExtractExpr::createByteOff(value, 4));
00721     write8(offset+4, ExtractExpr::createByteOff(value, 3));
00722     write8(offset+5, ExtractExpr::createByteOff(value, 2));
00723     write8(offset+6, ExtractExpr::createByteOff(value, 1));
00724     write8(offset+7, ExtractExpr::createByteOff(value, 0));
00725   } else {
00726     write8(offset+7, ExtractExpr::createByteOff(value, 7));
00727     write8(offset+6, ExtractExpr::createByteOff(value, 6));
00728     write8(offset+5, ExtractExpr::createByteOff(value, 5));
00729     write8(offset+4, ExtractExpr::createByteOff(value, 4));
00730     write8(offset+3, ExtractExpr::createByteOff(value, 3));
00731     write8(offset+2, ExtractExpr::createByteOff(value, 2));
00732     write8(offset+1, ExtractExpr::createByteOff(value, 1));
00733     write8(offset+0, ExtractExpr::createByteOff(value, 0));
00734   }
00735 }
00736 
00737 void ObjectState::write64(ref<Expr> offset, ref<Expr> value) {
00738   if (kMachineByteOrder == machine::MSB) {
00739     write8(AddExpr::create(offset,
00740                            ConstantExpr::create(0, kMachinePointerType)), 
00741            ExtractExpr::createByteOff(value,7));
00742     write8(AddExpr::create(offset,
00743                            ConstantExpr::create(1, kMachinePointerType)), 
00744            ExtractExpr::createByteOff(value,6));
00745     write8(AddExpr::create(offset,
00746                            ConstantExpr::create(2, kMachinePointerType)), 
00747            ExtractExpr::createByteOff(value,5));
00748     write8(AddExpr::create(offset,
00749                            ConstantExpr::create(3, kMachinePointerType)), 
00750            ExtractExpr::createByteOff(value,4));
00751     write8(AddExpr::create(offset,
00752                            ConstantExpr::create(4, kMachinePointerType)), 
00753            ExtractExpr::createByteOff(value,3));
00754     write8(AddExpr::create(offset,
00755                            ConstantExpr::create(5, kMachinePointerType)), 
00756            ExtractExpr::createByteOff(value,2));
00757     write8(AddExpr::create(offset,
00758                            ConstantExpr::create(6, kMachinePointerType)), 
00759            ExtractExpr::createByteOff(value,1));
00760     write8(AddExpr::create(offset,
00761                            ConstantExpr::create(7, kMachinePointerType)), 
00762            ExtractExpr::createByteOff(value,0));
00763   } else {
00764     write8(AddExpr::create(offset,
00765                            ConstantExpr::create(7, kMachinePointerType)), 
00766            ExtractExpr::createByteOff(value,7));
00767     write8(AddExpr::create(offset,
00768                            ConstantExpr::create(6, kMachinePointerType)), 
00769            ExtractExpr::createByteOff(value,6));
00770     write8(AddExpr::create(offset,
00771                            ConstantExpr::create(5, kMachinePointerType)), 
00772            ExtractExpr::createByteOff(value,5));
00773     write8(AddExpr::create(offset,
00774                            ConstantExpr::create(4, kMachinePointerType)), 
00775            ExtractExpr::createByteOff(value,4));
00776     write8(AddExpr::create(offset,
00777                            ConstantExpr::create(3, kMachinePointerType)), 
00778            ExtractExpr::createByteOff(value,3));
00779     write8(AddExpr::create(offset,
00780                            ConstantExpr::create(2, kMachinePointerType)), 
00781            ExtractExpr::createByteOff(value,2));
00782     write8(AddExpr::create(offset,
00783                            ConstantExpr::create(1, kMachinePointerType)), 
00784            ExtractExpr::createByteOff(value,1));
00785     write8(AddExpr::create(offset,
00786                            ConstantExpr::create(0, kMachinePointerType)), 
00787            ExtractExpr::createByteOff(value,0));
00788   }
00789 }
00790 
00791 void ObjectState::print() {
00792   llvm::cerr << "-- ObjectState --\n";
00793   llvm::cerr << "\tMemoryObject ID: " << object->id << "\n";
00794   llvm::cerr << "\tRoot Object: " << updates.root << "\n";
00795   llvm::cerr << "\tIs Rooted? " << updates.isRooted << "\n";
00796   llvm::cerr << "\tSize: " << size << "\n";
00797 
00798   llvm::cerr << "\tBytes:\n";
00799   for (unsigned i=0; i<size; i++) {
00800     llvm::cerr << "\t\t["<<i<<"]"
00801                << " concrete? " << isByteConcrete(i)
00802                << " known-sym? " << isByteKnownSymbolic(i)
00803                << " flushed? " << isByteFlushed(i) << " = ";
00804     ref<Expr> e = read8(i);
00805     llvm::cerr << e << "\n";
00806   }
00807 
00808   llvm::cerr << "\tUpdates:\n";
00809   for (const UpdateNode *un=updates.head; un; un=un->next) {
00810     llvm::cerr << "\t\t[" << un->index << "] = " << un->value << "\n";
00811   }
00812 }

Generated on Fri Jun 5 03:31:31 2009 for klee by  doxygen 1.5.8