00001
00002
00003
00004
00005
00006
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
00061
00062
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
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
00171 concreteStore[i] = 0xAB;
00172 }
00173 }
00174
00175
00176
00177
00178
00179
00180
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
00230
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 ) {
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
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
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 }