Memory.h

Go to the documentation of this file.
00001 //===-- Memory.h ------------------------------------------------*- C++ -*-===//
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 #ifndef KLEE_MEMORY_H
00011 #define KLEE_MEMORY_H
00012 
00013 #include "klee/Expr.h"
00014 
00015 #include <vector>
00016 #include <string>
00017 
00018 namespace llvm {
00019   class Value;
00020 }
00021 
00022 namespace klee {
00023 
00024 class BitArray;
00025 class MemoryManager;
00026 class Solver;
00027 
00028 class MemoryObject {
00029   friend class STPBuilder;
00030 
00031 private:
00032   static int counter;
00033 
00034 public:
00035   unsigned id;
00036   uint64_t address;
00037   Array *array;
00038 
00040   unsigned size;
00041   std::string name;
00042 
00043   bool isLocal;
00044   bool isGlobal;
00045   bool isFixed;
00046 
00048   bool fake_object;
00049   bool isUserSpecified;
00050 
00054   const llvm::Value *allocSite;
00055   
00060   mutable std::vector< ref<Expr> > cexPreferences;
00061 
00062   // DO NOT IMPLEMENT
00063   MemoryObject(const MemoryObject &b);
00064   MemoryObject &operator=(const MemoryObject &b);
00065 
00066 public:
00067   // XXX this is just a temp hack, should be removed
00068   explicit
00069   MemoryObject(uint64_t _address) 
00070     : id(counter++),
00071       address(_address),
00072       array(new Array(this, 0, id)),
00073       size(0),
00074       isFixed(true),
00075       allocSite(0) {
00076   }
00077 
00078   MemoryObject(uint64_t _address, unsigned _size, 
00079                bool _isLocal, bool _isGlobal, bool _isFixed,
00080                const llvm::Value *_allocSite) 
00081     : id(counter++),
00082       address(_address),
00083       array(new Array(this, id, _size)),
00084       size(_size),
00085       name("unnamed"),
00086       isLocal(_isLocal),
00087       isGlobal(_isGlobal),
00088       isFixed(_isFixed),
00089       fake_object(false),
00090       isUserSpecified(false),
00091       allocSite(_allocSite) {
00092   }
00093 
00094   ~MemoryObject();
00095 
00097   void getAllocInfo(std::string &result) const;
00098 
00099   void setName(std::string name) {
00100     this->name = name;
00101   }
00102 
00103   ref<Expr> getBaseExpr() const { 
00104     return ConstantExpr::create(address, kMachinePointerType);
00105   }
00106   ref<Expr> getSizeExpr() const { 
00107     return ConstantExpr::create(size, kMachinePointerType);
00108   }
00109   ref<Expr> getOffsetExpr(ref<Expr> pointer) const {
00110     return SubExpr::create(pointer, getBaseExpr());
00111   }
00112   ref<Expr> getBoundsCheckPointer(ref<Expr> pointer) const {
00113     return getBoundsCheckOffset(getOffsetExpr(pointer));
00114   }
00115   ref<Expr> getBoundsCheckPointer(ref<Expr> pointer, unsigned bytes) const {
00116     return getBoundsCheckOffset(getOffsetExpr(pointer), bytes);
00117   }
00118 
00119   ref<Expr> getBoundsCheckOffset(ref<Expr> offset) const {
00120     if (size==0) {
00121       return EqExpr::create(offset, ConstantExpr::alloc(0, kMachinePointerType));
00122     } else {
00123       return UltExpr::create(offset, getSizeExpr());
00124     }
00125   }
00126   ref<Expr> getBoundsCheckOffset(ref<Expr> offset, unsigned bytes) const {
00127     if (bytes<=size) {
00128       return UltExpr::create(offset, 
00129                              ConstantExpr::alloc(size - bytes + 1, kMachinePointerType));
00130     } else {
00131       return ConstantExpr::alloc(0, Expr::Bool);
00132     }
00133   }
00134 };
00135 
00136 class ObjectState {
00137 private:
00138   friend class AddressSpace;
00139   unsigned copyOnWriteOwner; // exclusively for AddressSpace
00140 
00141   friend class ObjectHolder;
00142   unsigned refCount;
00143 
00144   const MemoryObject *object;
00145 
00146   uint8_t *concreteStore;
00147   // XXX cleanup name of flushMask (its backwards or something)
00148   BitArray *concreteMask;
00149 
00150   // mutable because may need flushed during read of const
00151   mutable BitArray *flushMask;
00152 
00153   ref<Expr> *knownSymbolics;
00154 
00155 public:
00156   unsigned size;
00157 
00158   // mutable because we may need flush during read of const
00159   mutable UpdateList updates;
00160 
00161   bool readOnly;
00162 
00163 public:
00164   // initial contents are undefined but concrete, it is the creators
00165   // responsibility to initialize the object contents appropriate
00166   ObjectState(const MemoryObject *mo, unsigned size);
00167   ObjectState(const ObjectState &os);
00168   ~ObjectState();
00169 
00170   const MemoryObject *getObject() const { return object; }
00171 
00172   void setReadOnly(bool ro) { readOnly = ro; }
00173 
00174   // make all bytes are concrete with undefined values
00175   void makeConcrete();
00176 
00177   void makeSymbolic();
00178 
00179   // make contents all concrete and zero
00180   void initializeToZero();
00181   // make contents all concrete and random
00182   void initializeToRandom();
00183 
00184   ref<Expr> read(ref<Expr> offset, Expr::Width width) const;
00185   ref<Expr> read(unsigned offset, Expr::Width width) const;
00186   ref<Expr> read1(unsigned offset) const;
00187   ref<Expr> read8(unsigned offset) const;
00188   ref<Expr> read16(unsigned offset) const;
00189   ref<Expr> read32(unsigned offset) const;
00190   ref<Expr> read64(unsigned offset) const;
00191 
00192   // return bytes written.
00193   void write(unsigned offset, ref<Expr> value);
00194   void write(ref<Expr> offset, ref<Expr> value);
00195 
00196   void write8(unsigned offset, uint8_t value);
00197   void write16(unsigned offset, uint16_t value);
00198   void write32(unsigned offset, uint32_t value);
00199   void write64(unsigned offset, uint64_t value);
00200 
00201 private:
00202   ref<Expr> read1(ref<Expr> offset) const;
00203   ref<Expr> read8(ref<Expr> offset) const;
00204   ref<Expr> read16(ref<Expr> offset) const;
00205   ref<Expr> read32(ref<Expr> offset) const;
00206   ref<Expr> read64(ref<Expr> offset) const;
00207 
00208   void write1(unsigned offset, ref<Expr> value);
00209   void write1(ref<Expr> offset, ref<Expr> value);
00210   void write8(unsigned offset, ref<Expr> value);
00211   void write8(ref<Expr> offset, ref<Expr> value);
00212   void write16(unsigned offset, ref<Expr> value);
00213   void write16(ref<Expr> offset, ref<Expr> value);
00214   void write32(unsigned offset, ref<Expr> value);
00215   void write32(ref<Expr> offset, ref<Expr> value);
00216   void write64(unsigned offset, ref<Expr> value);
00217   void write64(ref<Expr> offset, ref<Expr> value);
00218 
00219   
00220   void fastRangeCheckOffset(ref<Expr> offset, unsigned *base_r, unsigned *size_r) const;
00221   void flushRangeForRead(unsigned rangeBase, unsigned rangeSize) const;
00222   void flushRangeForWrite(unsigned rangeBase, unsigned rangeSize);
00223 
00224   bool isByteConcrete(unsigned offset) const;
00225   bool isByteFlushed(unsigned offset) const;
00226   bool isByteKnownSymbolic(unsigned offset) const;
00227 
00228   void markByteConcrete(unsigned offset);
00229   void markByteSymbolic(unsigned offset);
00230   void markByteFlushed(unsigned offset);
00231   void markByteUnflushed(unsigned offset);
00232   void setKnownSymbolic(unsigned offset, Expr *value);
00233 
00234   void print();
00235 };
00236   
00237 } // End klee namespace
00238 
00239 #endif

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