ROSE  0.9.9.199
BaseSemantics2.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics2_BaseSemantics_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics2_BaseSemantics_H
3 
4 #include "BinarySmtSolver.h"
5 #include "Diagnostics.h"
6 #include "Registers.h"
7 #include "FormatRestorer.h"
8 
9 #include <boost/shared_ptr.hpp>
10 #include <boost/enable_shared_from_this.hpp>
11 #include <boost/optional.hpp>
12 #include <boost/serialization/access.hpp>
13 #ifndef USE_ROSE // [Robb P Matzke 2016-11-11]: ROSE cannot compile this header
14 #include <boost/serialization/shared_ptr.hpp>
15 #endif
16 #include <boost/serialization/string.hpp>
17 #include <Sawyer/Assert.h>
18 #include <Sawyer/IntervalMap.h>
19 #include <Sawyer/IntervalSetMap.h>
20 #include <Sawyer/Map.h>
21 #include <Sawyer/Optional.h>
22 #include <Sawyer/Set.h>
23 
24 namespace Rose {
25 namespace BinaryAnalysis {
26 
336 namespace InstructionSemantics2 {
337 
340 
342 void initDiagnostics();
343 
346 namespace BaseSemantics {
347 
348 class RiscOperators;
349 
353 class Formatter {
354 public:
355  Formatter(): regdict(NULL), suppress_initial_values(false), indentation_suffix(" "), show_latest_writers(true),
356  show_properties(true) {}
357  virtual ~Formatter() {}
358 
361  RegisterDictionary *get_register_dictionary() const { return regdict; }
362  void set_register_dictionary(RegisterDictionary *rd) { regdict = rd; }
368  bool get_suppress_initial_values() const { return suppress_initial_values; }
369  void set_suppress_initial_values(bool b=true) { suppress_initial_values=b; }
375  std::string get_line_prefix() const { return line_prefix; }
376  void set_line_prefix(const std::string &s) { line_prefix = s; }
381  std::string get_indentation_suffix() const { return indentation_suffix; }
382  void set_indentation_suffix(const std::string &s) { indentation_suffix = s; }
387  bool get_show_latest_writers() const { return show_latest_writers; }
388  void set_show_latest_writers(bool b=true) { show_latest_writers = b; }
389  void clear_show_latest_writers() { show_latest_writers = false; }
394  bool get_show_properties() const { return show_properties; }
395  void set_show_properties(bool b=true) { show_properties = b; }
396  void clear_show_properties() { show_properties = false; }
399 protected:
400  RegisterDictionary *regdict;
401  bool suppress_initial_values;
402  std::string line_prefix;
403  std::string indentation_suffix;
404  bool show_latest_writers;
405  bool show_properties;
406 };
407 
411 class Indent {
412 private:
413  Formatter &fmt;
414  std::string old_line_prefix;
415 public:
416  Indent(Formatter &fmt): fmt(fmt) {
417  old_line_prefix = fmt.get_line_prefix();
418  fmt.set_line_prefix(old_line_prefix + fmt.get_indentation_suffix());
419  }
420  ~Indent() {
421  fmt.set_line_prefix(old_line_prefix);
422  }
423 };
424 
444 };
445 
448 
449 
450 
452 // Exceptions
454 
456 class Exception: public std::runtime_error {
457 public:
458  SgAsmInstruction *insn;
459  Exception(const std::string &mesg, SgAsmInstruction *insn): std::runtime_error(mesg), insn(insn) {}
460  void print(std::ostream&) const;
461 };
462 
463 class NotImplemented: public Exception {
464 public:
465  NotImplemented(const std::string &mesg, SgAsmInstruction *insn)
466  : Exception(mesg, insn) {}
467 };
468 
469 
470 
472 // Merging states
474 
477 
495 protected:
496  Merger() {}
497 
498 public:
500  typedef MergerPtr Ptr;
501 
503  static Ptr instance() {
504  return Ptr(new Merger);
505  }
506 };
507 
509 // Semantic Values
511 
512 // This is leftover for compatibility with an older API. The old API had code like this:
513 // User::SValue user_svalue = BaseSemantics::dynamic_pointer_cast<User::SValue>(base_svalue);
514 // Which can be replaced now with
515 // User::SValue user_svalue = base_svalue.dynamicCast<User::SValue>();
516 template<class To, class From>
517 Sawyer::SharedPointer<To> dynamic_pointer_cast(const Sawyer::SharedPointer<From> &from) {
518  return from.template dynamicCast<To>();
519 }
520 
523 
539 protected:
540  size_t width;
542  // Serialization
544 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
545 private:
546  friend class boost::serialization::access;
547 
548  template<class S>
549  void serialize(S &s, const unsigned version) {
550  s & BOOST_SERIALIZATION_NVP(width);
551  }
552 #endif
553 
555  // Normal, protected, C++ constructors
556 protected:
557  SValue(): width(0) {} // needed for serialization
558  explicit SValue(size_t nbits): width(nbits) {} // hot
559  SValue(const SValue &other): width(other.width) {}
560 
561 public:
563  typedef SValuePtr Ptr;
564 
565 public:
566  virtual ~SValue() {}
567 
569  // Allocating static constructor. None are needed--this class is abstract.
570 
572  // Allocating virtual constructors. undefined_() needs underscores, so we do so consistently for all
573  // these allocating virtual c'tors. However, we use copy() rather than copy_() because this one is fundamentally
574  // different: the object (this) is use for more than just selecting which virtual method to invoke.
575  //
576  // The naming scheme we use here is a bit different than for most other objects for historical reasons. Most other classes
577  // use "create" and "clone" as the virtual constructor names, but SValue uses names ending in undercore, and "copy". The
578  // other difference (at least in this base class) is that we don't define any real constructors or static allocating
579  // constructors (usually named "instance")--it's because this is an abstract class.
580 public:
586  virtual SValuePtr undefined_(size_t nbits) const = 0; // hot
587 
596  virtual SValuePtr unspecified_(size_t nbits) const = 0;
597 
603  virtual SValuePtr bottom_(size_t nBits) const = 0;
604 
608  virtual SValuePtr number_(size_t nbits, uint64_t number) const = 0; // hot
609 
613  virtual SValuePtr boolean_(bool value) const { return number_(1, value?1:0); }
614 
618  virtual SValuePtr copy(size_t new_width=0) const = 0;
619 
647  createOptionalMerge(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const = 0;
648 
655  SValuePtr createMerged(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const /*final*/ {
656  return createOptionalMerge(other, merger, solver).orElse(copy());
657  }
658 
660  // Dynamic pointer casts. No-ops since this is the base class
661 public:
662  static SValuePtr promote(const SValuePtr &x) {
663  ASSERT_not_null(x);
664  return x;
665  }
666 
668  // The rest of the API...
669 public:
675  virtual bool isBottom() const = 0;
676 
679  virtual bool is_number() const = 0;
680 
683  virtual uint64_t get_number() const = 0;
684 
687  virtual size_t get_width() const { return width; }
688  virtual void set_width(size_t nbits) { width = nbits; }
692  virtual bool may_equal(const SValuePtr &other, const SmtSolverPtr &solver = SmtSolverPtr()) const = 0;
693 
695  virtual bool must_equal(const SValuePtr &other, const SmtSolverPtr &solver = SmtSolverPtr()) const = 0;
696 
699  bool isTrue() const {
700  return is_number() && get_number()!=0;
701  }
702 
705  bool isFalse() const {
706  return is_number() && get_number()==0;
707  }
708 
712  void print(std::ostream &stream) const { Formatter fmt; print(stream, fmt); }
713  virtual void print(std::ostream&, Formatter&) const = 0;
718  SValuePtr obj;
719  Formatter &fmt;
720  public:
721  WithFormatter(const SValuePtr &svalue, Formatter &fmt): obj(svalue), fmt(fmt) {}
722  void print(std::ostream &stream) const { obj->print(stream, fmt); }
723  };
724 
741  virtual std::string get_comment() const { return ""; }
742  virtual void set_comment(const std::string&) const {} // const is intended; cf. doxygen comment
744 };
745 
746 
747 
749 // Register States
751 
753 typedef boost::shared_ptr<class RegisterState> RegisterStatePtr;
754 
758 class RegisterState: public boost::enable_shared_from_this<RegisterState> {
759 private:
760  MergerPtr merger_;
761  SValuePtr protoval_;
763 protected:
766  // Serialization
768 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
769 private:
770  friend class boost::serialization::access;
771 
772  template<class S>
773  void serialize(S &s, const unsigned version) {
774  //s & merger_; -- not saved
775  s & BOOST_SERIALIZATION_NVP(protoval_);
776  }
777 #endif
778 
779 
781  // Real constructors
782 protected:
783  RegisterState() {} // for serialization
784 
785  RegisterState(const SValuePtr &protoval, const RegisterDictionary *regdict)
786  : protoval_(protoval), regdict(regdict) {
787  ASSERT_not_null(protoval_);
788  }
789 
790 public:
792  typedef RegisterStatePtr Ptr;
793 
794 public:
795  virtual ~RegisterState() {}
796 
798  // Static allocating constructors. None are needed--this class is abstract.
799 
800 
802  // Virtual constructors.
803 public:
808  virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionary *regdict) const = 0;
809 
811  virtual RegisterStatePtr clone() const = 0;
812 
814  // Dynamic pointer casts. No-op since this is the base class.
815 public:
816  static RegisterStatePtr promote(const RegisterStatePtr &x) {
817  ASSERT_not_null(x);
818  return x;
819  }
820 
821 public:
823  // The rest of the API...
824 
833  MergerPtr merger() const { return merger_; }
834  void merger(const MergerPtr &m) { merger_ = m; }
838  SValuePtr protoval() const { return protoval_; }
839 
840  // [Robb Matzke 2016-01-22]: deprecated
841  SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
842  return protoval();
843  }
844 
849  void set_register_dictionary(const RegisterDictionary *rd) { regdict = rd; }
863  virtual void clear() = 0;
864 
866  virtual void zero() = 0;
867 
871  virtual bool merge(const RegisterStatePtr &other, RiscOperators *ops) = 0;
872 
886  virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) = 0;
887 
891  virtual SValuePtr peekRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) = 0;
892 
899  virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops) = 0;
900 
903  void print(std::ostream &stream, const std::string prefix="") const {
904  Formatter fmt;
905  fmt.set_line_prefix(prefix);
906  print(stream, fmt);
907  }
908  virtual void print(std::ostream&, Formatter&) const = 0;
913  RegisterStatePtr obj;
914  Formatter &fmt;
915  public:
916  WithFormatter(const RegisterStatePtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
917  void print(std::ostream &stream) const { obj->print(stream, fmt); }
918  };
919 
927  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
931 };
932 
934 typedef boost::shared_ptr<class RegisterStateX86> RegisterStateX86Ptr;
935 
944 public:
945  static const size_t n_gprs = 8;
946  static const size_t n_segregs = 6;
947  static const size_t n_flags = 32;
948  static const size_t n_st = 8;
949  static const size_t n_xmm = 8;
951  SValuePtr ip;
952  SValuePtr gpr[n_gprs];
953  SValuePtr segreg[n_segregs];
954  SValuePtr flag[n_flags];
955  SValuePtr st[n_st];
956  SValuePtr fpstatus;
957  SValuePtr xmm[n_xmm];
959  // Real constructors
961 protected:
962  explicit RegisterStateX86(const SValuePtr &protoval, const RegisterDictionary *regdict)
963  : RegisterState(protoval, regdict) {
964  clear();
965  }
966 
967  RegisterStateX86(const RegisterStateX86 &other): RegisterState(other) {
968  ip = other.ip->copy();
969  for (size_t i=0; i<n_gprs; ++i)
970  gpr[i] = other.gpr[i]->copy();
971  for (size_t i=0; i<n_segregs; ++i)
972  segreg[i] = other.segreg[i]->copy();
973  for (size_t i=0; i<n_flags; ++i)
974  flag[i] = other.flag[i]->copy();
975  for (size_t i=0; i<n_st; ++i)
976  st[i] = other.st[i]->copy();
977  fpstatus = other.fpstatus;
978  for (size_t i=0; i<n_xmm; ++i)
979  xmm[i] = other.xmm[i]->copy();
980  }
981 
983  // Static allocating constructors
984 public:
988  static RegisterStateX86Ptr instance(const SValuePtr &protoval, const RegisterDictionary *regdict) {
989  return RegisterStateX86Ptr(new RegisterStateX86(protoval, regdict));
990  }
991 
993  static RegisterStateX86Ptr instance(const RegisterStateX86Ptr &other) {
994  return RegisterStateX86Ptr(new RegisterStateX86(*other));
995  }
996 
998  // Virtual constructors
999 public:
1000  virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionary *regdict) const ROSE_OVERRIDE {
1001  return instance(protoval, regdict);
1002  }
1003 
1004  virtual RegisterStatePtr clone() const ROSE_OVERRIDE {
1005  return RegisterStatePtr(new RegisterStateX86(*this));
1006  }
1007 
1009  // Dynamic pointer casts
1010 public:
1013  static RegisterStateX86Ptr promote(const RegisterStatePtr &from) {
1014  RegisterStateX86Ptr retval = boost::dynamic_pointer_cast<RegisterStateX86>(from);
1015  ASSERT_not_null(retval);
1016  return retval;
1017  }
1018 
1020  // Methods we inherited
1021 public:
1022  virtual void clear() ROSE_OVERRIDE;
1023  virtual void zero() ROSE_OVERRIDE;
1024  virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) ROSE_OVERRIDE;
1025  virtual SValuePtr peekRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) ROSE_OVERRIDE;
1026  virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops) ROSE_OVERRIDE;
1027  virtual void print(std::ostream&, Formatter&) const ROSE_OVERRIDE;
1028  virtual bool merge(const RegisterStatePtr &other, RiscOperators *ops) ROSE_OVERRIDE;
1029 
1031  // Methods first declared at this level of the class hierarchy
1032 protected:
1033  // helpers for readRegister()
1034  virtual SValuePtr readRegisterGpr(RegisterDescriptor reg, RiscOperators *ops);
1035  virtual SValuePtr readRegisterFlag(RegisterDescriptor reg, RiscOperators *ops);
1036  virtual SValuePtr readRegisterSeg(RegisterDescriptor reg, RiscOperators *ops);
1037  virtual SValuePtr readRegisterIp(RegisterDescriptor reg, RiscOperators *ops);
1038  virtual SValuePtr readRegisterSt(RegisterDescriptor reg, RiscOperators *ops);
1039  virtual SValuePtr readRegisterXmm(RegisterDescriptor reg, RiscOperators *ops);
1040  virtual SValuePtr readRegisterFpStatus(RegisterDescriptor reg, RiscOperators *ops);
1041 
1042  // helpers for writeRegister()
1043  virtual void writeRegisterGpr(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1044  virtual void writeRegisterFlag(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1045  virtual void writeRegisterSeg(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1046  virtual void writeRegisterIp(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1047  virtual void writeRegisterSt(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1048  virtual void writeRegisterXmm(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1049  virtual void writeRegisterFpStatus(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1050 
1051  // Generate a name for initial values.
1052  virtual std::string initialValueName(RegisterDescriptor) const;
1053 };
1054 
1055 
1056 
1058 // Memory State
1060 
1062 typedef boost::shared_ptr<class MemoryState> MemoryStatePtr;
1063 
1067 class MemoryState: public boost::enable_shared_from_this<MemoryState> {
1068  SValuePtr addrProtoval_;
1069  SValuePtr valProtoval_;
1070  ByteOrder::Endianness byteOrder_;
1071  MergerPtr merger_;
1072  bool byteRestricted_; // are cell values all exactly one byte wide?
1073 
1075  // Serialization
1076 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1077 private:
1078  friend class boost::serialization::access;
1079 
1080  template<class S>
1081  void serialize(S &s, const unsigned version) {
1082  s & BOOST_SERIALIZATION_NVP(addrProtoval_);
1083  s & BOOST_SERIALIZATION_NVP(valProtoval_);
1084  s & BOOST_SERIALIZATION_NVP(byteOrder_);
1085  //s & merger_ -- not saved
1086  s & BOOST_SERIALIZATION_NVP(byteRestricted_);
1087  }
1088 #endif
1089 
1090 
1092  // Real constructors
1093 protected:
1094  MemoryState() // for serialization
1095  : byteOrder_(ByteOrder::ORDER_UNSPECIFIED), byteRestricted_(true) {}
1096 
1097  explicit MemoryState(const SValuePtr &addrProtoval, const SValuePtr &valProtoval)
1098  : addrProtoval_(addrProtoval), valProtoval_(valProtoval), byteOrder_(ByteOrder::ORDER_UNSPECIFIED),
1099  byteRestricted_(true) {
1100  ASSERT_not_null(addrProtoval);
1101  ASSERT_not_null(valProtoval);
1102  }
1103 
1104  MemoryState(const MemoryStatePtr &other)
1105  : addrProtoval_(other->addrProtoval_), valProtoval_(other->valProtoval_), byteOrder_(ByteOrder::ORDER_UNSPECIFIED),
1106  merger_(other->merger_), byteRestricted_(other->byteRestricted_) {}
1107 
1108 public:
1110  typedef MemoryStatePtr Ptr;
1111 
1112 public:
1113  virtual ~MemoryState() {}
1114 
1116  // Static allocating constructors. None needed since this class is abstract
1117 
1119  // Virtual constructors
1120 public:
1127  virtual MemoryStatePtr create(const SValuePtr &addrProtoval, const SValuePtr &valProtoval) const = 0;
1128 
1130  virtual MemoryStatePtr clone() const = 0;
1131 
1133  // Dynamic pointer casts. No-op since this is the base class.
1134 public:
1135  static MemoryStatePtr promote(const MemoryStatePtr &x) {
1136  ASSERT_not_null(x);
1137  return x;
1138  }
1139 
1141  // Methods first declared at this level of the class hierarchy
1142 public:
1151  MergerPtr merger() const { return merger_; }
1152  void merger(const MergerPtr &m) { merger_ = m; }
1157  SValuePtr get_addr_protoval() const { return addrProtoval_; }
1158 
1161  SValuePtr get_val_protoval() const { return valProtoval_; }
1162 
1164  virtual void clear() = 0;
1165 
1173  bool byteRestricted() const { return byteRestricted_; }
1174  void byteRestricted(bool b) { byteRestricted_ = b; }
1179  ByteOrder::Endianness get_byteOrder() const { return byteOrder_; }
1180  void set_byteOrder(ByteOrder::Endianness bo) { byteOrder_ = bo; }
1186  virtual bool merge(const MemoryStatePtr &other, RiscOperators *addrOps, RiscOperators *valOps) = 0;
1187 
1207  virtual SValuePtr readMemory(const SValuePtr &address, const SValuePtr &dflt,
1208  RiscOperators *addrOps, RiscOperators *valOps) = 0;
1209 
1214  virtual SValuePtr peekMemory(const SValuePtr &address, const SValuePtr &dflt,
1215  RiscOperators *addrOps, RiscOperators *valOps) = 0;
1216 
1226  virtual void writeMemory(const SValuePtr &addr, const SValuePtr &value,
1227  RiscOperators *addrOps, RiscOperators *valOps) = 0;
1228 
1231  void print(std::ostream &stream, const std::string prefix="") const {
1232  Formatter fmt;
1233  fmt.set_line_prefix(prefix);
1234  print(stream, fmt);
1235  }
1236  virtual void print(std::ostream&, Formatter&) const = 0;
1241  MemoryStatePtr obj;
1242  Formatter &fmt;
1243  public:
1244  WithFormatter(const MemoryStatePtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
1245  void print(std::ostream &stream) const { obj->print(stream, fmt); }
1246  };
1247 
1255  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
1258 };
1259 
1260 
1261 
1263 // State
1265 
1267 typedef boost::shared_ptr<class State> StatePtr;
1268 
1285 class State: public boost::enable_shared_from_this<State> {
1286  SValuePtr protoval_; // Initial value used to create additional values as needed.
1287  RegisterStatePtr registers_; // All machine register values for this semantic state.
1288  MemoryStatePtr memory_; // All memory for this semantic state.
1289 
1291  // Serialization
1292 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1293 private:
1294  friend class boost::serialization::access;
1295 
1296  template<class S>
1297  void serialize(S &s, const unsigned version) {
1298  s & BOOST_SERIALIZATION_NVP(protoval_);
1299  s & BOOST_SERIALIZATION_NVP(registers_);
1300  s & BOOST_SERIALIZATION_NVP(memory_);
1301  }
1302 #endif
1303 
1304 
1306  // Real constructors
1307 protected:
1308  // needed for serialization
1309  State() {}
1310 
1311  State(const RegisterStatePtr &registers, const MemoryStatePtr &memory)
1312  : registers_(registers), memory_(memory) {
1313  ASSERT_not_null(registers);
1314  ASSERT_not_null(memory);
1315  protoval_ = registers->protoval();
1316  ASSERT_not_null(protoval_);
1317  }
1318 
1319  // deep-copy the registers and memory
1320  State(const State &other)
1321  : protoval_(other.protoval_) {
1322  registers_ = other.registers_->clone();
1323  memory_ = other.memory_->clone();
1324  }
1325 
1326 public:
1328  typedef StatePtr Ptr;
1329 
1330 public:
1331  virtual ~State() {}
1332 
1334  // Static allocating constructors
1335 public:
1337  static StatePtr instance(const RegisterStatePtr &registers, const MemoryStatePtr &memory) {
1338  return StatePtr(new State(registers, memory));
1339  }
1340 
1342  static StatePtr instance(const StatePtr &other) {
1343  return StatePtr(new State(*other));
1344  }
1345 
1347  // Virtual constructors
1348 public:
1350  virtual StatePtr create(const RegisterStatePtr &registers, const MemoryStatePtr &memory) const {
1351  return instance(registers, memory);
1352  }
1353 
1357  virtual StatePtr clone() const {
1358  StatePtr self = boost::const_pointer_cast<State>(shared_from_this());
1359  return instance(self);
1360  }
1361 
1363  // Dynamic pointer casts. No-op since this is the base class.
1364 public:
1365  static StatePtr promote(const StatePtr &x) {
1366  ASSERT_not_null(x);
1367  return x;
1368  }
1369 
1371  // Other methods that are part of our API. Most of these just chain to either the register state and/or the memory state.
1372 public:
1374  SValuePtr protoval() const { return protoval_; }
1375 
1376  // [Robb Matzke 2016-01-22]: deprecated
1377  SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
1378  return protoval();
1379  }
1380 
1382  virtual void clear();
1383 
1387  virtual void zero_registers();
1388 
1392  virtual void clear_memory();
1393 
1397  RegisterStatePtr registerState() const {
1398  return registers_;
1399  }
1400 
1401  // [Robb Matzke 2016-01-22]: deprecated
1402  RegisterStatePtr get_register_state() ROSE_DEPRECATED("use registerState instead") {
1403  return registerState();
1404  }
1405 
1410  return memory_;
1411  }
1412 
1413  // [Robb Matzke 2016-01-22]: deprecated
1414  MemoryStatePtr get_memory_state() ROSE_DEPRECATED("use memoryState instead") {
1415  return memoryState();
1416  }
1417 
1422  virtual SValuePtr readRegister(RegisterDescriptor desc, const SValuePtr &dflt, RiscOperators *ops);
1423 
1428  virtual SValuePtr peekRegister(RegisterDescriptor desc, const SValuePtr &dflt, RiscOperators *ops);
1429 
1434  virtual void writeRegister(RegisterDescriptor desc, const SValuePtr &value, RiscOperators *ops);
1435 
1440  virtual SValuePtr readMemory(const SValuePtr &address, const SValuePtr &dflt,
1441  RiscOperators *addrOps, RiscOperators *valOps);
1442 
1447  virtual SValuePtr peekMemory(const SValuePtr &address, const SValuePtr &dflt,
1448  RiscOperators *addrOps, RiscOperators *valOps);
1449 
1454  virtual void writeMemory(const SValuePtr &addr, const SValuePtr &value, RiscOperators *addrOps, RiscOperators *valOps);
1455 
1461  void printRegisters(std::ostream &stream, const std::string &prefix = "");
1462  virtual void printRegisters(std::ostream &stream, Formatter &fmt) const;
1465  // [Robb Matzke 2015-11-16]: deprecated
1466  void print_registers(std::ostream &stream, const std::string &prefix = "") ROSE_DEPRECATED("use printRegisters instead") {
1467  printRegisters(stream, prefix);
1468  }
1469 
1470  // [Robb Matzke 2015-11-16]: deprecated
1471  virtual void print_registers(std::ostream &stream, Formatter &fmt) const ROSE_DEPRECATED("use printRegisters instead") {
1472  printRegisters(stream, fmt);
1473  }
1474 
1480  void printMemory(std::ostream &stream, const std::string &prefix = "") const;
1481  virtual void printMemory(std::ostream &stream, Formatter &fmt) const;
1484  // [Robb Matzke 2015-11-16]: deprecated
1485  void print_memory(std::ostream &stream, const std::string prefix = "") const ROSE_DEPRECATED("use printMemory instead") {
1486  printMemory(stream, prefix);
1487  }
1488 
1489  // [Robb Matzke 2015-11-16]: deprecated
1490  virtual void print_memory(std::ostream &stream, Formatter &fmt) const ROSE_DEPRECATED("use printMemory instead") {
1491  printMemory(stream, fmt);
1492  }
1493 
1496  void print(std::ostream &stream, const std::string &prefix = "") const;
1497  virtual void print(std::ostream&, Formatter&) const;
1502  StatePtr obj;
1503  Formatter &fmt;
1504  public:
1505  WithFormatter(const StatePtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
1506  void print(std::ostream &stream) const { obj->print(stream, fmt); }
1507  };
1508 
1516  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
1525  virtual bool merge(const StatePtr &other, RiscOperators *ops);
1526 };
1527 
1528 
1529 
1531 // RISC Operators
1533 
1535 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
1536 
1557 class RiscOperators: public boost::enable_shared_from_this<RiscOperators> {
1558  SValuePtr protoval_; // Prototypical value used for its virtual constructors
1559  StatePtr currentState_; // State upon which RISC operators operate
1560  StatePtr initialState_; // Lazily updated initial state; see readMemory
1561  SmtSolverPtr solver_; // Optional SMT solver
1562  SgAsmInstruction *currentInsn_; // Current instruction, as set by latest startInstruction call
1563  size_t nInsns_; // Number of instructions processed
1564  std::string name_; // Name to use for debugging
1565 
1567  // Serialization
1568 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1569 private:
1570  friend class boost::serialization::access;
1571 
1572  template<class S>
1573  void serialize(S &s, const unsigned version) {
1574  s & BOOST_SERIALIZATION_NVP(protoval_);
1575  s & BOOST_SERIALIZATION_NVP(currentState_);
1576  s & BOOST_SERIALIZATION_NVP(initialState_);
1577  s & BOOST_SERIALIZATION_NVP(solver_);
1578  s & BOOST_SERIALIZATION_NVP(currentInsn_);
1579  s & BOOST_SERIALIZATION_NVP(nInsns_);
1580  s & BOOST_SERIALIZATION_NVP(name_);
1581  }
1582 #endif
1583 
1585  // Real constructors
1586 protected:
1587  // for serialization
1588  RiscOperators()
1589  : currentInsn_(NULL), nInsns_(0) {}
1590 
1591  explicit RiscOperators(const SValuePtr &protoval, const SmtSolverPtr &solver = SmtSolverPtr())
1592  : protoval_(protoval), solver_(solver), currentInsn_(NULL), nInsns_(0) {
1593  ASSERT_not_null(protoval_);
1594  }
1595 
1596  explicit RiscOperators(const StatePtr &state, const SmtSolverPtr &solver = SmtSolverPtr())
1597  : currentState_(state), solver_(solver), currentInsn_(NULL), nInsns_(0) {
1598  ASSERT_not_null(state);
1599  protoval_ = state->protoval();
1600  }
1601 
1602 public:
1604  typedef RiscOperatorsPtr Ptr;
1605 
1606 public:
1607  virtual ~RiscOperators() {}
1608 
1610  // Static allocating constructors. None needed since this class is abstract.
1611 
1612 
1614  // Virtual constructors.
1615 public:
1619  virtual RiscOperatorsPtr create(const SValuePtr &protoval, const SmtSolverPtr &solver = SmtSolverPtr()) const = 0;
1620 
1625  virtual RiscOperatorsPtr create(const StatePtr &state, const SmtSolverPtr &solver = SmtSolverPtr()) const = 0;
1626 
1628  // Dynamic pointer casts. No-op since this is the base class.
1629 public:
1630  static RiscOperatorsPtr promote(const RiscOperatorsPtr &x) {
1631  ASSERT_not_null(x);
1632  return x;
1633  }
1634 
1636  // Other methods part of our API
1637 public:
1641  virtual SValuePtr protoval() const { return protoval_; }
1642 
1643  // [Robb Matzke 2016-01-22]: deprecated
1644  virtual SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
1645  return protoval();
1646  }
1647 
1656  virtual SmtSolverPtr solver() const { return solver_; }
1657  virtual void solver(const SmtSolverPtr &s) { solver_ = s; }
1671  virtual StatePtr currentState() const { return currentState_; }
1672  virtual void currentState(const StatePtr &s) { currentState_ = s; }
1675  // [Robb Matzke 2016-01-22]: deprecated
1676  virtual StatePtr get_state() const ROSE_DEPRECATED("use currentState instead") {
1677  return currentState();
1678  }
1679 
1680  // [Robb Matzke 2016-01-22]: deprecated
1681  virtual void set_state(const StatePtr &s) ROSE_DEPRECATED("use currentState instead") {
1682  currentState(s);
1683  }
1684 
1722  virtual StatePtr initialState() const { return initialState_; }
1723  virtual void initialState(const StatePtr &s) { initialState_ = s; }
1731  virtual const std::string& name() const { return name_; }
1732  virtual void name(const std::string &s) { name_ = s; }
1735  // [Robb Matzke 2016-01-22]: deprecated
1736  virtual const std::string& get_name() const ROSE_DEPRECATED("use name instead") { return name(); }
1737  virtual void set_name(const std::string &s) ROSE_DEPRECATED("use name instead") { name(s); }
1738 
1741  void print(std::ostream &stream, const std::string prefix="") const {
1742  Formatter fmt;
1743  fmt.set_line_prefix(prefix);
1744  print(stream, fmt);
1745  }
1746  virtual void print(std::ostream &stream, Formatter &fmt) const {
1747  currentState_->print(stream, fmt);
1748  }
1753  RiscOperatorsPtr obj;
1754  Formatter &fmt;
1755  public:
1756  WithFormatter(const RiscOperatorsPtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
1757  void print(std::ostream &stream) const { obj->print(stream, fmt); }
1758  };
1759 
1767  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
1776  virtual size_t nInsns() const { return nInsns_; }
1777  virtual void nInsns(size_t n) { nInsns_ = n; }
1780  // [Robb Matzke 2016-01-22]: deprecated
1781  virtual size_t get_ninsns() const ROSE_DEPRECATED("use nInsns instead") { return nInsns(); }
1782  virtual void set_ninsns(size_t n) ROSE_DEPRECATED("use nInsns instead") { nInsns(n); }
1783 
1789  return currentInsn_;
1790  }
1791 
1792  // [Robb Matzke 2016-01-22]: deprecated
1793  virtual SgAsmInstruction *get_insn() const ROSE_DEPRECATED("use currentInstruction instead") {
1794  return currentInstruction();
1795  }
1796 
1799  virtual void startInstruction(SgAsmInstruction *insn);
1800 
1803  virtual void finishInstruction(SgAsmInstruction *insn) {
1804  ASSERT_not_null(insn);
1805  ASSERT_require(currentInsn_==insn);
1806  currentInsn_ = NULL;
1807  };
1808 
1809 
1811  // Value Construction Operations
1813  // The trailing underscores are necessary for for undefined_() on some machines, so we just add one to the end of all the
1814  // virtual constructors for consistency.
1815 
1817  virtual SValuePtr undefined_(size_t nbits) {
1818  return protoval_->undefined_(nbits);
1819  }
1820  virtual SValuePtr unspecified_(size_t nbits) {
1821  return protoval_->unspecified_(nbits);
1822  }
1823 
1825  virtual SValuePtr number_(size_t nbits, uint64_t value) {
1826  return protoval_->number_(nbits, value);
1827  }
1828 
1830  virtual SValuePtr boolean_(bool value) {
1831  return protoval_->boolean_(value);
1832  }
1833 
1835  virtual SValuePtr bottom_(size_t nbits) {
1836  return protoval_->bottom_(nbits);
1837  }
1838 
1839 
1841  // x86-specific Operations (FIXME)
1843 
1846  virtual SValuePtr filterCallTarget(const SValuePtr &a) {
1847  return a->copy();
1848  }
1849 
1853  virtual SValuePtr filterReturnTarget(const SValuePtr &a) {
1854  return a->copy();
1855  }
1856 
1860  virtual SValuePtr filterIndirectJumpTarget(const SValuePtr &a) {
1861  return a->copy();
1862  }
1863 
1865  virtual void hlt() {}
1866 
1868  virtual void cpuid() {}
1869 
1871  virtual SValuePtr rdtsc() { return unspecified_(64); }
1872 
1873 
1875  // Boolean Operations
1877 
1880  virtual SValuePtr and_(const SValuePtr &a, const SValuePtr &b) = 0;
1881 
1884  virtual SValuePtr or_(const SValuePtr &a, const SValuePtr &b) = 0;
1885 
1888  virtual SValuePtr xor_(const SValuePtr &a, const SValuePtr &b) = 0;
1889 
1891  virtual SValuePtr invert(const SValuePtr &a) = 0;
1892 
1896  virtual SValuePtr extract(const SValuePtr &a, size_t begin_bit, size_t end_bit) = 0;
1897 
1901  virtual SValuePtr concat(const SValuePtr &a, const SValuePtr &b) = 0;
1902 
1905  virtual SValuePtr leastSignificantSetBit(const SValuePtr &a) = 0;
1906 
1909  virtual SValuePtr mostSignificantSetBit(const SValuePtr &a) = 0;
1910 
1914  virtual SValuePtr rotateLeft(const SValuePtr &a, const SValuePtr &nbits) = 0;
1915 
1919  virtual SValuePtr rotateRight(const SValuePtr &a, const SValuePtr &nbits) = 0;
1920 
1924  virtual SValuePtr shiftLeft(const SValuePtr &a, const SValuePtr &nbits) = 0;
1925 
1929  virtual SValuePtr shiftRight(const SValuePtr &a, const SValuePtr &nbits) = 0;
1930 
1935  virtual SValuePtr shiftRightArithmetic(const SValuePtr &a, const SValuePtr &nbits) = 0;
1936 
1937 
1939  // Comparison Operations
1941 
1944  virtual SValuePtr equalToZero(const SValuePtr &a) = 0;
1945 
1949  virtual SValuePtr ite(const SValuePtr &cond, const SValuePtr &a, const SValuePtr &b) = 0;
1950 
1957  SValuePtr equal(const SValuePtr &a, const SValuePtr &b) ROSE_DEPRECATED("use isEqual instead");
1958  virtual SValuePtr isEqual(const SValuePtr &a, const SValuePtr &b);
1959  virtual SValuePtr isNotEqual(const SValuePtr &a, const SValuePtr &b);
1969  virtual SValuePtr isUnsignedLessThan(const SValuePtr &a, const SValuePtr &b);
1970  virtual SValuePtr isUnsignedLessThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1971  virtual SValuePtr isUnsignedGreaterThan(const SValuePtr &a, const SValuePtr &b);
1972  virtual SValuePtr isUnsignedGreaterThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1982  virtual SValuePtr isSignedLessThan(const SValuePtr &a, const SValuePtr &b);
1983  virtual SValuePtr isSignedLessThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1984  virtual SValuePtr isSignedGreaterThan(const SValuePtr &a, const SValuePtr &b);
1985  virtual SValuePtr isSignedGreaterThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1988  // Integer Arithmetic Operations
1991 
1994  virtual SValuePtr unsignedExtend(const SValuePtr &a, size_t new_width) {
1995  return a->copy(new_width);
1996  }
1997 
2000  virtual SValuePtr signExtend(const SValuePtr &a, size_t new_width) = 0;
2001 
2004  virtual SValuePtr add(const SValuePtr &a, const SValuePtr &b) = 0;
2005 
2008  virtual SValuePtr subtract(const SValuePtr &minuend, const SValuePtr &subtrahend);
2009 
2026  virtual SValuePtr addWithCarries(const SValuePtr &a, const SValuePtr &b, const SValuePtr &c,
2027  SValuePtr &carry_out/*output*/) = 0;
2028 
2030  virtual SValuePtr negate(const SValuePtr &a) = 0;
2031 
2033  virtual SValuePtr signedDivide(const SValuePtr &a, const SValuePtr &b) = 0;
2034 
2036  virtual SValuePtr signedModulo(const SValuePtr &a, const SValuePtr &b) = 0;
2037 
2039  virtual SValuePtr signedMultiply(const SValuePtr &a, const SValuePtr &b) = 0;
2040 
2042  virtual SValuePtr unsignedDivide(const SValuePtr &a, const SValuePtr &b) = 0;
2043 
2045  virtual SValuePtr unsignedModulo(const SValuePtr &a, const SValuePtr &b) = 0;
2046 
2048  virtual SValuePtr unsignedMultiply(const SValuePtr &a, const SValuePtr &b) = 0;
2049 
2050 
2052  // Interrupt and system calls
2054 
2059  virtual void interrupt(int majr, int minr) {}
2060 
2061 
2063  // Floating-point operations
2064  //
2065  // For now these all have default implementations that throw NotImplemented, but we might change them to pure virtual
2066  // sometime in the future so they're consistent with most other RISC operators. [Robb P. Matzke 2015-08-03]
2068 
2070  virtual SValuePtr fpFromInteger(const SValuePtr &intValue, SgAsmFloatType *fpType);
2071 
2077  virtual SValuePtr fpToInteger(const SValuePtr &fpValue, SgAsmFloatType *fpType, const SValuePtr &dflt);
2078 
2082  virtual SValuePtr fpConvert(const SValuePtr &a, SgAsmFloatType *aType, SgAsmFloatType *retType);
2083 
2085  virtual SValuePtr fpIsNan(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2086 
2088  virtual SValuePtr fpIsDenormalized(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2089 
2091  virtual SValuePtr fpIsZero(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2092 
2097  virtual SValuePtr fpIsInfinity(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2098 
2102  virtual SValuePtr fpSign(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2103 
2109  virtual SValuePtr fpEffectiveExponent(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2110 
2114  virtual SValuePtr fpAdd(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2115 
2120  virtual SValuePtr fpSubtract(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2121 
2125  virtual SValuePtr fpMultiply(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2126 
2130  virtual SValuePtr fpDivide(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2131 
2135  virtual SValuePtr fpSquareRoot(const SValuePtr &a, SgAsmFloatType *fpType);
2136 
2140  virtual SValuePtr fpRoundTowardZero(const SValuePtr &a, SgAsmFloatType *fpType);
2141 
2142 
2144  // State Accessing Operations
2146 
2171  virtual SValuePtr readRegister(RegisterDescriptor reg) { // old subclasses can still override this if they want,
2172  return readRegister(reg, undefined_(reg.get_nbits())); // but new subclasses should not override this method.
2173  }
2174  virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt); // new subclasses override this
2186  virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &a) {
2187  ASSERT_not_null(currentState_);
2188  currentState_->writeRegister(reg, a, this);
2189  }
2190 
2196  virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt);
2197 
2220  virtual SValuePtr readMemory(RegisterDescriptor segreg, const SValuePtr &addr, const SValuePtr &dflt,
2221  const SValuePtr &cond) = 0;
2222 
2233  virtual void writeMemory(RegisterDescriptor segreg, const SValuePtr &addr, const SValuePtr &data,
2234  const SValuePtr &cond) = 0;
2235 
2240  virtual SValuePtr peekMemory(RegisterDescriptor segreg, const SValuePtr &addr, const SValuePtr &dflt) = 0;
2241 };
2242 
2243 
2244 
2246 // Instruction Dispatcher
2248 
2250 typedef boost::shared_ptr<class Dispatcher> DispatcherPtr;
2251 
2254 public:
2255  virtual ~InsnProcessor() {}
2256  virtual void process(const DispatcherPtr &dispatcher, SgAsmInstruction *insn) = 0;
2257 };
2258 
2272 class Dispatcher: public boost::enable_shared_from_this<Dispatcher> {
2273 protected:
2274  RiscOperatorsPtr operators;
2276  size_t addrWidth_;
2279  // Dispatchers keep a table of all the kinds of instructions they can handle. The lookup key is typically some sort of
2280  // instruction identifier, such as from SgAsmX86Instruction::get_kind(), and comes from the iproc_key() virtual method.
2281  typedef std::vector<InsnProcessor*> InsnProcessors;
2282  InsnProcessors iproc_table;
2283 
2284 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
2285 private:
2286  friend class boost::serialization::access;
2287 
2288  template<class S>
2289  void serialize(S &s, const unsigned version) {
2290  s & BOOST_SERIALIZATION_NVP(operators);
2291  s & BOOST_SERIALIZATION_NVP(regdict);
2292  s & BOOST_SERIALIZATION_NVP(addrWidth_);
2293  s & BOOST_SERIALIZATION_NVP(autoResetInstructionPointer_);
2294  //s & iproc_table; -- not saved
2295  }
2296 #endif
2297 
2299  // Real constructors
2300 protected:
2301  // Prototypical constructor
2302  Dispatcher(): regdict(NULL), addrWidth_(0), autoResetInstructionPointer_(true) {}
2303 
2304  // Prototypical constructor
2305  Dispatcher(size_t addrWidth, const RegisterDictionary *regs)
2306  : regdict(regs), addrWidth_(addrWidth), autoResetInstructionPointer_(true) {}
2307 
2308  Dispatcher(const RiscOperatorsPtr &ops, size_t addrWidth, const RegisterDictionary *regs)
2309  : operators(ops), regdict(regs), addrWidth_(addrWidth), autoResetInstructionPointer_(true) {
2310  ASSERT_not_null(operators);
2311  ASSERT_not_null(regs);
2312  }
2313 
2314 public:
2316  typedef DispatcherPtr Ptr;
2317 
2318 public:
2319  virtual ~Dispatcher() {
2320  for (InsnProcessors::iterator iter=iproc_table.begin(); iter!=iproc_table.end(); ++iter)
2321  delete *iter;
2322  }
2323 
2325  // Static allocating constructors. None since this is an abstract class
2326 
2327 
2329  // Virtual constructors
2330 public:
2332  virtual DispatcherPtr create(const RiscOperatorsPtr &ops, size_t addrWidth=0, const RegisterDictionary *regs=NULL) const = 0;
2333 
2335  // Methods to process instructions
2336 public:
2338  virtual void processInstruction(SgAsmInstruction *insn);
2339 
2341  // Instruction processor table operations
2342 public:
2346  virtual InsnProcessor *iproc_lookup(SgAsmInstruction *insn);
2347 
2351  virtual void iproc_replace(SgAsmInstruction *insn, InsnProcessor *iproc);
2352 
2354  virtual int iproc_key(SgAsmInstruction*) const = 0;
2355 
2359  virtual void iproc_set(int key, InsnProcessor *iproc);
2360 
2362  virtual InsnProcessor *iproc_get(int key);
2363 
2365  // Convenience methods that defer the call to some member object
2366 public:
2368  virtual RiscOperatorsPtr get_operators() const { return operators; }
2369 
2372  virtual StatePtr currentState() const { return operators ? operators->currentState() : StatePtr(); }
2373 
2374  // [Robb Matzke 2016-01-22]: deprecated
2375  virtual StatePtr get_state() const ROSE_DEPRECATED("use currentState instead") {
2376  return currentState();
2377  }
2378 
2380  virtual SValuePtr protoval() const { return operators ? operators->protoval() : SValuePtr(); }
2381 
2382  // [Robb Matzke 2016-01-22]: deprecated
2383  virtual SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
2384  return protoval();
2385  }
2386 
2392  return operators ? operators->currentInstruction() : NULL;
2393  }
2394 
2395  // [Robb Matzke 2016-01-22]: deprecated
2396  virtual SgAsmInstruction *get_insn() const ROSE_DEPRECATED("use currentInstruction instead") {
2397  return currentInstruction();
2398  }
2399 
2401  virtual SValuePtr undefined_(size_t nbits) const {
2402  ASSERT_not_null(operators);
2403  return operators->undefined_(nbits);
2404  }
2405  virtual SValuePtr unspecified_(size_t nbits) const {
2406  ASSERT_not_null(operators);
2407  return operators->unspecified_(nbits);
2408  }
2409 
2411  virtual SValuePtr number_(size_t nbits, uint64_t number) const {
2412  ASSERT_not_null(operators);
2413  return operators->number_(nbits, number);
2414  }
2415 
2417  // Methods related to registers
2418 public:
2431  return regdict;
2432  }
2433  virtual void set_register_dictionary(const RegisterDictionary *regdict) {
2434  this->regdict = regdict;
2435  }
2442  virtual RegisterDescriptor findRegister(const std::string &regname, size_t nbits=0, bool allowMissing=false) const;
2443 
2450  size_t addressWidth() const { return addrWidth_; }
2451  void addressWidth(size_t nbits);
2455  virtual RegisterDescriptor instructionPointerRegister() const = 0;
2456 
2458  virtual RegisterDescriptor stackPointerRegister() const = 0;
2459 
2466  bool autoResetInstructionPointer() const { return autoResetInstructionPointer_; }
2467  void autoResetInstructionPointer(bool b) { autoResetInstructionPointer_ = b; }
2471  // Miscellaneous methods that tend to be the same for most dispatchers
2473 public:
2474 
2483  virtual void advanceInstructionPointer(SgAsmInstruction*);
2484 
2488  virtual RegisterDescriptor segmentRegister(SgAsmMemoryReferenceExpression*);
2489 
2493  virtual void incrementRegisters(SgAsmExpression*);
2494 
2498  virtual void decrementRegisters(SgAsmExpression*);
2499 
2503  virtual SValuePtr effectiveAddress(SgAsmExpression*, size_t nbits=0);
2504 
2510  virtual SValuePtr read(SgAsmExpression*, size_t value_nbits=0, size_t addr_nbits=0);
2511 
2515  virtual void write(SgAsmExpression*, const SValuePtr &value, size_t addr_nbits=0);
2516 };
2517 
2518 
2519 
2521 // Printing
2523 
2524 std::ostream& operator<<(std::ostream&, const Exception&);
2525 std::ostream& operator<<(std::ostream&, const SValue&);
2526 std::ostream& operator<<(std::ostream&, const SValue::WithFormatter&);
2527 std::ostream& operator<<(std::ostream&, const MemoryState&);
2528 std::ostream& operator<<(std::ostream&, const MemoryState::WithFormatter&);
2529 std::ostream& operator<<(std::ostream&, const RegisterState&);
2530 std::ostream& operator<<(std::ostream&, const RegisterState::WithFormatter&);
2531 std::ostream& operator<<(std::ostream&, const State&);
2532 std::ostream& operator<<(std::ostream&, const State::WithFormatter&);
2533 std::ostream& operator<<(std::ostream&, const RiscOperators&);
2534 std::ostream& operator<<(std::ostream&, const RiscOperators::WithFormatter&);
2535 
2536 } // namespace
2537 } // namespace
2538 } // namespace
2539 } // namespace
2540 
2541 #endif
void autoResetInstructionPointer(bool b)
Property: Reset instruction pointer register for each instruction.
bool autoResetInstructionPointer() const
Property: Reset instruction pointer register for each instruction.
MergerPtr Ptr
Shared ownership pointer for Merger.
void clear_show_latest_writers()
Whether to show latest writer information for register and memory states.
The location was read without having the IO_WRITE or IO_INIT property.
virtual SgAsmInstruction * currentInstruction() const
Returns current instruction.
The location was written on behalf of an instruction.
virtual SValuePtr filterIndirectJumpTarget(const SValuePtr &a)
Invoked to filter indirect jumps.
void set_line_prefix(const std::string &s)
The string to print at the start of each line.
MemoryStatePtr memoryState() const
Property: Memory state.
virtual SValuePtr undefined_(size_t nbits)
Returns a new undefined value.
virtual std::string get_comment() const
Some subclasses support the ability to add comments to values.
virtual void zero() ROSE_OVERRIDE
Set all registers to the zero.
WithFormatter operator+(Formatter &fmt)
Used for printing memory states with formatting.
virtual void set_width(size_t nbits)
Accessor for value width.
virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) ROSE_OVERRIDE
Read a value from a register.
WithFormatter with_format(Formatter &fmt)
Used for printing values with formatting.
void clear_suppress_initial_values()
Whether register initial values should be suppressed.
virtual bool must_equal(const SValuePtr &other, const SmtSolverPtr &solver=SmtSolverPtr()) const =0
Returns true if two values must be equal.
virtual void print(std::ostream &, Formatter &) const ROSE_OVERRIDE
Print the register contents.
bool isFalse() const
Returns true if concrete zero.
virtual RegisterStatePtr clone() const =0
Make a copy of this register state.
Base class for machine instructions.
Collection of streams.
Definition: Message.h:1579
const RegisterDictionary * get_register_dictionary() const
The register dictionary should be compatible with the register dictionary used for other parts of bin...
void print(std::ostream &stream, const std::string prefix="") const
Print a memory state to more than one line of output.
WithFormatter operator+(Formatter &fmt)
Used for printing RISC operators with formatting.
virtual SValuePtr undefined_(size_t nbits) const
Return a new undefined semantic value.
virtual void finishInstruction(SgAsmInstruction *insn)
Called at the end of every instruction.
RegisterStatePtr registerState() const
Property: Register state.
virtual void clear()=0
Removes stored values from the register state.
virtual SValuePtr boolean_(bool value) const
Create a new, Boolean value.
bool get_suppress_initial_values() const
Whether register initial values should be suppressed.
RegisterStatePtr Ptr
Shared-ownership pointer for a RegisterState object.
SValuePtr createMerged(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const
Create a new value by merging two existing values.
virtual StatePtr currentState() const
Get a pointer to the state object.
std::string get_indentation_suffix() const
Indentation string appended to the line prefix for multi-level, multi-line outputs.
virtual bool merge(const RegisterStatePtr &other, RiscOperators *ops)=0
Merge register states for data flow analysis.
SValuePtr Ptr
Shared-ownership pointer for an SValue object.
WithFormatter operator+(Formatter &fmt)
Used for printing values with formatting.
MemoryStatePtr Ptr
Shared-ownership pointer for a MemoryState.
STL namespace.
Holds a value or nothing.
Definition: Optional.h:49
ByteOrder::Endianness get_byteOrder() const
Memory byte order.
virtual SValuePtr protoval() const
Return the prototypical value.
Small object support.
Definition: SmallObject.h:19
virtual void cpuid()
Invoked for the x86 CPUID instruction.
void initDiagnostics()
Initialize diagnostics for instruction semantics.
virtual SValuePtr protoval() const
Property: Prototypical semantic value.
virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops)=0
Write a value to a register.
Main namespace for the ROSE library.
void print(std::ostream &stream, const std::string prefix="") const
Print the register contents.
virtual SValuePtr unspecified_(size_t nbits) const =0
Create a new unspecified semantic value.
Describes (part of) a physical CPU register.
void byteRestricted(bool b)
Indicates whether memory cell values are required to be eight bits wide.
void set_suppress_initial_values(bool b=true)
Whether register initial values should be suppressed.
virtual StatePtr create(const RegisterStatePtr &registers, const MemoryStatePtr &memory) const
Virtual constructor.
void set_show_latest_writers(bool b=true)
Whether to show latest writer information for register and memory states.
virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops)=0
Read a value from a register.
virtual SValuePtr peekRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) ROSE_OVERRIDE
Read a register without side effects.
static const size_t n_st
Number of ST registers (not counting _st_top pseudo register).
virtual void solver(const SmtSolverPtr &s)
Property: Satisfiability module theory (SMT) solver.
virtual const RegisterDictionary * get_register_dictionary() const
Access the register dictionary.
WithFormatter operator+(Formatter &fmt)
Used for printing states with formatting.
InputOutputProperty
Boolean properties related to I/O.
virtual SValuePtr boolean_(bool value)
Returns a Boolean value.
virtual void interrupt(int majr, int minr)
Invoked for instructions that cause an interrupt.
virtual size_t nInsns() const
Property: Number of instructions processed.
static const size_t n_segregs
Number of segmentation registers in this state.
virtual StatePtr currentState() const
Property: Current semantic state.
Sawyer::SharedPointer< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
virtual uint64_t get_number() const =0
Return the concrete number for this value.
virtual void clear() ROSE_OVERRIDE
Removes stored values from the register state.
SValuePtr get_addr_protoval() const
Return the address protoval.
boost::shared_ptr< class RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
bool get_show_latest_writers() const
Whether to show latest writer information for register and memory states.
boost::shared_ptr< class State > StatePtr
Shared-ownership pointer to a semantic state.
RiscOperatorsPtr Ptr
Shared-ownership pointer for a RiscOperators object.
virtual void hlt()
Invoked for the x86 HLT instruction.
Reference to memory locations.
boost::shared_ptr< class Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
static RegisterStateX86Ptr instance(const SValuePtr &protoval, const RegisterDictionary *regdict)
Instantiate a new register state.
static StatePtr instance(const StatePtr &other)
Instantiate a new copy of an existing state.
The set of all registers and their values for a 32-bit x86 architecture.
Base classes for instruction semantics.
virtual SgAsmInstruction * currentInstruction() const
Returns the instruction that is being processed.
virtual SValuePtr filterReturnTarget(const SValuePtr &a)
Invoked to filter return targets.
WithFormatter operator+(Formatter &fmt)
Used for printing register states with formatting.
size_t addressWidth() const
Property: Width of memory addresses.
virtual void nInsns(size_t n)
Property: Number of instructions processed.
boost::shared_ptr< class RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
virtual RiscOperatorsPtr get_operators() const
Get a pointer to the RISC operators object.
Creates SharedPointer from this.
WithFormatter with_format(Formatter &fmt)
Used for printing register states with formatting.
virtual bool may_equal(const SValuePtr &other, const SmtSolverPtr &solver=SmtSolverPtr()) const =0
Returns true if two values could be equal.
void clear_show_properties()
Whether to show register properties.
WithFormatter with_format(Formatter &fmt)
Used for printing states with formatting.
virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionary *regdict) const =0
Virtual constructor.
static const size_t n_flags
Number of flag registers in this state.
virtual SValuePtr unsignedExtend(const SValuePtr &a, size_t new_width)
Extend (or shrink) operand a so it is nbits wide by adding or removing high-order bits...
virtual SValuePtr filterCallTarget(const SValuePtr &a)
Invoked to filter call targets.
Sawyer::Message::Facility mlog
Diagnostics logging facility for instruction semantics.
Sawyer::SharedPointer< class SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
bool isTrue() const
Returns true if concrete non-zero.
virtual void set_comment(const std::string &) const
Some subclasses support the ability to add comments to values.
Functor that knows how to dispatch a single kind of instruction.
virtual SValuePtr bottom_(size_t nBits) const =0
Data-flow bottom value.
virtual void currentState(const StatePtr &s)
Property: Current semantic state.
DispatcherPtr Ptr
Shared-ownership pointer for a Dispatcher object.
Defines registers available for a particular architecture.
Definition: Registers.h:32
void print(std::ostream &stream, const std::string prefix="") const
Print multi-line output for this object.
The location was read without having the IO_WRITE property.
The location was written without an instruction.
virtual bool isBottom() const =0
Determines whether a value is a data-flow bottom.
virtual StatePtr initialState() const
Property: Optional lazily updated initial state.
Base class for most instruction semantics RISC operators.
const RegisterDictionary * regdict
See set_register_dictionary().
Base class for expressions.
virtual SValuePtr rdtsc()
Invoked for the x86 RDTSC instruction.
static const size_t n_gprs
Number of general-purpose registers in this state.
const RegisterDictionary * regdict
Registers that are able to be stored by this state.
void set_register_dictionary(RegisterDictionary *rd)
The register dictionary which is used for printing register names.
virtual void initialState(const StatePtr &s)
Property: Optional lazily updated initial state.
static RegisterStateX86Ptr promote(const RegisterStatePtr &from)
Run-time promotion of a base register state pointer to a RegisterStateX86 pointer.
virtual SValuePtr number_(size_t nbits, uint64_t number) const =0
Create a new concrete semantic value.
static StatePtr instance(const RegisterStatePtr &registers, const MemoryStatePtr &memory)
Instantiate a new state object with specified register and memory states.
Sawyer::SharedPointer< class Merger > MergerPtr
Shared-ownership pointer for Merger classes.
void set_show_properties(bool b=true)
Whether to show register properties.
Base class for reference counted objects.
Definition: SharedObject.h:22
void set_register_dictionary(const RegisterDictionary *rd)
The register dictionary should be compatible with the register dictionary used for other parts of bin...
virtual StatePtr clone() const
Virtual copy constructor.
boost::shared_ptr< class MemoryState > MemoryStatePtr
Shared-ownership pointer to a memory state.
std::string get_line_prefix() const
The string to print at the start of each line.
WithFormatter with_format(Formatter &fmt)
Used for printing memory states with formatting.
void print(std::ostream &stream) const
Print a value to a stream using default format.
virtual void name(const std::string &s)
Property: Name used for debugging.
virtual size_t get_width() const
Accessor for value width.
virtual SValuePtr bottom_(size_t nbits)
Returns a data-flow bottom value.
WithFormatter with_format(Formatter &fmt)
Used for printing RISC operators with formatting.
SValuePtr get_val_protoval() const
Return the value protoval.
virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &a)
Writes a value to a register.
virtual bool is_number() const =0
Determines if the value is a concrete number.
virtual RegisterStatePtr clone() const ROSE_OVERRIDE
Make a copy of this register state.
virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionary *regdict) const ROSE_OVERRIDE
Virtual constructor.
void set_byteOrder(ByteOrder::Endianness bo)
Memory byte order.
SValuePtr flag[n_flags]
Control/status flags (i.e., FLAG register).
bool get_show_properties() const
Whether to show register properties.
bool autoResetInstructionPointer_
Reset instruction pointer register for each instruction.
virtual SmtSolverPtr solver() const
Property: Satisfiability module theory (SMT) solver.
RegisterDictionary * get_register_dictionary() const
The register dictionary which is used for printing register names.
virtual void set_register_dictionary(const RegisterDictionary *regdict)
Access the register dictionary.
void set_indentation_suffix(const std::string &s)
Indentation string appended to the line prefix for multi-level, multi-line outputs.
virtual const std::string & name() const
Property: Name used for debugging.
virtual SValuePtr readRegister(RegisterDescriptor reg)
Reads a value from a register.
virtual SValuePtr undefined_(size_t nbits) const =0
Create a new undefined semantic value.
virtual SValuePtr number_(size_t nbits, uint64_t value)
Returns a number of the specified bit width.
Sawyer::Container::Set< InputOutputProperty > InputOutputPropertySet
Set of Boolean properties.
virtual Sawyer::Optional< SValuePtr > createOptionalMerge(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const =0
Possibly create a new value by merging two existing values.
bool byteRestricted() const
Indicates whether memory cell values are required to be eight bits wide.
Base class for exceptions thrown by instruction semantics.
virtual bool merge(const RegisterStatePtr &other, RiscOperators *ops) ROSE_OVERRIDE
Merge register states for data flow analysis.
virtual SValuePtr number_(size_t nbits, uint64_t number) const
Return a semantic value representing a number.
static RegisterStateX86Ptr instance(const RegisterStateX86Ptr &other)
Instantiate a new copy of an existing register state.
virtual SValuePtr peekRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops)=0
Read a register without side effects.
Floating point types.
virtual void print(std::ostream &stream, Formatter &fmt) const
Print multi-line output for this object.
virtual SValuePtr copy(size_t new_width=0) const =0
Create a new value from an existing value, changing the width if new_width is non-zero.
The location was read on behalf of an instruction.
virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops) ROSE_OVERRIDE
Write a value to a register.
StatePtr Ptr
Shared-ownership pointer for a State.
Adjusts a Formatter for one additional level of indentation.
boost::shared_ptr< class RegisterStateX86 > RegisterStateX86Ptr
Shared-ownership pointer to an x86 register state.