00001 #ifndef Rose_VirtualMachineSemantics_H
00002 #define Rose_VirtualMachineSemantics_H
00003
00004
00005 #ifndef __STDC_FORMAT_MACROS
00006 #define __STDC_FORMAT_MACROS
00007 #endif
00008 #include <inttypes.h>
00009
00010 #include <map>
00011 #include <stdint.h>
00012 #include <vector>
00013
00014 #include "rosePublicConfig.h"
00015 #ifdef ROSE_HAVE_GCRYPT_H
00016 #include <gcrypt.h>
00017 #endif
00018
00019 #include "x86InstructionSemantics.h"
00020 #include "BaseSemantics.h"
00021 #include "MemoryMap.h"
00022
00023 namespace BinaryAnalysis {
00024 namespace InstructionSemantics {
00025
00026
00040 namespace VirtualMachineSemantics {
00041
00042 extern uint64_t name_counter;
00043
00044 typedef std::map<uint64_t, uint64_t> RenameMap;
00045
00047 template<size_t nBits>
00048 struct ValueType {
00049 uint64_t name;
00050 uint64_t offset;
00052 bool negate;
00056 ValueType(): name(++name_counter), offset(0), negate(false) {}
00057
00059 template <size_t Len>
00060 ValueType(const ValueType<Len> &other) {
00061 name = other.name;
00062
00063 offset = other.offset & IntegerOps::GenMask<uint64_t, nBits>::value;
00064 negate = other.negate;
00065 }
00066
00068 ValueType(uint64_t n)
00069 : name(0), offset(n), negate(false) {
00070 this->offset &= IntegerOps::GenMask<uint64_t, nBits>::value;
00071 }
00072
00074 ValueType(uint64_t name, uint64_t offset, bool negate=false)
00075 : name(name), offset(offset), negate(negate) {
00076 this->offset &= IntegerOps::GenMask<uint64_t, nBits>::value;
00077 }
00078
00080 bool is_known() const {
00081 return 0==name;
00082 }
00083
00085 uint64_t known_value() const {
00086 ROSE_ASSERT(is_known());
00087 return offset;
00088 }
00089
00094 ValueType<nBits> rename(RenameMap *rmap=NULL) const;
00095
00098 void print(std::ostream &o, RenameMap *rmap=NULL) const {
00099 uint64_t sign_bit = (uint64_t)1 << (nBits-1);
00100 uint64_t val_mask = sign_bit - 1;
00101
00102 uint64_t negative = nBits>1 && (offset & sign_bit) ? (~offset & val_mask) + 1 : 0;
00103
00104 if (name!=0) {
00105
00106 uint64_t renamed = name;
00107 if (rmap) {
00108 RenameMap::iterator found = rmap->find(name);
00109 if (found==rmap->end()) {
00110 renamed = rmap->size()+1;
00111 rmap->insert(std::make_pair(name, renamed));
00112 } else {
00113 renamed = found->second;
00114 }
00115 }
00116 const char *sign = negate ? "-" : "";
00117 o <<sign <<"v" <<std::dec <<renamed;
00118 if (negative) {
00119 o <<"-0x" <<std::hex <<negative;
00120 } else if (offset) {
00121 o <<"+0x" <<std::hex <<offset;
00122 }
00123 } else {
00124
00125 ROSE_ASSERT(!negate);
00126 o <<"0x" <<std::hex <<offset;
00127 if (negative)
00128 o <<" (-0x" <<std::hex <<negative <<")";
00129 }
00130 }
00131 void print(std::ostream &o, BaseSemantics::SEMANTIC_NO_PRINT_HELPER *unused=NULL) const {
00132 print(o, (RenameMap*)0);
00133 }
00134
00135 friend bool operator==(const ValueType &a, const ValueType &b) {
00136 return a.name==b.name && (!a.name || a.negate==b.negate) && a.offset==b.offset;
00137 }
00138
00139 friend bool operator!=(const ValueType &a, const ValueType &b) {
00140 return !(a==b);
00141 }
00142
00143 friend bool operator<(const ValueType &a, const ValueType &b) {
00144 if (a.name<b.name) return true;
00145 if (b.name<a.name) return false;
00146 if (a.name && a.negate<b.negate) return true;
00147 if (a.name && b.negate<a.negate) return false;
00148 return a.offset < b.offset;
00149 }
00150 };
00151
00152 template<size_t Len>
00153 std::ostream& operator<<(std::ostream &o, const ValueType<Len> &e) {
00154 e.print(o, (RenameMap*)0);
00155 return o;
00156 }
00157
00160 template <template <size_t> class ValueType=VirtualMachineSemantics::ValueType>
00161 class MemoryCell: public BaseSemantics::MemoryCell<ValueType> {
00162 public:
00163
00165 template <size_t Len>
00166 MemoryCell(const ValueType<32> &address, const ValueType<Len> data, size_t nbytes)
00167 : BaseSemantics::MemoryCell<ValueType>(address, data, nbytes) {}
00168
00172 bool may_alias(const MemoryCell &other) const;
00173
00176 bool must_alias(const MemoryCell &other) const;
00177
00178 friend bool operator==(const MemoryCell &a, const MemoryCell &b) {
00179 return (a.get_address()==b.get_address() &&
00180 a.get_data()==b.get_data() &&
00181 a.get_nbytes()==b.get_nbytes() &&
00182 a.get_clobbered()==b.get_clobbered() &&
00183 a.get_written()==b.get_written());
00184 }
00185 friend bool operator!=(const MemoryCell &a, const MemoryCell &b) {
00186 return !(a==b);
00187 }
00188 friend bool operator<(const MemoryCell &a, const MemoryCell &b) {
00189 return a.get_address() < b.get_address();
00190 }
00191 };
00192
00194 template <template <size_t> class ValueType=VirtualMachineSemantics::ValueType>
00195 struct State: public BaseSemantics::StateX86<MemoryCell, ValueType> {
00196 typedef typename BaseSemantics::StateX86<MemoryCell, ValueType>::Memory Memory;
00197
00200 void print_diff_registers(std::ostream &o, const State&, RenameMap *rmap=NULL) const;
00201
00203 bool equal_registers(const State&) const;
00204
00207 void discard_popped_memory();
00208 };
00209
00211 template<
00212 template <template <size_t> class ValueType> class State = VirtualMachineSemantics::State,
00213 template <size_t nBits> class ValueType = VirtualMachineSemantics::ValueType
00214 >
00215 class Policy: public BaseSemantics::Policy {
00216 protected:
00217 SgAsmInstruction *cur_insn;
00218 mutable State<ValueType> orig_state;
00229 mutable State<ValueType> cur_state;
00235 bool p_discard_popped_memory;
00240 size_t ninsns;
00243 MemoryMap *map;
00245 public:
00246 Policy(): cur_insn(NULL), p_discard_popped_memory(false), ninsns(0), map(NULL) {
00247
00248 set_register_dictionary(RegisterDictionary::dictionary_pentium4());
00249 orig_state = cur_state;
00250 }
00251
00254 void set_map(MemoryMap *map) {
00255 this->map = map;
00256 }
00257
00260 size_t get_ninsns() const {
00261 return ninsns;
00262 }
00263
00266 void set_ninsns(size_t n) {
00267 ninsns = n;
00268 }
00269
00271 SgAsmInstruction *get_insn() const {
00272 return cur_insn;
00273 }
00274
00277 const State<ValueType>& get_state() const { return cur_state; }
00278 State<ValueType>& get_state() { return cur_state; }
00283 const State<ValueType>& get_orig_state() const { return orig_state; }
00284 State<ValueType>& get_orig_state() { return orig_state; }
00285
00287 const ValueType<32>& get_ip() const { return cur_state.ip; }
00288
00290 const ValueType<32>& get_orig_ip() const { return orig_state.ip; }
00291
00293 typename State<ValueType>::Memory memory_for_equality(const State<ValueType>&) const;
00294
00297 typename State<ValueType>::Memory memory_for_equality() const { return memory_for_equality(cur_state); }
00298
00302 bool equal_states(const State<ValueType>&, const State<ValueType>&) const;
00303
00306 void print(std::ostream&, RenameMap *rmap=NULL) const;
00307 friend std::ostream& operator<<(std::ostream &o, const Policy &p) {
00308 p.print(o, NULL);
00309 return o;
00310 }
00311
00314 bool on_stack(const ValueType<32> &value) const;
00315
00318 void set_discard_popped_memory(bool b) {
00319 p_discard_popped_memory = b;
00320 }
00321
00324 bool get_discard_popped_memory() const {
00325 return p_discard_popped_memory;
00326 }
00327
00330 void print_diff(std::ostream&, const State<ValueType>&, const State<ValueType>&, RenameMap *rmap=NULL) const ;
00331
00334 void print_diff(std::ostream &o, const State<ValueType> &state, RenameMap *rmap=NULL) const {
00335 print_diff(o, orig_state, state, rmap);
00336 }
00337
00340 void print_diff(std::ostream &o, RenameMap *rmap=NULL) const {
00341 print_diff(o, orig_state, cur_state, rmap);
00342 }
00343
00346 std::string SHA1() const;
00347
00352 bool SHA1(unsigned char *digest) const;
00353
00355 template <size_t FromLen, size_t ToLen>
00356 ValueType<ToLen> signExtend(const ValueType<FromLen> &a) const {
00357 if (ToLen==FromLen) return a;
00358 if (a.name) return ValueType<ToLen>();
00359 return IntegerOps::signExtend<FromLen, ToLen>(a.offset);
00360 }
00361
00363 template <size_t BeginAt, size_t EndAt, size_t Len>
00364 ValueType<EndAt-BeginAt> extract(const ValueType<Len> &a) const {
00365 if (0==BeginAt) return ValueType<EndAt-BeginAt>(a);
00366 if (a.name) return ValueType<EndAt-BeginAt>();
00367 return (a.offset >> BeginAt) & (IntegerOps::SHL1<uint64_t, EndAt-BeginAt>::value - 1);
00368 }
00369
00372 template <size_t FromLen, size_t ToLen>
00373 ValueType<ToLen> unsignedExtend(const ValueType<FromLen> &a) const {
00374 return ValueType<ToLen>(a);
00375 }
00376
00386 template <size_t Len> ValueType<Len> mem_read(State<ValueType> &state, const ValueType<32> &addr) const {
00387 MemoryCell<ValueType> new_cell(addr, ValueType<32>(), Len/8);
00388 bool aliased = false;
00389
00390 for (typename State<ValueType>::Memory::iterator mi=state.mem.begin(); mi!=state.mem.end(); ++mi) {
00391 if (new_cell.must_alias(*mi)) {
00392 if ((*mi).is_clobbered()) {
00393 (*mi).set_clobbered(false);
00394 (*mi).set_data(new_cell.get_data());
00395 return new_cell.get_data();
00396 } else {
00397 return (*mi).get_data();
00398 }
00399 } else if (new_cell.may_alias(*mi) && (*mi).is_written()) {
00400 aliased = true;
00401 }
00402 }
00403
00404 if (!aliased && &state!=&orig_state) {
00405
00406
00407 for (typename State<ValueType>::Memory::iterator mi=orig_state.mem.begin();
00408 mi!=orig_state.mem.end();
00409 ++mi) {
00410 if (new_cell.must_alias(*mi)) {
00411 ROSE_ASSERT(!(*mi).is_clobbered());
00412 ROSE_ASSERT(!(*mi).is_written());
00413 state.mem.push_back(*mi);
00414 std::sort(state.mem.begin(), state.mem.end());
00415 return (*mi).get_data();
00416 }
00417 }
00418
00419
00420
00421 if (map && addr.is_known()) {
00422 uint8_t buf[sizeof(uint64_t)];
00423 ROSE_ASSERT(Len/8 < sizeof buf);
00424 size_t nread = map->read(buf, addr.known_value(), Len/8);
00425 if (nread==Len/8) {
00426 uint64_t n = 0;
00427 for (size_t i=0; i<Len/8; i++)
00428 n |= buf[i] << (8*i);
00429 new_cell.set_data(number<32>(n));
00430 }
00431 }
00432
00433 orig_state.mem.push_back(new_cell);
00434 std::sort(orig_state.mem.begin(), orig_state.mem.end());
00435 }
00436
00437
00438 state.mem.push_back(new_cell);
00439 std::sort(state.mem.begin(), state.mem.end());
00440 return new_cell.get_data();
00441 }
00442
00444 enum MemRefType { MRT_STACK_PTR, MRT_FRAME_PTR, MRT_OTHER_PTR };
00445
00450 MemRefType memory_reference_type(const State<ValueType> &state, const ValueType<32> &addr) const {
00451 if (addr.name) {
00452 if (addr.name==state.gpr[x86_gpr_sp].name) return MRT_STACK_PTR;
00453 if (addr.name==state.gpr[x86_gpr_bp].name) return MRT_FRAME_PTR;
00454 return MRT_OTHER_PTR;
00455 }
00456 if (addr==state.gpr[x86_gpr_sp]) return MRT_STACK_PTR;
00457 if (addr==state.gpr[x86_gpr_bp]) return MRT_FRAME_PTR;
00458 return MRT_OTHER_PTR;
00459 }
00460
00464 template <size_t Len> void mem_write(State<ValueType> &state, const ValueType<32> &addr,
00465 const ValueType<Len> &data) {
00466 ROSE_ASSERT(&state!=&orig_state);
00467 MemoryCell<ValueType> new_cell(addr, data, Len/8);
00468 new_cell.set_written();
00469 bool saved = false;
00470
00471
00472 MemRefType new_mrt = memory_reference_type(state, addr);
00473
00474
00475 for (typename State<ValueType>::Memory::iterator mi=state.mem.begin(); mi!=state.mem.end(); ++mi) {
00476 if (new_cell.must_alias(*mi)) {
00477 *mi = new_cell;
00478 saved = true;
00479 } else if (p_discard_popped_memory && new_mrt!=memory_reference_type(state, (*mi).get_address())) {
00480
00481
00482 } else if (new_cell.may_alias(*mi)) {
00483 (*mi).set_clobbered();
00484 } else {
00485
00486 }
00487 }
00488 if (!saved) {
00489 state.mem.push_back(new_cell);
00490 std::sort(state.mem.begin(), state.mem.end());
00491 }
00492 }
00493
00494
00495
00496
00497
00499 void startInstruction(SgAsmInstruction *insn) {
00500 cur_state.ip = ValueType<32>(insn->get_address());
00501 if (0==ninsns++)
00502 orig_state = cur_state;
00503 cur_insn = insn;
00504 }
00505
00507 void finishInstruction(SgAsmInstruction*) {
00508 if (p_discard_popped_memory)
00509 cur_state.discard_popped_memory();
00510 cur_insn = NULL;
00511 }
00512
00513
00514 void startBlock(rose_addr_t addr) {}
00515
00516
00517 void finishBlock(rose_addr_t addr) {}
00518
00519
00520
00521
00522
00524 ValueType<1> true_() const {
00525 return 1;
00526 }
00527
00529 ValueType<1> false_() const {
00530 return 0;
00531 }
00532
00534 ValueType<1> undefined_() const {
00535 return ValueType<1>();
00536 }
00537
00539 template <size_t Len>
00540 ValueType<Len> number(uint64_t n) const {
00541 return n;
00542 }
00543
00544
00545
00546
00547
00548
00549
00551 ValueType<32> filterCallTarget(const ValueType<32> &a) const {
00552 return a;
00553 }
00554
00556 ValueType<32> filterReturnTarget(const ValueType<32> &a) const {
00557 return a;
00558 }
00559
00561 ValueType<32> filterIndirectJumpTarget(const ValueType<32> &a) const {
00562 return a;
00563 }
00564
00566 void hlt() {}
00567
00569 void cpuid() {}
00570
00572 ValueType<64> rdtsc() {
00573 return 0;
00574 }
00575
00577 void interrupt(uint8_t num) {
00578 cur_state = State<ValueType>();
00579 }
00580
00582 void sysenter() {
00583 cur_state = State<ValueType>();
00584 }
00585
00586
00587
00588
00589
00590
00591
00592 #include "ReadWriteRegisterFragment.h"
00593
00595 template <size_t Len> ValueType<Len>
00596 readMemory(X86SegmentRegister segreg, const ValueType<32> &addr, const ValueType<1> &cond) const {
00597 return mem_read<Len>(cur_state, addr);
00598 }
00599
00601 template <size_t Len> void
00602 writeMemory(X86SegmentRegister segreg, const ValueType<32> &addr, const ValueType<Len> &data,
00603 const ValueType<1> &cond) {
00604 mem_write<Len>(cur_state, addr, data);
00605 }
00606
00607
00608
00609
00610
00611
00612
00614 template <size_t Len>
00615 ValueType<Len> add(const ValueType<Len> &a, const ValueType<Len> &b) const {
00616 if (a.name==b.name && (!a.name || a.negate!=b.negate)) {
00617
00618
00619 return a.offset + b.offset;
00620 } else if (!a.name || !b.name) {
00621
00622
00623
00624
00625 return ValueType<Len>(a.name+b.name, a.offset+b.offset, a.negate || b.negate);
00626 } else {
00627 return ValueType<Len>();
00628 }
00629 }
00630
00632 template <size_t Len>
00633 ValueType<Len> addWithCarries(const ValueType<Len> &a, const ValueType<Len> &b, const ValueType<1> &c,
00634 ValueType<Len> &carry_out) const {
00635 int n_unknown = (a.name?1:0) + (b.name?1:0) + (c.name?1:0);
00636 if (n_unknown <= 1) {
00637
00638 uint64_t sum = a.offset + b.offset + c.offset;
00639 carry_out = 0==n_unknown ? ValueType<Len>((a.offset ^ b.offset ^ sum)>>1) : ValueType<Len>();
00640 return ValueType<Len>(a.name+b.name+c.name, sum, a.negate||b.negate||c.negate);
00641 } else if (a.name==b.name && !c.name && a.negate!=b.negate) {
00642
00643 uint64_t sum = a.offset + b.offset + c.offset;
00644 carry_out = ValueType<Len>((a.offset ^ b.offset ^ sum)>>1);
00645 return ValueType<Len>(sum);
00646 } else {
00647 carry_out = ValueType<Len>();
00648 return ValueType<Len>();
00649 }
00650 }
00651
00653 template <size_t Len>
00654 ValueType<Len> and_(const ValueType<Len> &a, const ValueType<Len> &b) const {
00655 if ((!a.name && 0==a.offset) || (!b.name && 0==b.offset)) return 0;
00656 if (a.name || b.name) return ValueType<Len>();
00657 return a.offset & b.offset;
00658 }
00659
00661 template <size_t Len>
00662 ValueType<1> equalToZero(const ValueType<Len> &a) const {
00663 if (a.name) return undefined_();
00664 return a.offset ? false_() : true_();
00665 }
00666
00668 template <size_t Len>
00669 ValueType<Len> invert(const ValueType<Len> &a) const {
00670 if (a.name) return ValueType<Len>(a.name, ~a.offset, !a.negate);
00671 return ~a.offset;
00672 }
00673
00675 template<size_t Len1, size_t Len2>
00676 ValueType<Len1+Len2> concat(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00677 if (a.name || b.name) return ValueType<Len1+Len2>();
00678 return a.offset | (b.offset << Len1);
00679 }
00680
00682 template <size_t Len>
00683 ValueType<Len> ite(const ValueType<1> &sel, const ValueType<Len> &ifTrue, const ValueType<Len> &ifFalse) const {
00684 if (ifTrue==ifFalse) return ifTrue;
00685 if (sel.name) return ValueType<Len>();
00686 return sel.offset ? ifTrue : ifFalse;
00687 }
00688
00690 template <size_t Len>
00691 ValueType<Len> leastSignificantSetBit(const ValueType<Len> &a) const {
00692 if (a.name) return ValueType<Len>();
00693 for (size_t i=0; i<Len; ++i) {
00694 if (a.offset & ((uint64_t)1 << i))
00695 return i;
00696 }
00697 return 0;
00698 }
00699
00701 template <size_t Len>
00702 ValueType<Len> mostSignificantSetBit(const ValueType<Len> &a) const {
00703 if (a.name) return ValueType<Len>();
00704 for (size_t i=Len; i>0; --i) {
00705 if (a.offset & ((uint64_t)1 << (i-1)))
00706 return i-1;
00707 }
00708 return 0;
00709 }
00710
00712 template <size_t Len>
00713 ValueType<Len> negate(const ValueType<Len> &a) const {
00714 if (a.name) return ValueType<Len>(a.name, -a.offset, !a.negate);
00715 return -a.offset;
00716 }
00717
00719 template <size_t Len>
00720 ValueType<Len> or_(const ValueType<Len> &a, const ValueType<Len> &b) const {
00721 if (a==b) return a;
00722 if (!a.name && !b.name) return a.offset | b.offset;
00723 if (!a.name && a.offset==IntegerOps::GenMask<uint64_t, Len>::value) return a;
00724 if (!b.name && b.offset==IntegerOps::GenMask<uint64_t, Len>::value) return b;
00725 return ValueType<Len>();
00726 }
00727
00729 template <size_t Len, size_t SALen>
00730 ValueType<Len> rotateLeft(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00731 if (!a.name && !sa.name) return IntegerOps::rotateLeft<Len>(a.offset, sa.offset);
00732 if (!sa.name && 0==sa.offset % Len) return a;
00733 return ValueType<Len>();
00734 }
00735
00737 template <size_t Len, size_t SALen>
00738 ValueType<Len> rotateRight(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00739 if (!a.name && !sa.name) return IntegerOps::rotateRight<Len>(a.offset, sa.offset);
00740 if (!sa.name && 0==sa.offset % Len) return a;
00741 return ValueType<Len>();
00742 }
00743
00745 template <size_t Len, size_t SALen>
00746 ValueType<Len> shiftLeft(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00747 if (!a.name && !sa.name) return IntegerOps::shiftLeft<Len>(a.offset, sa.offset);
00748 if (!sa.name) {
00749 if (0==sa.offset) return a;
00750 if (sa.offset>=Len) return 0;
00751 }
00752 return ValueType<Len>();
00753 }
00754
00756 template <size_t Len, size_t SALen>
00757 ValueType<Len> shiftRight(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00758 if (!a.name && !sa.name) return IntegerOps::shiftRightLogical<Len>(a.offset, sa.offset);
00759 if (!sa.name) {
00760 if (0==sa.offset) return a;
00761 if (sa.offset>=Len) return 0;
00762 }
00763 return ValueType<Len>();
00764 }
00765
00767 template <size_t Len, size_t SALen>
00768 ValueType<Len> shiftRightArithmetic(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00769 if (!a.name && !sa.name) return IntegerOps::shiftRightArithmetic<Len>(a.offset, sa.offset);
00770 if (!sa.name && 0==sa.offset) return a;
00771 return ValueType<Len>();
00772 }
00773
00775 template <size_t Len1, size_t Len2>
00776 ValueType<Len1> signedDivide(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00777 if (!b.name) {
00778 if (0==b.offset) throw Exception("division by zero");
00779 if (!a.name)
00780 return IntegerOps::signExtend<Len1, 64>(a.offset) / IntegerOps::signExtend<Len2, 64>(b.offset);
00781 if (1==b.offset) return a;
00782 if (b.offset==IntegerOps::GenMask<uint64_t,Len2>::value) return negate(a);
00783
00784 }
00785 return ValueType<Len1>();
00786 }
00787
00789 template <size_t Len1, size_t Len2>
00790 ValueType<Len2> signedModulo(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00791 if (a.name || b.name) return ValueType<Len2>();
00792 if (0==b.offset) throw Exception("division by zero");
00793 return IntegerOps::signExtend<Len1, 64>(a.offset) % IntegerOps::signExtend<Len2, 64>(b.offset);
00794
00795
00796 }
00797
00799 template <size_t Len1, size_t Len2>
00800 ValueType<Len1+Len2> signedMultiply(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00801 if (!a.name && !b.name)
00802 return IntegerOps::signExtend<Len1, 64>(a.offset) * IntegerOps::signExtend<Len2, 64>(b.offset);
00803 if (!b.name) {
00804 if (0==b.offset) return 0;
00805 if (1==b.offset) return signExtend<Len1, Len1+Len2>(a);
00806 if (b.offset==IntegerOps::GenMask<uint64_t,Len2>::value) return signExtend<Len1, Len1+Len2>(negate(a));
00807 }
00808 if (!a.name) {
00809 if (0==a.offset) return 0;
00810 if (1==a.offset) return signExtend<Len2, Len1+Len2>(b);
00811 if (a.offset==IntegerOps::GenMask<uint64_t,Len1>::value) return signExtend<Len2, Len1+Len2>(negate(b));
00812 }
00813 return ValueType<Len1+Len2>();
00814 }
00815
00817 template <size_t Len1, size_t Len2>
00818 ValueType<Len1> unsignedDivide(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00819 if (!b.name) {
00820 if (0==b.offset) throw Exception("division by zero");
00821 if (!a.name) return a.offset / b.offset;
00822 if (1==b.offset) return a;
00823
00824 }
00825 return ValueType<Len1>();
00826 }
00827
00829 template <size_t Len1, size_t Len2>
00830 ValueType<Len2> unsignedModulo(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00831 if (!b.name) {
00832 if (0==b.offset) throw Exception("division by zero");
00833 if (!a.name) return a.offset % b.offset;
00834
00835
00836 }
00837 if (unsignedExtend<Len1,64>(a)==unsignedExtend<Len2,64>(b)) return b;
00838 return ValueType<Len2>();
00839 }
00840
00842 template <size_t Len1, size_t Len2>
00843 ValueType<Len1+Len2> unsignedMultiply(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00844 if (!a.name && !b.name)
00845 return a.offset * b.offset;
00846 if (!b.name) {
00847 if (0==b.offset) return 0;
00848 if (1==b.offset) return unsignedExtend<Len1, Len1+Len2>(a);
00849 }
00850 if (!a.name) {
00851 if (0==a.offset) return 0;
00852 if (1==a.offset) return unsignedExtend<Len2, Len1+Len2>(b);
00853 }
00854 return ValueType<Len1+Len2>();
00855 }
00856
00858 template <size_t Len>
00859 ValueType<Len> xor_(const ValueType<Len> &a, const ValueType<Len> &b) const {
00860 if (!a.name && !b.name)
00861 return a.offset ^ b.offset;
00862 if (a==b)
00863 return 0;
00864 if (!b.name) {
00865 if (0==b.offset) return a;
00866 if (b.offset==IntegerOps::GenMask<uint64_t, Len>::value) return invert(a);
00867 }
00868 if (!a.name) {
00869 if (0==a.offset) return b;
00870 if (a.offset==IntegerOps::GenMask<uint64_t, Len>::value) return invert(b);
00871 }
00872 return ValueType<Len>();
00873 }
00874 };
00875
00876
00877
00878
00879
00880
00881 template<size_t Len> ValueType<Len>
00882 ValueType<Len>::rename(RenameMap *rmap) const
00883 {
00884 ValueType<Len> retval = *this;
00885 if (rmap && name>0) {
00886 RenameMap::iterator found = rmap->find(name);
00887 if (found==rmap->end()) {
00888 retval.name = rmap->size()+1;
00889 rmap->insert(std::make_pair(name, retval.name));
00890 } else {
00891 retval.name = found->second;
00892 }
00893 }
00894 return retval;
00895 }
00896
00897
00898
00899
00900
00901
00902
00903 template<template <size_t> class ValueType>
00904 bool
00905 MemoryCell<ValueType>::may_alias(const MemoryCell &other) const {
00906 const ValueType<32> &addr1 = this->address;
00907 const ValueType<32> &addr2 = other.address;
00908 if (addr1.name != addr2.name) return true;
00909
00910
00911 if (addr1.name && addr1.negate!=addr2.negate) return true;
00912
00913
00914
00915
00916 uint32_t offsetDiff = (uint32_t)(addr1.offset - addr2.offset);
00917 if (offsetDiff < this->nbytes || offsetDiff > (uint32_t)(-other.nbytes))
00918 return true;
00919 return false;
00920 }
00921
00922 template<template<size_t> class ValueType>
00923 bool
00924 MemoryCell<ValueType>::must_alias(const MemoryCell<ValueType> &other) const {
00925 return this->address == other.address;
00926 }
00927
00928
00929
00930
00931
00932 template<template<size_t> class ValueType>
00933 void
00934 State<ValueType>::print_diff_registers(std::ostream &o, const State &other, RenameMap *rmap) const
00935 {
00936 #ifndef CXX_IS_ROSE_ANALYSIS
00937
00938
00939
00940 std::string prefix = " ";
00941
00942 for (size_t i=0; i<this->n_gprs; ++i) {
00943 if (this->gpr[i]!=other.gpr[i]) {
00944 o <<prefix <<gprToString((X86GeneralPurposeRegister)i) <<": "
00945 <<this->gpr[i].rename(rmap) <<" -> " <<other.gpr[i].rename(rmap) <<"\n";
00946 }
00947 }
00948 for (size_t i=0; i<this->n_segregs; ++i) {
00949 if (this->segreg[i]!=other.segreg[i]) {
00950 o <<prefix <<segregToString((X86SegmentRegister)i) <<": "
00951 <<this->segreg[i].rename(rmap) <<" -> " <<other.segreg[i].rename(rmap) <<"\n";
00952 }
00953 }
00954 for (size_t i=0; i<this->n_flags; ++i) {
00955 if (this->flag[i]!=other.flag[i]) {
00956 o <<prefix <<flagToString((X86Flag)i) <<": "
00957 <<this->flag[i].rename(rmap) <<" -> " <<other.flag[i].rename(rmap) <<"\n";
00958 }
00959 }
00960 if (this->ip!=other.ip) {
00961 o <<prefix <<"ip: " <<this->ip.rename(rmap) <<" -> " <<other.ip.rename(rmap) <<"\n";
00962 }
00963 #endif
00964 }
00965
00966 template<template<size_t> class ValueType>
00967 bool
00968 State<ValueType>::equal_registers(const State &other) const
00969 {
00970 #ifndef CXX_IS_ROSE_ANALYSIS
00971 for (size_t i=0; i<this->n_gprs; ++i)
00972 if (this->gpr[i]!=other.gpr[i]) return false;
00973 for (size_t i=0; i<this->n_segregs; ++i)
00974 if (this->segreg[i]!=other.segreg[i]) return false;
00975 for (size_t i=0; i<this->n_flags; ++i)
00976 if (this->flag[i]!=other.flag[i]) return false;
00977 if (this->ip!=other.ip) return false;
00978 #endif
00979 return true;
00980 }
00981
00982 template<template<size_t> class ValueType>
00983 void
00984 State<ValueType>::discard_popped_memory()
00985 {
00986 Memory new_mem;
00987 const ValueType<32> &sp = this->gpr[x86_gpr_sp];
00988 for (typename Memory::const_iterator mi=this->mem.begin(); mi!=this->mem.end(); ++mi) {
00989 const ValueType<32> &addr = (*mi).get_address();
00990 if (addr.name!=sp.name || addr.negate!=sp.negate || (int32_t)addr.offset>=(int32_t)sp.offset)
00991 new_mem.push_back(*mi);
00992 }
00993 this->mem = new_mem;
00994 }
00995
00996
00997
00998
00999
01000
01001 template<
01002 template <template <size_t> class ValueType> class State,
01003 template<size_t> class ValueType>
01004 typename State<ValueType>::Memory
01005 Policy<State, ValueType>::memory_for_equality(const State<ValueType> &state) const
01006 {
01007 State<ValueType> tmp_state = state;
01008 typename State<ValueType>::Memory retval;
01009 #ifndef CXX_IS_ROSE_ANALYSIS
01010 for (typename State<ValueType>::Memory::const_iterator mi=state.mem.begin(); mi!=state.mem.end(); ++mi) {
01011 if ((*mi).is_written() && (*mi).get_data()!=mem_read<32>(orig_state, (*mi).get_address()))
01012 retval.push_back(*mi);
01013 }
01014 #endif
01015 return retval;
01016 }
01017
01018 template<
01019 template <template <size_t> class ValueType> class State,
01020 template<size_t> class ValueType>
01021 bool
01022 Policy<State, ValueType>::equal_states(const State<ValueType> &s1, const State<ValueType> &s2) const
01023 {
01024 #ifndef CXX_IS_ROSE_ANALYSIS
01025 if (!s1.equal_registers(s2))
01026 return false;
01027 typename State<ValueType>::Memory m1 = memory_for_equality(s1);
01028 typename State<ValueType>::Memory m2 = memory_for_equality(s2);
01029 if (m1.size()!=m2.size())
01030 return false;
01031 for (size_t i=0; i<m1.size(); ++i) {
01032 if (m1[i].get_nbytes() != m2[i].get_nbytes() ||
01033 m1[i].get_address()!= m2[i].get_address() ||
01034 m1[i].get_data() != m2[i].get_data())
01035 return false;
01036 }
01037 #endif
01038 return true;
01039 }
01040
01041 template<
01042 template <template <size_t> class ValueType> class State,
01043 template<size_t> class ValueType>
01044 void
01045 Policy<State, ValueType>::print(std::ostream &o, RenameMap *rmap) const
01046 {
01047 cur_state.print(o, "", rmap);
01048 }
01049
01050 template<
01051 template <template <size_t> class ValueType> class State,
01052 template<size_t> class ValueType>
01053 void
01054 Policy<State, ValueType>::print_diff(std::ostream &o, const State<ValueType> &s1,
01055 const State<ValueType> &s2, RenameMap *rmap) const
01056 {
01057 #ifndef CXX_IS_ROSE_ANALYSIS
01058 s1.print_diff_registers(o, s2, rmap);
01059
01060
01061 std::set<ValueType<32> > addresses;
01062 for (typename State<ValueType>::Memory::const_iterator mi=s1.mem.begin(); mi!=s1.mem.end(); ++mi) {
01063 if (!(*mi).is_clobbered() && (*mi).is_written())
01064 addresses.insert((*mi).get_address());
01065 }
01066 for (typename State<ValueType>::Memory::const_iterator mi=s2.mem.begin(); mi!=s2.mem.end(); ++mi) {
01067 if (!(*mi).is_clobbered() && (*mi).is_written())
01068 addresses.insert((*mi).get_address());
01069 }
01070
01071 State<ValueType> tmp_s1 = s1;
01072 State<ValueType> tmp_s2 = s2;
01073 size_t nmemdiff = 0;
01074 for (typename std::set<ValueType<32> >::const_iterator ai=addresses.begin(); ai!=addresses.end(); ++ai) {
01075 ValueType<32> v1 = mem_read<32>(tmp_s1, *ai);
01076 ValueType<32> v2 = mem_read<32>(tmp_s2, *ai);
01077 if (v1 != v2) {
01078 if (0==nmemdiff++) o <<" memory:\n";
01079 o <<" " <<(*ai).rename(rmap) <<": " <<v1.rename(rmap) <<" -> " <<v2.rename(rmap) <<"\n";
01080 }
01081 }
01082 #endif
01083 }
01084
01085 template<
01086 template <template <size_t> class ValueType> class State,
01087 template<size_t> class ValueType>
01088 bool
01089 Policy<State, ValueType>::on_stack(const ValueType<32> &value) const
01090 {
01091 #ifndef CXX_IS_ROSE_ANALYSIS
01092 const ValueType<32> sp_inverted = invert(cur_state.gpr[x86_gpr_sp]);
01093 for (typename State<ValueType>::Memory::const_iterator mi=cur_state.mem.begin(); mi!=cur_state.mem.end(); ++mi) {
01094 if ((*mi).get_nbytes()!=4 || !((*mi).get_data()==value)) continue;
01095 const ValueType<32> &addr = (*mi).get_address();
01096
01097
01098 ValueType<32> carries = 0;
01099 ValueType<32> diff = addWithCarries(addr, sp_inverted, true_(), carries);
01100 ValueType<1> sf = extract<31,32>(diff);
01101 ValueType<1> of = xor_(extract<31,32>(carries), extract<30,31>(carries));
01102 if (sf==of) return true;
01103 }
01104 #endif
01105 return false;
01106 }
01107
01108 template<
01109 template <template <size_t> class ValueType> class State,
01110 template<size_t> class ValueType>
01111 bool
01112 Policy<State, ValueType>::SHA1(unsigned char digest[20]) const
01113 {
01114 #ifdef ROSE_HAVE_GCRYPT_H
01115
01116
01117
01118
01119 static bool initialized = false;
01120 if (!initialized) {
01121 gcry_check_version(NULL);
01122 initialized = true;
01123 }
01124
01125 std::stringstream s;
01126 RenameMap rmap;
01127 print_diff(s, &rmap);
01128 ROSE_ASSERT(gcry_md_get_algo_dlen(GCRY_MD_SHA1)==20);
01129 gcry_md_hash_buffer(GCRY_MD_SHA1, digest, s.str().c_str(), s.str().size());
01130 return true;
01131 #else
01132 memset(digest, 0, 20);
01133 return false;
01134 #endif
01135 }
01136
01137 template<
01138 template <template <size_t> class ValueType> class State,
01139 template<size_t> class ValueType>
01140 std::string
01141 Policy<State, ValueType>::SHA1() const
01142 {
01143 std::string digest_str;
01144 unsigned char digest[20];
01145 if (SHA1(digest)) {
01146 for (size_t i=sizeof digest; i>0; --i) {
01147 digest_str += "0123456789abcdef"[(digest[i-1] >> 4) & 0xf];
01148 digest_str += "0123456789abcdef"[digest[i-1] & 0xf];
01149 }
01150 }
01151 return digest_str;
01152 }
01153
01154 }
01155 }
01156 }
01157
01158
01159 #endif