00001 #ifndef Rose_SymbolicSemantics_H
00002 #define Rose_SymbolicSemantics_H
00003 #include <stdint.h>
00004
00005 #ifndef __STDC_FORMAT_MACROS
00006 #define __STDC_FORMAT_MACROS
00007 #endif
00008 #include <inttypes.h>
00009
00010 #include "x86InstructionSemantics.h"
00011 #include "BaseSemantics.h"
00012 #include "SMTSolver.h"
00013
00014 #include <map>
00015 #include <vector>
00016
00017 namespace BinaryAnalysis {
00018 namespace InstructionSemantics {
00019
00035 namespace SymbolicSemantics {
00036
00037 typedef InsnSemanticsExpr::RenameMap RenameMap;
00038 typedef InsnSemanticsExpr::LeafNode LeafNode;
00039 typedef InsnSemanticsExpr::LeafNodePtr LeafNodePtr;
00040 typedef InsnSemanticsExpr::InternalNode InternalNode;
00041 typedef InsnSemanticsExpr::InternalNodePtr InternalNodePtr;
00042 typedef InsnSemanticsExpr::TreeNode TreeNode;
00043 typedef InsnSemanticsExpr::TreeNodePtr TreeNodePtr;
00044 typedef std::set<SgAsmInstruction*> InsnSet;
00045
00046
00047
00048
00049
00050
00051
00052
00053 template<size_t nBits>
00054 class ValueType {
00055 protected:
00056 TreeNodePtr expr;
00057
00060 InsnSet defs;
00061
00062 public:
00063
00065 ValueType(std::string comment="") {
00066 expr = LeafNode::create_variable(nBits, comment);
00067 }
00068
00069 ValueType(const ValueType &other) {
00070 expr = other.expr;
00071 defs = other.defs;
00072 }
00073
00075 explicit ValueType(uint64_t n, std::string comment="") {
00076 expr = LeafNode::create_integer(nBits, n, comment);
00077 }
00078
00080 explicit ValueType(const TreeNodePtr &node) {
00081 assert(node->get_nbits()==nBits);
00082 expr = node;
00083 }
00084
00089 ValueType& defined_by(SgAsmInstruction *insn, const InsnSet &set1, const InsnSet &set2, const InsnSet &set3) {
00090 add_defining_instructions(set3);
00091 return defined_by(insn, set1, set2);
00092 }
00093 ValueType& defined_by(SgAsmInstruction *insn, const InsnSet &set1, const InsnSet &set2) {
00094 add_defining_instructions(set2);
00095 return defined_by(insn, set1);
00096 }
00097 ValueType& defined_by(SgAsmInstruction *insn, const InsnSet &set1) {
00098 add_defining_instructions(set1);
00099 return defined_by(insn);
00100 }
00101 ValueType& defined_by(SgAsmInstruction *insn) {
00102 add_defining_instructions(insn);
00103 return *this;
00104 }
00109 void print(std::ostream &o, RenameMap *rmap=NULL) const {
00110 o <<"defs={";
00111 size_t ndefs=0;
00112 for (InsnSet::const_iterator di=defs.begin(); di!=defs.end(); ++di, ++ndefs) {
00113 SgAsmInstruction *insn = *di;
00114 if (insn!=NULL)
00115 o <<(ndefs>0?",":"") <<StringUtility::addrToString(insn->get_address());
00116 }
00117 o <<"} expr=";
00118 expr->print(o, rmap);
00119 }
00120 void print(std::ostream &o, BaseSemantics::SEMANTIC_NO_PRINT_HELPER *unused=NULL) const {
00121 print(o, (RenameMap*)0);
00122 }
00123 friend std::ostream& operator<<(std::ostream &o, const ValueType &e) {
00124 e.print(o, (RenameMap*)0);
00125 return o;
00126 }
00127
00129 bool is_known() const {
00130 return expr->is_known();
00131 }
00132
00134 uint64_t known_value() const {
00135 LeafNodePtr leaf = expr->isLeafNode();
00136 assert(leaf!=NULL);
00137 return leaf->get_value();
00138 }
00139
00142 const TreeNodePtr& get_expression() const {
00143 return expr;
00144 }
00145
00148 void set_expression(const TreeNodePtr &new_expr) {
00149 expr = new_expr;
00150 }
00151 void set_expression(const ValueType &source) {
00152 set_expression(source.get_expression());
00153 }
00168 const InsnSet& get_defining_instructions() const {
00169 return defs;
00170 }
00171
00175 size_t add_defining_instructions(const InsnSet &to_add) {
00176 size_t nadded = 0;
00177 for (InsnSet::const_iterator i=to_add.begin(); i!=to_add.end(); ++i) {
00178 std::pair<InsnSet::iterator, bool> inserted = defs.insert(*i);
00179 if (inserted.second)
00180 ++nadded;
00181 }
00182 return nadded;
00183 }
00184 size_t add_defining_instructions(const ValueType &source) {
00185 return add_defining_instructions(source.get_defining_instructions());
00186 }
00187 size_t add_defining_instructions(SgAsmInstruction *insn) {
00188 InsnSet tmp;
00189 if (insn)
00190 tmp.insert(insn);
00191 return add_defining_instructions(tmp);
00192 }
00198 void set_defining_instructions(const InsnSet &new_defs) {
00199 defs = new_defs;
00200 }
00201 void set_defining_instructions(const ValueType &source) {
00202 set_defining_instructions(source.get_defining_instructions());
00203 }
00204 void set_defining_instructions(SgAsmInstruction *insn) {
00205 InsnSet tmp;
00206 if (insn)
00207 tmp.insert(insn);
00208 return set_defining_instructions(tmp);
00209 }
00212 };
00213
00214
00215
00216
00217
00218
00221 template<template<size_t> class ValueType=SymbolicSemantics::ValueType>
00222 class MemoryCell: public BaseSemantics::MemoryCell<ValueType> {
00223 public:
00224
00227 template <size_t Len>
00228 MemoryCell(const ValueType<32> &address, const ValueType<Len> &data, size_t nbytes, SgAsmInstruction *insn=NULL)
00229 : BaseSemantics::MemoryCell<ValueType>(address, data, nbytes) {
00230 this->get_data().add_defining_instructions(insn);
00231 }
00232
00254 bool may_alias(const MemoryCell &other, SMTSolver *solver) const {
00255 bool retval = must_alias(other, solver);
00256 if (retval)
00257 return retval;
00258 if (solver) {
00259 TreeNodePtr x_addr = this->address.get_expression();
00260 TreeNodePtr x_nbytes = LeafNode::create_integer(32, this->nbytes);
00261 TreeNodePtr y_addr = other.address.get_expression();
00262 TreeNodePtr y_nbytes = LeafNode::create_integer(32, other.nbytes);
00263
00264 TreeNodePtr x_end =
00265 InternalNode::create(32, InsnSemanticsExpr::OP_ADD, x_addr, x_nbytes);
00266 TreeNodePtr y_end =
00267 InternalNode::create(32, InsnSemanticsExpr::OP_ADD, y_addr, y_nbytes);
00268
00269 TreeNodePtr and1 =
00270 InternalNode::create(1, InsnSemanticsExpr::OP_AND,
00271 InternalNode::create(1, InsnSemanticsExpr::OP_UGT, x_end, y_addr),
00272 InternalNode::create(1, InsnSemanticsExpr::OP_ULT, x_addr, y_end));
00273 TreeNodePtr and2 =
00274 InternalNode::create(1, InsnSemanticsExpr::OP_AND,
00275 InternalNode::create(1, InsnSemanticsExpr::OP_UGT, y_end, x_addr),
00276 InternalNode::create(1, InsnSemanticsExpr::OP_ULT, y_addr, x_end));
00277 TreeNodePtr assertion =
00278 InternalNode::create(1, InsnSemanticsExpr::OP_OR, and1, and2);
00279 retval = solver->satisfiable(assertion);
00280 }
00281 return retval;
00282 }
00283
00287 bool must_alias(const MemoryCell &other, SMTSolver *solver) const {
00288 return this->get_address().get_expression()->equal_to(other.get_address().get_expression(), solver);
00289 }
00290 };
00291
00293 template <template <size_t> class ValueType=SymbolicSemantics::ValueType>
00294 struct State: public BaseSemantics::StateX86<MemoryCell, ValueType> {
00297 void print_diff_registers(std::ostream &o, const State&, RenameMap *rmap=NULL) const;
00298
00300 bool equal_registers(const State&) const;
00301
00304 void discard_popped_memory() {
00305
00306 }
00307 };
00308
00312 template <
00313 template <template <size_t> class ValueType> class State = SymbolicSemantics::State,
00314 template <size_t> class ValueType = SymbolicSemantics::ValueType
00315 >
00316 class Policy: public BaseSemantics::Policy {
00317 protected:
00318 typedef typename State<ValueType>::Memory Memory;
00319
00320 SgAsmInstruction *cur_insn;
00321 mutable State<ValueType> orig_state;
00332 mutable State<ValueType> cur_state;
00338 bool p_discard_popped_memory;
00343 size_t ninsns;
00346 SMTSolver *solver;
00348 public:
00349
00351 Policy() {
00352 init();
00353
00354 orig_state = cur_state;
00355 }
00356
00358 Policy(SMTSolver *solver) {
00359 init();
00360 this->solver = solver;
00361
00362 orig_state = cur_state;
00363 }
00364
00366 void init() {
00367 set_register_dictionary(RegisterDictionary::dictionary_pentium4());
00368 cur_insn = NULL;
00369 p_discard_popped_memory = false;
00370 ninsns = 0;
00371 solver = NULL;
00372 }
00373
00375 void set_solver(SMTSolver *s) { solver = s; }
00376
00378 SMTSolver *get_solver() const { return solver; }
00379
00381 const State<ValueType>& get_state() const { return cur_state; }
00382 State<ValueType>& get_state() { return cur_state; }
00383
00386 const State<ValueType>& get_orig_state() const { return orig_state; }
00387 State<ValueType>& get_orig_state() { return orig_state; }
00388
00390 const ValueType<32>& get_ip() const { return cur_state.ip; }
00391
00393 const ValueType<32>& get_orig_ip() const { return orig_state.ip; }
00394
00396 Memory memory_for_equality(const State<ValueType>&) const;
00397
00400 Memory memory_for_equality() const { return memory_for_equality(cur_state); }
00401
00405 bool equal_states(const State<ValueType>&, const State<ValueType>&) const;
00406
00409 void print(std::ostream &o, RenameMap *rmap=NULL) const {
00410 cur_state.print(o, "", rmap);
00411 }
00412 friend std::ostream& operator<<(std::ostream &o, const Policy &p) {
00413 p.print(o, NULL);
00414 return o;
00415 }
00416
00419 bool on_stack(const ValueType<32> &value) const;
00420
00423 void set_discard_popped_memory(bool b) {
00424 p_discard_popped_memory = b;
00425 }
00426
00429 bool get_discard_popped_memory() const {
00430 return p_discard_popped_memory;
00431 }
00432
00435 void print_diff(std::ostream&, const State<ValueType>&, const State<ValueType>&, RenameMap *rmap=NULL) const ;
00436
00439 void print_diff(std::ostream &o, const State<ValueType> &state, RenameMap *rmap=NULL) const {
00440 print_diff(o, orig_state, state, rmap);
00441 }
00442
00445 void print_diff(std::ostream &o, RenameMap *rmap=NULL) const {
00446 print_diff(o, orig_state, cur_state, rmap);
00447 }
00448
00451 std::string SHA1() const;
00452
00455 template <size_t FromLen, size_t ToLen>
00456 ValueType<ToLen> unsignedExtend(const ValueType<FromLen> &a) const {
00457 if (a.is_known())
00458 return ValueType<ToLen>(IntegerOps::GenMask<uint64_t,ToLen>::value & a.known_value())
00459 .defined_by(cur_insn, a.get_defining_instructions());
00460 if (FromLen==ToLen) {
00461
00462 return ValueType<ToLen>(a.get_expression()).defined_by(NULL, a.get_defining_instructions());
00463 }
00464 if (FromLen>ToLen)
00465 return ValueType<ToLen>(InternalNode::create(ToLen, InsnSemanticsExpr::OP_EXTRACT,
00466 LeafNode::create_integer(32, 0),
00467 LeafNode::create_integer(32, ToLen),
00468 a.get_expression()))
00469 .defined_by(cur_insn, a.get_defining_instructions());
00470 return ValueType<ToLen>(InternalNode::create(ToLen, InsnSemanticsExpr::OP_UEXTEND,
00471 LeafNode::create_integer(32, ToLen), a.get_expression()))
00472 .defined_by(cur_insn, a.get_defining_instructions());
00473 }
00474
00476 template <size_t FromLen, size_t ToLen>
00477 ValueType<ToLen> signedExtend(const ValueType<FromLen> &a) const {
00478 if (a.is_known())
00479 return ValueType<ToLen>(IntegerOps::signExtend<FromLen, ToLen>(a.known_value())).
00480 defined_by(cur_insn, a.get_defining_instructions());
00481 if (FromLen==ToLen) {
00482
00483 return ValueType<ToLen>(a.get_expression()).defined_by(NULL, a.get_defining_instructions());
00484 }
00485 if (FromLen > ToLen)
00486 return ValueType<ToLen>(InternalNode::create(ToLen, InsnSemanticsExpr::OP_EXTRACT,
00487 LeafNode::create_integer(32, 0),
00488 LeafNode::create_integer(32, ToLen),
00489 a.get_expression()))
00490 .defined_by(cur_insn, a.get_defining_instructions());
00491 return ValueType<ToLen>(InternalNode::create(ToLen, InsnSemanticsExpr::OP_SEXTEND,
00492 LeafNode::create_integer(32, ToLen), a.get_expression()))
00493 .defined_by(cur_insn, a.get_defining_instructions());
00494 }
00495
00499 template <size_t BeginAt, size_t EndAt, size_t Len>
00500 ValueType<EndAt-BeginAt> extract(const ValueType<Len> &a) const {
00501 if (0==BeginAt)
00502 return unsignedExtend<Len,EndAt-BeginAt>(a);
00503 if (a.is_known())
00504 return ValueType<EndAt-BeginAt>((a.known_value()>>BeginAt) & IntegerOps::genMask<uint64_t>(EndAt-BeginAt))
00505 .defined_by(cur_insn, a.get_defining_instructions());
00506 return ValueType<EndAt-BeginAt>(InternalNode::create(EndAt-BeginAt, InsnSemanticsExpr::OP_EXTRACT,
00507 LeafNode::create_integer(32, BeginAt),
00508 LeafNode::create_integer(32, EndAt),
00509 a.get_expression()))
00510 .defined_by(cur_insn, a.get_defining_instructions());
00511 }
00512
00524 template <size_t Len> ValueType<Len> mem_read(State<ValueType> &state, const ValueType<32> &addr,
00525 const ValueType<Len> &dflt) const {
00526 MemoryCell<ValueType> new_cell(addr, unsignedExtend<Len,32>(dflt), Len/8, NULL);
00527 bool aliased = false;
00528
00529 for (typename Memory::iterator mi=state.mem.begin(); mi!=state.mem.end(); ++mi) {
00530 if (new_cell.must_alias(*mi, solver)) {
00531 if ((*mi).is_clobbered()) {
00532 (*mi).set_clobbered(false);
00533 (*mi).set_data(new_cell.get_data());
00534 return unsignedExtend<32, Len>(new_cell.get_data());
00535 } else {
00536 return unsignedExtend<32, Len>((*mi).get_data());
00537 }
00538 } else if ((*mi).is_written() && new_cell.may_alias(*mi, solver)) {
00539 aliased = true;
00540 }
00541 }
00542
00543 if (!aliased && &state!=&orig_state) {
00544
00545
00546 for (typename Memory::iterator mi=orig_state.mem.begin(); mi!=orig_state.mem.end(); ++mi) {
00547 if (new_cell.must_alias(*mi, solver)) {
00548 ROSE_ASSERT(!(*mi).is_clobbered());
00549 ROSE_ASSERT(!(*mi).is_written());
00550 state.mem.push_back(*mi);
00551 return unsignedExtend<32, Len>((*mi).get_data());
00552 }
00553 }
00554
00555 orig_state.mem.push_back(new_cell);
00556 }
00557
00558
00559 state.mem.push_back(new_cell);
00560 return unsignedExtend<32,Len>(new_cell.get_data());
00561 }
00562
00564 enum MemRefType { MRT_STACK_PTR, MRT_FRAME_PTR, MRT_OTHER_PTR };
00565
00570 MemRefType memory_reference_type(const State<ValueType> &state, const ValueType<32> &addr) const {
00571 #if 0
00572 if (addr.name) {
00573 if (addr.name==state.gpr[x86_gpr_sp].name) return MRT_STACK_PTR;
00574 if (addr.name==state.gpr[x86_gpr_bp].name) return MRT_FRAME_PTR;
00575 return MRT_OTHER_PTR;
00576 }
00577 if (addr==state.gpr[x86_gpr_sp]) return MRT_STACK_PTR;
00578 if (addr==state.gpr[x86_gpr_bp]) return MRT_FRAME_PTR;
00579 #endif
00580 return MRT_OTHER_PTR;
00581 }
00582
00586 template <size_t Len> void mem_write(State<ValueType> &state, const ValueType<32> &addr,
00587 const ValueType<Len> &data) {
00588 ROSE_ASSERT(&state!=&orig_state);
00589 MemoryCell<ValueType> new_cell(addr, unsignedExtend<Len, 32>(data), Len/8, cur_insn);
00590 new_cell.set_written();
00591 bool saved = false;
00592
00593
00594 MemRefType new_mrt = memory_reference_type(state, addr);
00595
00596
00597 for (typename Memory::iterator mi=state.mem.begin(); mi!=state.mem.end(); ++mi) {
00598 if (new_cell.must_alias(*mi, solver)) {
00599 *mi = new_cell;
00600 saved = true;
00601 } else if (p_discard_popped_memory && new_mrt!=memory_reference_type(state, (*mi).get_address())) {
00602
00603
00604 } else if (new_cell.may_alias(*mi, solver)) {
00605 (*mi).set_clobbered();
00606 } else {
00607
00608 }
00609 }
00610 if (!saved)
00611 state.mem.push_back(new_cell);
00612 }
00613
00614
00615
00616
00617
00618
00620 void startInstruction(SgAsmInstruction *insn) {
00621 if (!cur_state.ip.is_known()) {
00622 cur_state.ip = ValueType<32>(insn->get_address());
00623 } else if (cur_state.ip.known_value()!=insn->get_address()) {
00624 fprintf(stderr, "SymbolicSemantics::Policy::startInstruction: invalid EIP value for current instruction\n\
00625 startInstruction() is being called for an instruction with a concrete\n\
00626 address stored in the SgAsmx86Instruction object, but the current value of\n\
00627 this policy's EIP register does not match the instruction. This might\n\
00628 happen if you're processing instructions in an order that's different than\n\
00629 the order the policy thinks they would be executed. If this is truly your\n\
00630 intent, then you need to set the policy's EIP register to the instruction\n\
00631 address before you translate the instruction--and you might want to make\n\
00632 sure the other state information is also appropriate for this instruction\n\
00633 rather than use the final state from the previously translated\n\
00634 instruction. x86 \"REP\" instructions might be the culprit: ROSE\n\
00635 instruction semantics treat them as a tiny loop, updating the policy's EIP\n\
00636 depending on whether the loop is to be taken again, or not.\n");
00637 assert(cur_state.ip.known_value()==insn->get_address());
00638 abort();
00639 }
00640 if (0==ninsns++)
00641 orig_state = cur_state;
00642 cur_insn = insn;
00643 }
00644
00646 void finishInstruction(SgAsmInstruction*) {
00647 if (p_discard_popped_memory)
00648 cur_state.discard_popped_memory();
00649 cur_insn = NULL;
00650 }
00651
00652
00653
00654
00655
00656
00657
00659 ValueType<1> true_() const {
00660 return ValueType<1>(1).defined_by(cur_insn);
00661 }
00662
00664 ValueType<1> false_() const {
00665 return ValueType<1>((uint64_t)0).defined_by(cur_insn);
00666 }
00667
00669 ValueType<1> undefined_() const {
00670 return ValueType<1>().defined_by(cur_insn);
00671 }
00672
00674 template <size_t Len>
00675 ValueType<Len> number(uint64_t n) const {
00676 return ValueType<Len>(n).defined_by(cur_insn);
00677 }
00678
00679
00680
00681
00682
00683
00684
00686 ValueType<32> filterCallTarget(const ValueType<32> &a) const {
00687 return a;
00688 }
00689
00691 ValueType<32> filterReturnTarget(const ValueType<32> &a) const {
00692 return a;
00693 }
00694
00696 ValueType<32> filterIndirectJumpTarget(const ValueType<32> &a) const {
00697 return a;
00698 }
00699
00701 void hlt() {}
00702
00704 void cpuid() {}
00705
00707 ValueType<64> rdtsc() {
00708 return ValueType<64>((uint64_t)0);
00709 }
00710
00712 void interrupt(uint8_t num) {
00713 cur_state = State<ValueType>();
00714 }
00715
00717 void sysenter() {
00718 cur_state = State<ValueType>();
00719 }
00720
00721
00722
00723
00724
00725
00726
00728 template <size_t Len>
00729 ValueType<Len> add(const ValueType<Len> &a, const ValueType<Len> &b) const {
00730 if (a.is_known()) {
00731 if (b.is_known()) {
00732 return ValueType<Len>(LeafNode::create_integer(Len, a.known_value()+b.known_value()))
00733 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00734 } else if (0==a.known_value()) {
00735 return b;
00736 }
00737 } else if (b.is_known() && 0==b.known_value()) {
00738 return a;
00739 }
00740 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_ADD,
00741 a.get_expression(),
00742 b.get_expression()))
00743 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00744 }
00745
00747 template <size_t Len>
00748 ValueType<Len> addWithCarries(const ValueType<Len> &a, const ValueType<Len> &b, const ValueType<1> &c,
00749 ValueType<Len> &carry_out) const {
00750 ValueType<Len+1> aa = unsignedExtend<Len, Len+1>(a);
00751 ValueType<Len+1> bb = unsignedExtend<Len, Len+1>(b);
00752 ValueType<Len+1> cc = unsignedExtend<1, Len+1>(c);
00753 ValueType<Len+1> sumco = add<Len+1>(aa, add<Len+1>(bb, cc));
00754 carry_out = extract<1, Len+1>(xor_<Len+1>(aa, xor_<Len+1>(bb, sumco)));
00755 return add<Len>(a, add<Len>(b, unsignedExtend<1, Len>(c)));
00756 }
00757
00759 template <size_t Len>
00760 ValueType<Len> and_(const ValueType<Len> &a, const ValueType<Len> &b) const {
00761 if (a.is_known() && b.is_known())
00762 return ValueType<Len>(a.known_value() & b.known_value())
00763 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00764 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_BV_AND,
00765 a.get_expression(), b.get_expression()))
00766 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00767 }
00768
00770 template <size_t Len>
00771 ValueType<1> equalToZero(const ValueType<Len> &a) const {
00772 if (a.is_known()) {
00773 ValueType<1> retval = a.known_value() ? false_() : true_();
00774 return retval.defined_by(cur_insn, a.get_defining_instructions());
00775 }
00776 return ValueType<1>(InternalNode::create(1, InsnSemanticsExpr::OP_ZEROP, a.get_expression()))
00777 .defined_by(cur_insn, a.get_defining_instructions());
00778 }
00779
00781 template <size_t Len>
00782 ValueType<Len> invert(const ValueType<Len> &a) const {
00783 if (a.is_known())
00784 return ValueType<Len>(LeafNode::create_integer(Len, ~a.known_value()))
00785 .defined_by(cur_insn, a.get_defining_instructions());
00786 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_INVERT, a.get_expression()))
00787 .defined_by(cur_insn, a.get_defining_instructions());
00788 }
00789
00791 template<size_t Len1, size_t Len2>
00792 ValueType<Len1+Len2> concat(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00793 if (a.is_known() && b.is_known())
00794 return ValueType<Len1+Len2>(a.known_value() | (b.known_value() << Len1))
00795 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00796 return ValueType<Len1+Len2>(InternalNode::create(Len1+Len2, InsnSemanticsExpr::OP_CONCAT,
00797 b.get_expression(), a.get_expression()))
00798 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00799 }
00800
00802 template <size_t Len>
00803 ValueType<Len> ite(const ValueType<1> &sel, const ValueType<Len> &ifTrue, const ValueType<Len> &ifFalse) const {
00804 if (sel.is_known()) {
00805 ValueType<Len> retval = sel.known_value() ? ifTrue : ifFalse;
00806 return retval.defined_by(cur_insn, sel.get_defining_instructions());
00807 }
00808 if (solver) {
00809
00810 TreeNodePtr assertion = InternalNode::create(1, InsnSemanticsExpr::OP_EQ,
00811 sel.get_expression(),
00812 LeafNode::create_integer(1, 1));
00813 bool can_be_true = solver->satisfiable(assertion);
00814 if (!can_be_true) {
00815 ValueType<Len> retval = ifFalse;
00816 return retval.defined_by(cur_insn, sel.get_defining_instructions());
00817 }
00818
00819
00820 assertion = InternalNode::create(1, InsnSemanticsExpr::OP_EQ,
00821 sel.get_expression(), LeafNode::create_integer(1, 0));
00822 bool can_be_false = solver->satisfiable(assertion);
00823 if (!can_be_false) {
00824 ValueType<Len> retval = ifTrue;
00825 return retval.defined_by(cur_insn, sel.get_defining_instructions());
00826 }
00827 }
00828 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_ITE, sel.get_expression(),
00829 ifTrue.get_expression(), ifFalse.get_expression()))
00830 .defined_by(cur_insn, sel.get_defining_instructions(),
00831 ifTrue.get_defining_instructions(), ifFalse.get_defining_instructions());
00832 }
00833
00835 template <size_t Len>
00836 ValueType<Len> leastSignificantSetBit(const ValueType<Len> &a) const {
00837 if (a.is_known()) {
00838 uint64_t n = a.known_value();
00839 for (size_t i=0; i<Len; ++i) {
00840 if (n & ((uint64_t)1 << i))
00841 return number<Len>(i).defined_by(cur_insn, a.get_defining_instructions());
00842 }
00843 return number<Len>(0).defined_by(cur_insn, a.get_defining_instructions());
00844 }
00845 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_LSSB, a.get_expression()))
00846 .defined_by(cur_insn, a.get_defining_instructions());
00847 }
00848
00850 template <size_t Len>
00851 ValueType<Len> mostSignificantSetBit(const ValueType<Len> &a) const {
00852 if (a.is_known()) {
00853 uint64_t n = a.known_value();
00854 for (size_t i=Len; i>0; --i) {
00855 if (n & ((uint64_t)1 << (i-1)))
00856 return number<Len>(i-1).defined_by(cur_insn, a.get_defining_instructions());
00857 }
00858 return number<Len>(0);
00859 }
00860 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_MSSB, a.get_expression()))
00861 .defined_by(cur_insn, a.get_defining_instructions());
00862 }
00863
00865 template <size_t Len>
00866 ValueType<Len> negate(const ValueType<Len> &a) const {
00867 if (a.is_known())
00868 return ValueType<Len>(-a.known_value()).defined_by(cur_insn, a.get_defining_instructions());
00869 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_NEGATE, a.get_expression()))
00870 .defined_by(cur_insn, a.get_defining_instructions());
00871 }
00872
00874 template <size_t Len>
00875 ValueType<Len> or_(const ValueType<Len> &a, const ValueType<Len> &b) const {
00876 if (a.is_known() && b.is_known())
00877 return ValueType<Len>(a.known_value() | b.known_value())
00878 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00879 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_BV_OR,
00880 a.get_expression(), b.get_expression()))
00881 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00882 }
00883
00885 template <size_t Len, size_t SALen>
00886 ValueType<Len> rotateLeft(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00887 if (a.is_known() && sa.is_known())
00888 return ValueType<Len>(IntegerOps::rotateLeft<Len>(a.known_value(), sa.known_value()))
00889 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00890 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_ROL,
00891 sa.get_expression(), a.get_expression()))
00892 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00893 }
00894
00896 template <size_t Len, size_t SALen>
00897 ValueType<Len> rotateRight(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00898 if (a.is_known() && sa.is_known())
00899 return ValueType<Len>(IntegerOps::rotateRight<Len>(a.known_value(), sa.known_value()))
00900 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00901 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_ROR,
00902 sa.get_expression(), a.get_expression()))
00903 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00904 }
00905
00907 template <size_t Len, size_t SALen>
00908 ValueType<Len> shiftLeft(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00909 if (a.is_known() && sa.is_known())
00910 return ValueType<Len>(IntegerOps::shiftLeft<Len>(a.known_value(), sa.known_value()))
00911 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00912 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_SHL0,
00913 sa.get_expression(), a.get_expression()))
00914 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00915 }
00916
00918 template <size_t Len, size_t SALen>
00919 ValueType<Len> shiftRight(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00920 if (a.is_known() && sa.is_known())
00921 return ValueType<Len>(IntegerOps::shiftRightLogical<Len>(a.known_value(), sa.known_value()))
00922 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00923 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_SHR0,
00924 sa.get_expression(), a.get_expression()))
00925 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00926 }
00927
00929 template <size_t Len, size_t SALen>
00930 ValueType<Len> shiftRightArithmetic(const ValueType<Len> &a, const ValueType<SALen> &sa) const {
00931 if (a.is_known() && sa.is_known())
00932 return ValueType<Len>(IntegerOps::shiftRightArithmetic<Len>(a.known_value(), sa.known_value()))
00933 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00934 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_ASR,
00935 sa.get_expression(), a.get_expression()))
00936 .defined_by(cur_insn, a.get_defining_instructions(), sa.get_defining_instructions());
00937 }
00938
00940 template <size_t From, size_t To>
00941 ValueType<To> signExtend(const ValueType<From> &a) {
00942 return signedExtend<From, To>(a);
00943 }
00944
00946 template <size_t Len1, size_t Len2>
00947 ValueType<Len1> signedDivide(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00948 if (a.is_known() && b.is_known() && 0!=b.known_value())
00949 return ValueType<Len1>(IntegerOps::signExtend<Len1, 64>(a.known_value()) /
00950 IntegerOps::signExtend<Len2, 64>(b.known_value()))
00951 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00952 return ValueType<Len1>(InternalNode::create(Len1, InsnSemanticsExpr::OP_SDIV,
00953 a.get_expression(), b.get_expression()))
00954 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00955 }
00956
00958 template <size_t Len1, size_t Len2>
00959 ValueType<Len2> signedModulo(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00960 if (a.is_known() && b.is_known() && 0!=b.known_value())
00961 return ValueType<Len2>(IntegerOps::signExtend<Len1, 64>(a.known_value()) %
00962 IntegerOps::signExtend<Len2, 64>(b.known_value()))
00963 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00964 return ValueType<Len2>(InternalNode::create(Len2, InsnSemanticsExpr::OP_SMOD,
00965 a.get_expression(), b.get_expression()))
00966 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00967 }
00968
00970 template <size_t Len1, size_t Len2>
00971 ValueType<Len1+Len2> signedMultiply(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00972 if (a.is_known() && b.is_known())
00973 return ValueType<Len1+Len2>(IntegerOps::signExtend<Len1, 64>(a.known_value()) *
00974 IntegerOps::signExtend<Len2, 64>(b.known_value()))
00975 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00976 return ValueType<Len1+Len2>(InternalNode::create(Len1+Len2, InsnSemanticsExpr::OP_SMUL,
00977 a.get_expression(), b.get_expression()))
00978 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00979 }
00980
00982 template <size_t Len1, size_t Len2>
00983 ValueType<Len1> unsignedDivide(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00984 if (a.is_known() && b.is_known() && 0!=b.known_value())
00985 return ValueType<Len1>(a.known_value() / b.known_value())
00986 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00987 return ValueType<Len1>(InternalNode::create(Len1, InsnSemanticsExpr::OP_UDIV,
00988 a.get_expression(), b.get_expression()))
00989 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00990 }
00991
00993 template <size_t Len1, size_t Len2>
00994 ValueType<Len2> unsignedModulo(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
00995 if (a.is_known() && b.is_known() && 0!=b.known_value())
00996 return ValueType<Len2>(a.known_value() % b.known_value())
00997 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
00998 return ValueType<Len2>(InternalNode::create(Len2, InsnSemanticsExpr::OP_UMOD,
00999 a.get_expression(), b.get_expression()))
01000 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
01001 }
01002
01004 template <size_t Len1, size_t Len2>
01005 ValueType<Len1+Len2> unsignedMultiply(const ValueType<Len1> &a, const ValueType<Len2> &b) const {
01006 if (a.is_known() && b.is_known())
01007 return ValueType<Len1+Len2>(a.known_value()*b.known_value())
01008 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
01009 return ValueType<Len1+Len2>(InternalNode::create(Len1+Len2, InsnSemanticsExpr::OP_UMUL,
01010 a.get_expression(), b.get_expression()))
01011 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
01012 }
01013
01015 template <size_t Len>
01016 ValueType<Len> xor_(const ValueType<Len> &a, const ValueType<Len> &b) const {
01017 if (a.is_known() && b.is_known())
01018 return ValueType<Len>(a.known_value() ^ b.known_value())
01019 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
01020 if (a.get_expression()->equal_to(b.get_expression(), solver))
01021 return number<Len>(0).defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
01022 return ValueType<Len>(InternalNode::create(Len, InsnSemanticsExpr::OP_BV_XOR,
01023 a.get_expression(), b.get_expression()))
01024 .defined_by(cur_insn, a.get_defining_instructions(), b.get_defining_instructions());
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01035 template<size_t Len>
01036 ValueType<Len> readRegister(const char *regname) {
01037 return readRegister<Len>(findRegister(regname, Len));
01038 }
01039
01041 template<size_t Len>
01042 void writeRegister(const char *regname, const ValueType<Len> &value) {
01043 writeRegister<Len>(findRegister(regname, Len), value);
01044 }
01045
01047 template<size_t Len>
01048 ValueType<Len> readRegister(const RegisterDescriptor ®) {
01049 switch (Len) {
01050 case 1:
01051
01052
01053 if (reg.get_major()!=x86_regclass_flags)
01054 throw Exception("bit access only valid for FLAGS/EFLAGS register");
01055 if (reg.get_minor()!=0 || reg.get_offset()>=cur_state.n_flags)
01056 throw Exception("register not implemented in semantic policy");
01057 if (reg.get_nbits()!=1)
01058 throw Exception("semantic policy supports only single-bit flags");
01059 return unsignedExtend<1, Len>(cur_state.flag[reg.get_offset()]);
01060
01061 case 8:
01062
01063
01064 if (reg.get_major()!=x86_regclass_gpr)
01065 throw Exception("byte access only valid for general purpose registers");
01066 if (reg.get_minor()>=cur_state.n_gprs)
01067 throw Exception("register not implemented in semantic policy");
01068 assert(reg.get_nbits()==8);
01069 switch (reg.get_offset()) {
01070 case 0:
01071 return extract<0, Len>(cur_state.gpr[reg.get_minor()]);
01072 case 8:
01073 return extract<8, 8+Len>(cur_state.gpr[reg.get_minor()]);
01074 default:
01075 throw Exception("invalid one-byte access offset");
01076 }
01077
01078 case 16:
01079 if (reg.get_nbits()!=16)
01080 throw Exception("invalid 2-byte register");
01081 if (reg.get_offset()!=0)
01082 throw Exception("policy does not support non-zero offsets for word granularity register access");
01083 switch (reg.get_major()) {
01084 case x86_regclass_segment:
01085 if (reg.get_minor()>=cur_state.n_segregs)
01086 throw Exception("register not implemented in semantic policy");
01087 return unsignedExtend<16, Len>(cur_state.segreg[reg.get_minor()]);
01088 case x86_regclass_gpr:
01089 if (reg.get_minor()>=cur_state.n_gprs)
01090 throw Exception("register not implemented in semantic policy");
01091 return extract<0, Len>(cur_state.gpr[reg.get_minor()]);
01092 case x86_regclass_flags:
01093 if (reg.get_minor()!=0 || cur_state.n_flags<16)
01094 throw Exception("register not implemented in semantic policy");
01095 return unsignedExtend<16, Len>(concat(cur_state.flag[0],
01096 concat(cur_state.flag[1],
01097 concat(cur_state.flag[2],
01098 concat(cur_state.flag[3],
01099 concat(cur_state.flag[4],
01100 concat(cur_state.flag[5],
01101 concat(cur_state.flag[6],
01102 concat(cur_state.flag[7],
01103 concat(cur_state.flag[8],
01104 concat(cur_state.flag[9],
01105 concat(cur_state.flag[10],
01106 concat(cur_state.flag[11],
01107 concat(cur_state.flag[12],
01108 concat(cur_state.flag[13],
01109 concat(cur_state.flag[14],
01110 cur_state.flag[15]))))))))))))))));
01111 default:
01112 throw Exception("word access not valid for this register type");
01113 }
01114
01115 case 32:
01116 if (reg.get_offset()!=0)
01117 throw Exception("policy does not support non-zero offsets for double word granularity"
01118 " register access");
01119 switch (reg.get_major()) {
01120 case x86_regclass_gpr:
01121 if (reg.get_minor()>=cur_state.n_gprs)
01122 throw Exception("register not implemented in semantic policy");
01123 return unsignedExtend<32, Len>(cur_state.gpr[reg.get_minor()]);
01124 case x86_regclass_ip:
01125 if (reg.get_minor()!=0)
01126 throw Exception("register not implemented in semantic policy");
01127 return unsignedExtend<32, Len>(cur_state.ip);
01128 case x86_regclass_segment:
01129 if (reg.get_minor()>=cur_state.n_segregs || reg.get_nbits()!=16)
01130 throw Exception("register not implemented in semantic policy");
01131 return unsignedExtend<16, Len>(cur_state.segreg[reg.get_minor()]);
01132 case x86_regclass_flags: {
01133 if (reg.get_minor()!=0 || cur_state.n_flags<32)
01134 throw Exception("register not implemented in semantic policy");
01135 if (reg.get_nbits()!=32)
01136 throw Exception("register is not 32 bits");
01137 return unsignedExtend<32, Len>(concat(readRegister<16>("flags"),
01138 concat(cur_state.flag[16],
01139 concat(cur_state.flag[17],
01140 concat(cur_state.flag[18],
01141 concat(cur_state.flag[19],
01142 concat(cur_state.flag[20],
01143 concat(cur_state.flag[21],
01144 concat(cur_state.flag[22],
01145 concat(cur_state.flag[23],
01146 concat(cur_state.flag[24],
01147 concat(cur_state.flag[25],
01148 concat(cur_state.flag[26],
01149 concat(cur_state.flag[27],
01150 concat(cur_state.flag[28],
01151 concat(cur_state.flag[29],
01152 concat(cur_state.flag[30],
01153 cur_state.flag[31])))))))))))))))));
01154 }
01155 default:
01156 throw Exception("double word access not valid for this register type");
01157 }
01158
01159 default:
01160 throw Exception("invalid register access width");
01161 }
01162 }
01163
01165 template<size_t Len>
01166 void writeRegister(const RegisterDescriptor ®, const ValueType<Len> &value) {
01167 switch (Len) {
01168 case 1:
01169
01170
01171 if (reg.get_major()!=x86_regclass_flags)
01172 throw Exception("bit access only valid for FLAGS/EFLAGS register");
01173 if (reg.get_minor()!=0 || reg.get_offset()>=cur_state.n_flags)
01174 throw Exception("register not implemented in semantic policy");
01175 if (reg.get_nbits()!=1)
01176 throw Exception("semantic policy supports only single-bit flags");
01177 cur_state.flag[reg.get_offset()] = unsignedExtend<Len, 1>(value);
01178 cur_state.flag[reg.get_offset()].defined_by(cur_insn);
01179 break;
01180
01181 case 8:
01182
01183 if (reg.get_major()!=x86_regclass_gpr)
01184 throw Exception("byte access only valid for general purpose registers.");
01185 if (reg.get_minor()>=cur_state.n_gprs)
01186 throw Exception("register not implemented in semantic policy");
01187 assert(reg.get_nbits()==8);
01188 switch (reg.get_offset()) {
01189 case 0:
01190 cur_state.gpr[reg.get_minor()] =
01191 concat(signExtend<Len, 8>(value), extract<8, 32>(cur_state.gpr[reg.get_minor()]));
01192 cur_state.gpr[reg.get_minor()].defined_by(cur_insn);
01193 break;
01194 case 8:
01195 cur_state.gpr[reg.get_minor()] =
01196 concat(extract<0, 8>(cur_state.gpr[reg.get_minor()]),
01197 concat(unsignedExtend<Len, 8>(value),
01198 extract<16, 32>(cur_state.gpr[reg.get_minor()])));
01199 cur_state.gpr[reg.get_minor()].defined_by(cur_insn);
01200 break;
01201 default:
01202 throw Exception("invalid byte access offset");
01203 }
01204 break;
01205
01206 case 16:
01207 if (reg.get_nbits()!=16)
01208 throw Exception("invalid 2-byte register");
01209 if (reg.get_offset()!=0)
01210 throw Exception("policy does not support non-zero offsets for word granularity register access");
01211 switch (reg.get_major()) {
01212 case x86_regclass_segment:
01213 if (reg.get_minor()>=cur_state.n_segregs)
01214 throw Exception("register not implemented in semantic policy");
01215 cur_state.segreg[reg.get_minor()] = unsignedExtend<Len, 16>(value);
01216 cur_state.segreg[reg.get_minor()].defined_by(cur_insn);
01217 break;
01218 case x86_regclass_gpr:
01219 if (reg.get_minor()>=cur_state.n_gprs)
01220 throw Exception("register not implemented in semantic policy");
01221 cur_state.gpr[reg.get_minor()] =
01222 concat(unsignedExtend<Len, 16>(value),
01223 extract<16, 32>(cur_state.gpr[reg.get_minor()]));
01224 cur_state.gpr[reg.get_minor()].defined_by(cur_insn);
01225 break;
01226 case x86_regclass_flags:
01227 if (reg.get_minor()!=0 || cur_state.n_flags<16)
01228 throw Exception("register not implemented in semantic policy");
01229 cur_state.flag[0] = extract<0, 1 >(value); cur_state.flag[0].defined_by(cur_insn);
01230 cur_state.flag[1] = extract<1, 2 >(value); cur_state.flag[1].defined_by(cur_insn);
01231 cur_state.flag[2] = extract<2, 3 >(value); cur_state.flag[2].defined_by(cur_insn);
01232 cur_state.flag[3] = extract<3, 4 >(value); cur_state.flag[3].defined_by(cur_insn);
01233 cur_state.flag[4] = extract<4, 5 >(value); cur_state.flag[4].defined_by(cur_insn);
01234 cur_state.flag[5] = extract<5, 6 >(value); cur_state.flag[5].defined_by(cur_insn);
01235 cur_state.flag[6] = extract<6, 7 >(value); cur_state.flag[6].defined_by(cur_insn);
01236 cur_state.flag[7] = extract<7, 8 >(value); cur_state.flag[7].defined_by(cur_insn);
01237 cur_state.flag[8] = extract<8, 9 >(value); cur_state.flag[8].defined_by(cur_insn);
01238 cur_state.flag[9] = extract<9, 10>(value); cur_state.flag[9].defined_by(cur_insn);
01239 cur_state.flag[10] = extract<10, 11>(value); cur_state.flag[10].defined_by(cur_insn);
01240 cur_state.flag[11] = extract<11, 12>(value); cur_state.flag[11].defined_by(cur_insn);
01241 cur_state.flag[12] = extract<12, 13>(value); cur_state.flag[12].defined_by(cur_insn);
01242 cur_state.flag[13] = extract<13, 14>(value); cur_state.flag[13].defined_by(cur_insn);
01243 cur_state.flag[14] = extract<14, 15>(value); cur_state.flag[14].defined_by(cur_insn);
01244 cur_state.flag[15] = extract<15, 16>(value); cur_state.flag[15].defined_by(cur_insn);
01245 break;
01246 default:
01247 throw Exception("word access not valid for this register type");
01248 }
01249 break;
01250
01251 case 32:
01252 if (reg.get_offset()!=0)
01253 throw Exception("policy does not support non-zero offsets for double word granularity"
01254 " register access");
01255 switch (reg.get_major()) {
01256 case x86_regclass_gpr:
01257 if (reg.get_minor()>=cur_state.n_gprs)
01258 throw Exception("register not implemented in semantic policy");
01259 cur_state.gpr[reg.get_minor()] = signExtend<Len, 32>(value);
01260 cur_state.gpr[reg.get_minor()].defined_by(cur_insn);
01261 break;
01262 case x86_regclass_ip:
01263 if (reg.get_minor()!=0)
01264 throw Exception("register not implemented in semantic policy");
01265 cur_state.ip = unsignedExtend<Len, 32>(value);
01266 cur_state.ip.defined_by(cur_insn);
01267 break;
01268 case x86_regclass_flags:
01269 if (reg.get_minor()!=0 || cur_state.n_flags<32)
01270 throw Exception("register not implemented in semantic policy");
01271 if (reg.get_nbits()!=32)
01272 throw Exception("register is not 32 bits");
01273 writeRegister<16>("flags", unsignedExtend<Len, 16>(value));
01274 cur_state.flag[16] = extract<16, 17>(value); cur_state.flag[16].defined_by(cur_insn);
01275 cur_state.flag[17] = extract<17, 18>(value); cur_state.flag[17].defined_by(cur_insn);
01276 cur_state.flag[18] = extract<18, 19>(value); cur_state.flag[18].defined_by(cur_insn);
01277 cur_state.flag[19] = extract<19, 20>(value); cur_state.flag[19].defined_by(cur_insn);
01278 cur_state.flag[20] = extract<20, 21>(value); cur_state.flag[20].defined_by(cur_insn);
01279 cur_state.flag[21] = extract<21, 22>(value); cur_state.flag[21].defined_by(cur_insn);
01280 cur_state.flag[22] = extract<22, 23>(value); cur_state.flag[22].defined_by(cur_insn);
01281 cur_state.flag[23] = extract<23, 24>(value); cur_state.flag[23].defined_by(cur_insn);
01282 cur_state.flag[24] = extract<24, 25>(value); cur_state.flag[24].defined_by(cur_insn);
01283 cur_state.flag[25] = extract<25, 26>(value); cur_state.flag[25].defined_by(cur_insn);
01284 cur_state.flag[26] = extract<26, 27>(value); cur_state.flag[26].defined_by(cur_insn);
01285 cur_state.flag[27] = extract<27, 28>(value); cur_state.flag[27].defined_by(cur_insn);
01286 cur_state.flag[28] = extract<28, 29>(value); cur_state.flag[28].defined_by(cur_insn);
01287 cur_state.flag[29] = extract<29, 30>(value); cur_state.flag[29].defined_by(cur_insn);
01288 cur_state.flag[30] = extract<30, 31>(value); cur_state.flag[30].defined_by(cur_insn);
01289 cur_state.flag[31] = extract<31, 32>(value); cur_state.flag[31].defined_by(cur_insn);
01290 break;
01291 default:
01292 throw Exception("double word access not valid for this register type");
01293 }
01294 break;
01295
01296 default:
01297 throw Exception("invalid register access width");
01298 }
01299 }
01300
01302 template <size_t Len> ValueType<Len>
01303 readMemory(X86SegmentRegister segreg, const ValueType<32> &addr, const ValueType<1> &cond) const {
01304 return mem_read<Len>(cur_state, addr, ValueType<Len>());
01305 }
01306
01308 template <size_t Len> void
01309 writeMemory(X86SegmentRegister segreg, const ValueType<32> &addr, const ValueType<Len> &data,
01310 const ValueType<1> &cond) {
01311 mem_write<Len>(cur_state, addr, data);
01312 }
01313 };
01314 }
01315 }
01316 }
01317
01318 #endif