SymbolicSemantics.h

Go to the documentation of this file.
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 {              // documented elsewhere
00018     namespace InstructionSemantics {    // documented elsewhere
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              *                          ValueType
00048              ******************************************************************************************************************/
00049 
00050             /* ValueType cannot directly be a TreeNode because ValueType's bit size is a template argument while tree node
00051              * sizes are stored as a data member.  Therefore, ValueType will always point to a TreeNode.  Most of the methods
00052              * that are invoked on ValueType just call the same methods for TreeNode. */
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              *                          MemoryCell
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); /*this might be faster to solve*/
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                     /*FIXME: not implemented yet. [RPM 2010-05-24]*/
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                     /* So that named values are identical in both; reinitialized by first call to startInstruction(). */
00354                     orig_state = cur_state;
00355                 }
00356 
00358                 Policy(SMTSolver *solver) {
00359                     init();
00360                     this->solver = solver;
00361                     /* So that named values are identical in both; reinitialized by first call to startInstruction(). */
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                         // no-op, so not defined by current insn
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                         // no-op, so not defined by current insns
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/*no defining instruction*/);
00527                     bool aliased = false; /*is new_cell aliased by any existing writes?*/
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                         /* We didn't find the memory cell in the specified state and it's not aliased to any writes in that
00545                          * state.  Therefore use the value from the initial memory state (creating it if necessary). */
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                     /* Create the cell in the current state. */
00559                     state.mem.push_back(new_cell);
00560                     return unsignedExtend<32,Len>(new_cell.get_data()); // no defining instruction
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 /*FIXME: not implemented yet [RPM 2010-05-24]*/
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; /* has new_cell been saved into memory? */
00592 
00593                     /* Is new memory reference through the stack pointer or frame pointer? */
00594                     MemRefType new_mrt = memory_reference_type(state, addr);
00595 
00596                     /* Overwrite and/or clobber existing memory locations. */
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                             /* Assume that memory referenced through the stack pointer does not alias that which is referenced
00603                              * through the frame pointer, and neither of them alias memory that is referenced other ways. */
00604                         } else if (new_cell.may_alias(*mi, solver)) {
00605                             (*mi).set_clobbered();
00606                         } else {
00607                             /* memory cell *mi is not aliased to cell being written */
00608                         }
00609                     }
00610                     if (!saved)
00611                         state.mem.push_back(new_cell);
00612                 }
00613 
00614 
00615                 /*************************************************************************************************************
00616                  * Functions invoked by the X86InstructionSemantics class for every processed instructions
00617                  *************************************************************************************************************/
00618 
00620                 void startInstruction(SgAsmInstruction *insn) {
00621                     if (!cur_state.ip.is_known()) {
00622                         cur_state.ip = ValueType<32>(insn->get_address()); // semantics user should have probably initialized EIP
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()); // redundant, used for error mesg
00638                         abort(); // we must fail even when optimized
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                  * Functions invoked by the X86InstructionSemantics class to construct values
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                  * Functions invoked by the X86InstructionSemantics class for individual instructions
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() {} // FIXME
00702 
00704                 void cpuid() {} // FIXME
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>(); /*reset entire machine state*/
00714                 }
00715 
00717                 void sysenter() {
00718                     cur_state = State<ValueType>(); /*reset entire machine state*/
00719                 }
00720 
00721 
00722 
00723                 /*****************************************************************************************************************
00724                  * Functions invoked by the X86InstructionSemantics class for arithmetic operations
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                         /* If the selection expression cannot be true, then return ifFalse */
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                         /* If the selection expression cannot be false, then return ifTrue */
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                  * Functions invoked by the X86InstructionSemantics class for data access operations
01031                  *****************************************************************************************************************/
01032 
01033 
01035                 template<size_t Len/*bits*/>
01036                 ValueType<Len> readRegister(const char *regname) {
01037                     return readRegister<Len>(findRegister(regname, Len));
01038                 }
01039 
01041                 template<size_t Len/*bits*/>
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 &reg) {
01049                     switch (Len) {
01050                         case 1:
01051                             // Only FLAGS/EFLAGS bits have a size of one.  Other registers cannot be accessed at this
01052                             // granularity.
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                             // Only general-purpose registers can be accessed at a byte granularity, and we can access only the
01063                             // low-order byte or the next higher byte.  For instance, "al" and "ah" registers.
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); // we had better be asking for a one-byte register (e.g., "ah", not "ax")
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"), // no-op sign extension
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 &reg, const ValueType<Len> &value) {
01167                     switch (Len) {
01168                         case 1:
01169                             // Only FLAGS/EFLAGS bits have a size of one.  Other registers cannot be accessed at this
01170                             // granularity.
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                             // Only general purpose registers can be accessed at byte granularity, and only for offsets 0 and 8.
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); // we had better be asking for a one-byte register (e.g., "ah", not "ax")
01188                             switch (reg.get_offset()) {
01189                                 case 0:
01190                                     cur_state.gpr[reg.get_minor()] =                                    // no-op extend
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         } /*namespace*/
01315     } /*namespace*/
01316 } /*namespace*/
01317 
01318 #endif

Generated on Wed May 16 06:18:11 2012 for ROSE by  doxygen 1.4.7