00001
00002
00003
00004
00005
00006
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
00063 MemoryObject(const MemoryObject &b);
00064 MemoryObject &operator=(const MemoryObject &b);
00065
00066 public:
00067
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;
00140
00141 friend class ObjectHolder;
00142 unsigned refCount;
00143
00144 const MemoryObject *object;
00145
00146 uint8_t *concreteStore;
00147
00148 BitArray *concreteMask;
00149
00150
00151 mutable BitArray *flushMask;
00152
00153 ref<Expr> *knownSymbolics;
00154
00155 public:
00156 unsigned size;
00157
00158
00159 mutable UpdateList updates;
00160
00161 bool readOnly;
00162
00163 public:
00164
00165
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
00175 void makeConcrete();
00176
00177 void makeSymbolic();
00178
00179
00180 void initializeToZero();
00181
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
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 }
00238
00239 #endif