ROSE  0.9.9.139
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, SmtSolver *solver) const = 0;
648 
655  SValuePtr createMerged(const SValuePtr &other, const MergerPtr &merger, SmtSolver *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, SmtSolver *solver=NULL) const = 0;
693 
695  virtual bool must_equal(const SValuePtr &other, SmtSolver *solver=NULL) 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 
894  virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops) = 0;
895 
898  void print(std::ostream &stream, const std::string prefix="") const {
899  Formatter fmt;
900  fmt.set_line_prefix(prefix);
901  print(stream, fmt);
902  }
903  virtual void print(std::ostream&, Formatter&) const = 0;
908  RegisterStatePtr obj;
909  Formatter &fmt;
910  public:
911  WithFormatter(const RegisterStatePtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
912  void print(std::ostream &stream) const { obj->print(stream, fmt); }
913  };
914 
922  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
926 };
927 
929 typedef boost::shared_ptr<class RegisterStateX86> RegisterStateX86Ptr;
930 
939 public:
940  static const size_t n_gprs = 8;
941  static const size_t n_segregs = 6;
942  static const size_t n_flags = 32;
943  static const size_t n_st = 8;
944  static const size_t n_xmm = 8;
946  SValuePtr ip;
947  SValuePtr gpr[n_gprs];
948  SValuePtr segreg[n_segregs];
949  SValuePtr flag[n_flags];
950  SValuePtr st[n_st];
951  SValuePtr fpstatus;
952  SValuePtr xmm[n_xmm];
954  // Real constructors
956 protected:
957  explicit RegisterStateX86(const SValuePtr &protoval, const RegisterDictionary *regdict)
958  : RegisterState(protoval, regdict) {
959  clear();
960  }
961 
962  RegisterStateX86(const RegisterStateX86 &other): RegisterState(other) {
963  ip = other.ip->copy();
964  for (size_t i=0; i<n_gprs; ++i)
965  gpr[i] = other.gpr[i]->copy();
966  for (size_t i=0; i<n_segregs; ++i)
967  segreg[i] = other.segreg[i]->copy();
968  for (size_t i=0; i<n_flags; ++i)
969  flag[i] = other.flag[i]->copy();
970  for (size_t i=0; i<n_st; ++i)
971  st[i] = other.st[i]->copy();
972  fpstatus = other.fpstatus;
973  for (size_t i=0; i<n_xmm; ++i)
974  xmm[i] = other.xmm[i]->copy();
975  }
976 
978  // Static allocating constructors
979 public:
983  static RegisterStateX86Ptr instance(const SValuePtr &protoval, const RegisterDictionary *regdict) {
984  return RegisterStateX86Ptr(new RegisterStateX86(protoval, regdict));
985  }
986 
988  static RegisterStateX86Ptr instance(const RegisterStateX86Ptr &other) {
989  return RegisterStateX86Ptr(new RegisterStateX86(*other));
990  }
991 
993  // Virtual constructors
994 public:
995  virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionary *regdict) const ROSE_OVERRIDE {
996  return instance(protoval, regdict);
997  }
998 
999  virtual RegisterStatePtr clone() const ROSE_OVERRIDE {
1000  return RegisterStatePtr(new RegisterStateX86(*this));
1001  }
1002 
1004  // Dynamic pointer casts
1005 public:
1008  static RegisterStateX86Ptr promote(const RegisterStatePtr &from) {
1009  RegisterStateX86Ptr retval = boost::dynamic_pointer_cast<RegisterStateX86>(from);
1010  ASSERT_not_null(retval);
1011  return retval;
1012  }
1013 
1015  // Methods we inherited
1016 public:
1017  virtual void clear() ROSE_OVERRIDE;
1018  virtual void zero() ROSE_OVERRIDE;
1019  virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt, RiscOperators *ops) ROSE_OVERRIDE;
1020  virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops) ROSE_OVERRIDE;
1021  virtual void print(std::ostream&, Formatter&) const ROSE_OVERRIDE;
1022  virtual bool merge(const RegisterStatePtr &other, RiscOperators *ops) ROSE_OVERRIDE;
1023 
1025  // Methods first declared at this level of the class hierarchy
1026 protected:
1027  // helpers for readRegister()
1028  virtual SValuePtr readRegisterGpr(RegisterDescriptor reg, RiscOperators *ops);
1029  virtual SValuePtr readRegisterFlag(RegisterDescriptor reg, RiscOperators *ops);
1030  virtual SValuePtr readRegisterSeg(RegisterDescriptor reg, RiscOperators *ops);
1031  virtual SValuePtr readRegisterIp(RegisterDescriptor reg, RiscOperators *ops);
1032  virtual SValuePtr readRegisterSt(RegisterDescriptor reg, RiscOperators *ops);
1033  virtual SValuePtr readRegisterXmm(RegisterDescriptor reg, RiscOperators *ops);
1034  virtual SValuePtr readRegisterFpStatus(RegisterDescriptor reg, RiscOperators *ops);
1035 
1036  // helpers for writeRegister()
1037  virtual void writeRegisterGpr(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1038  virtual void writeRegisterFlag(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1039  virtual void writeRegisterSeg(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1040  virtual void writeRegisterIp(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1041  virtual void writeRegisterSt(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1042  virtual void writeRegisterXmm(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1043  virtual void writeRegisterFpStatus(RegisterDescriptor reg, const SValuePtr &value, RiscOperators *ops);
1044 
1045  // Generate a name for initial values.
1046  virtual std::string initialValueName(RegisterDescriptor) const;
1047 };
1048 
1049 
1050 
1052 // Memory State
1054 
1056 typedef boost::shared_ptr<class MemoryState> MemoryStatePtr;
1057 
1061 class MemoryState: public boost::enable_shared_from_this<MemoryState> {
1062  SValuePtr addrProtoval_;
1063  SValuePtr valProtoval_;
1064  ByteOrder::Endianness byteOrder_;
1065  MergerPtr merger_;
1066  bool byteRestricted_; // are cell values all exactly one byte wide?
1067 
1069  // Serialization
1070 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1071 private:
1072  friend class boost::serialization::access;
1073 
1074  template<class S>
1075  void serialize(S &s, const unsigned version) {
1076  s & BOOST_SERIALIZATION_NVP(addrProtoval_);
1077  s & BOOST_SERIALIZATION_NVP(valProtoval_);
1078  s & BOOST_SERIALIZATION_NVP(byteOrder_);
1079  //s & merger_ -- not saved
1080  s & BOOST_SERIALIZATION_NVP(byteRestricted_);
1081  }
1082 #endif
1083 
1084 
1086  // Real constructors
1087 protected:
1088  MemoryState() // for serialization
1089  : byteOrder_(ByteOrder::ORDER_UNSPECIFIED), byteRestricted_(true) {}
1090 
1091  explicit MemoryState(const SValuePtr &addrProtoval, const SValuePtr &valProtoval)
1092  : addrProtoval_(addrProtoval), valProtoval_(valProtoval), byteOrder_(ByteOrder::ORDER_UNSPECIFIED),
1093  byteRestricted_(true) {
1094  ASSERT_not_null(addrProtoval);
1095  ASSERT_not_null(valProtoval);
1096  }
1097 
1098  MemoryState(const MemoryStatePtr &other)
1099  : addrProtoval_(other->addrProtoval_), valProtoval_(other->valProtoval_), byteOrder_(ByteOrder::ORDER_UNSPECIFIED),
1100  merger_(other->merger_), byteRestricted_(other->byteRestricted_) {}
1101 
1102 public:
1104  typedef MemoryStatePtr Ptr;
1105 
1106 public:
1107  virtual ~MemoryState() {}
1108 
1110  // Static allocating constructors. None needed since this class is abstract
1111 
1113  // Virtual constructors
1114 public:
1121  virtual MemoryStatePtr create(const SValuePtr &addrProtoval, const SValuePtr &valProtoval) const = 0;
1122 
1124  virtual MemoryStatePtr clone() const = 0;
1125 
1127  // Dynamic pointer casts. No-op since this is the base class.
1128 public:
1129  static MemoryStatePtr promote(const MemoryStatePtr &x) {
1130  ASSERT_not_null(x);
1131  return x;
1132  }
1133 
1135  // Methods first declared at this level of the class hierarchy
1136 public:
1145  MergerPtr merger() const { return merger_; }
1146  void merger(const MergerPtr &m) { merger_ = m; }
1151  SValuePtr get_addr_protoval() const { return addrProtoval_; }
1152 
1155  SValuePtr get_val_protoval() const { return valProtoval_; }
1156 
1158  virtual void clear() = 0;
1159 
1167  bool byteRestricted() const { return byteRestricted_; }
1168  void byteRestricted(bool b) { byteRestricted_ = b; }
1173  ByteOrder::Endianness get_byteOrder() const { return byteOrder_; }
1174  void set_byteOrder(ByteOrder::Endianness bo) { byteOrder_ = bo; }
1180  virtual bool merge(const MemoryStatePtr &other, RiscOperators *addrOps, RiscOperators *valOps) = 0;
1181 
1201  virtual SValuePtr readMemory(const SValuePtr &address, const SValuePtr &dflt,
1202  RiscOperators *addrOps, RiscOperators *valOps) = 0;
1203 
1213  virtual void writeMemory(const SValuePtr &addr, const SValuePtr &value,
1214  RiscOperators *addrOps, RiscOperators *valOps) = 0;
1215 
1218  void print(std::ostream &stream, const std::string prefix="") const {
1219  Formatter fmt;
1220  fmt.set_line_prefix(prefix);
1221  print(stream, fmt);
1222  }
1223  virtual void print(std::ostream&, Formatter&) const = 0;
1228  MemoryStatePtr obj;
1229  Formatter &fmt;
1230  public:
1231  WithFormatter(const MemoryStatePtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
1232  void print(std::ostream &stream) const { obj->print(stream, fmt); }
1233  };
1234 
1242  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
1245 };
1246 
1247 
1248 
1250 // State
1252 
1254 typedef boost::shared_ptr<class State> StatePtr;
1255 
1272 class State: public boost::enable_shared_from_this<State> {
1273  SValuePtr protoval_; // Initial value used to create additional values as needed.
1274  RegisterStatePtr registers_; // All machine register values for this semantic state.
1275  MemoryStatePtr memory_; // All memory for this semantic state.
1276 
1278  // Serialization
1279 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1280 private:
1281  friend class boost::serialization::access;
1282 
1283  template<class S>
1284  void serialize(S &s, const unsigned version) {
1285  s & BOOST_SERIALIZATION_NVP(protoval_);
1286  s & BOOST_SERIALIZATION_NVP(registers_);
1287  s & BOOST_SERIALIZATION_NVP(memory_);
1288  }
1289 #endif
1290 
1291 
1293  // Real constructors
1294 protected:
1295  // needed for serialization
1296  State() {}
1297 
1298  State(const RegisterStatePtr &registers, const MemoryStatePtr &memory)
1299  : registers_(registers), memory_(memory) {
1300  ASSERT_not_null(registers);
1301  ASSERT_not_null(memory);
1302  protoval_ = registers->protoval();
1303  ASSERT_not_null(protoval_);
1304  }
1305 
1306  // deep-copy the registers and memory
1307  State(const State &other)
1308  : protoval_(other.protoval_) {
1309  registers_ = other.registers_->clone();
1310  memory_ = other.memory_->clone();
1311  }
1312 
1313 public:
1315  typedef StatePtr Ptr;
1316 
1317 public:
1318  virtual ~State() {}
1319 
1321  // Static allocating constructors
1322 public:
1324  static StatePtr instance(const RegisterStatePtr &registers, const MemoryStatePtr &memory) {
1325  return StatePtr(new State(registers, memory));
1326  }
1327 
1329  static StatePtr instance(const StatePtr &other) {
1330  return StatePtr(new State(*other));
1331  }
1332 
1334  // Virtual constructors
1335 public:
1337  virtual StatePtr create(const RegisterStatePtr &registers, const MemoryStatePtr &memory) const {
1338  return instance(registers, memory);
1339  }
1340 
1344  virtual StatePtr clone() const {
1345  StatePtr self = boost::const_pointer_cast<State>(shared_from_this());
1346  return instance(self);
1347  }
1348 
1350  // Dynamic pointer casts. No-op since this is the base class.
1351 public:
1352  static StatePtr promote(const StatePtr &x) {
1353  ASSERT_not_null(x);
1354  return x;
1355  }
1356 
1358  // Other methods that are part of our API. Most of these just chain to either the register state and/or the memory state.
1359 public:
1361  SValuePtr protoval() const { return protoval_; }
1362 
1363  // [Robb Matzke 2016-01-22]: deprecated
1364  SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
1365  return protoval();
1366  }
1367 
1369  virtual void clear();
1370 
1374  virtual void zero_registers();
1375 
1379  virtual void clear_memory();
1380 
1384  RegisterStatePtr registerState() const {
1385  return registers_;
1386  }
1387 
1388  // [Robb Matzke 2016-01-22]: deprecated
1389  RegisterStatePtr get_register_state() ROSE_DEPRECATED("use registerState instead") {
1390  return registerState();
1391  }
1392 
1397  return memory_;
1398  }
1399 
1400  // [Robb Matzke 2016-01-22]: deprecated
1401  MemoryStatePtr get_memory_state() ROSE_DEPRECATED("use memoryState instead") {
1402  return memoryState();
1403  }
1404 
1409  virtual SValuePtr readRegister(RegisterDescriptor desc, const SValuePtr &dflt, RiscOperators *ops);
1410 
1415  virtual void writeRegister(RegisterDescriptor desc, const SValuePtr &value, RiscOperators *ops);
1416 
1421  virtual SValuePtr readMemory(const SValuePtr &address, const SValuePtr &dflt,
1422  RiscOperators *addrOps, RiscOperators *valOps);
1423 
1428  virtual void writeMemory(const SValuePtr &addr, const SValuePtr &value, RiscOperators *addrOps, RiscOperators *valOps);
1429 
1435  void printRegisters(std::ostream &stream, const std::string &prefix = "");
1436  virtual void printRegisters(std::ostream &stream, Formatter &fmt) const;
1439  // [Robb Matzke 2015-11-16]: deprecated
1440  void print_registers(std::ostream &stream, const std::string &prefix = "") ROSE_DEPRECATED("use printRegisters instead") {
1441  printRegisters(stream, prefix);
1442  }
1443 
1444  // [Robb Matzke 2015-11-16]: deprecated
1445  virtual void print_registers(std::ostream &stream, Formatter &fmt) const ROSE_DEPRECATED("use printRegisters instead") {
1446  printRegisters(stream, fmt);
1447  }
1448 
1454  void printMemory(std::ostream &stream, const std::string &prefix = "") const;
1455  virtual void printMemory(std::ostream &stream, Formatter &fmt) const;
1458  // [Robb Matzke 2015-11-16]: deprecated
1459  void print_memory(std::ostream &stream, const std::string prefix = "") const ROSE_DEPRECATED("use printMemory instead") {
1460  printMemory(stream, prefix);
1461  }
1462 
1463  // [Robb Matzke 2015-11-16]: deprecated
1464  virtual void print_memory(std::ostream &stream, Formatter &fmt) const ROSE_DEPRECATED("use printMemory instead") {
1465  printMemory(stream, fmt);
1466  }
1467 
1470  void print(std::ostream &stream, const std::string &prefix = "") const;
1471  virtual void print(std::ostream&, Formatter&) const;
1476  StatePtr obj;
1477  Formatter &fmt;
1478  public:
1479  WithFormatter(const StatePtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
1480  void print(std::ostream &stream) const { obj->print(stream, fmt); }
1481  };
1482 
1490  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
1499  virtual bool merge(const StatePtr &other, RiscOperators *ops);
1500 };
1501 
1502 
1503 
1505 // RISC Operators
1507 
1509 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
1510 
1531 class RiscOperators: public boost::enable_shared_from_this<RiscOperators> {
1532  SValuePtr protoval_; // Prototypical value used for its virtual constructors
1533  StatePtr currentState_; // State upon which RISC operators operate
1534  StatePtr initialState_; // Lazily updated initial state; see readMemory
1535  SmtSolver *solver_; // Optional SMT solver
1536  SgAsmInstruction *currentInsn_; // Current instruction, as set by latest startInstruction call
1537  size_t nInsns_; // Number of instructions processed
1538  std::string name_; // Name to use for debugging
1539 
1541  // Serialization
1542 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1543 private:
1544  friend class boost::serialization::access;
1545 
1546  template<class S>
1547  void serialize(S &s, const unsigned version) {
1548  s & BOOST_SERIALIZATION_NVP(protoval_);
1549  s & BOOST_SERIALIZATION_NVP(currentState_);
1550  s & BOOST_SERIALIZATION_NVP(initialState_);
1551  s & BOOST_SERIALIZATION_NVP(solver_);
1552  s & BOOST_SERIALIZATION_NVP(currentInsn_);
1553  s & BOOST_SERIALIZATION_NVP(nInsns_);
1554  s & BOOST_SERIALIZATION_NVP(name_);
1555  }
1556 #endif
1557 
1559  // Real constructors
1560 protected:
1561  // for serialization
1562  RiscOperators()
1563  : solver_(NULL), currentInsn_(NULL), nInsns_(0) {}
1564 
1565  explicit RiscOperators(const SValuePtr &protoval, SmtSolver *solver=NULL)
1566  : protoval_(protoval), solver_(solver), currentInsn_(NULL), nInsns_(0) {
1567  ASSERT_not_null(protoval_);
1568  }
1569 
1570  explicit RiscOperators(const StatePtr &state, SmtSolver *solver=NULL)
1571  : currentState_(state), solver_(solver), currentInsn_(NULL), nInsns_(0) {
1572  ASSERT_not_null(state);
1573  protoval_ = state->protoval();
1574  }
1575 
1576 public:
1578  typedef RiscOperatorsPtr Ptr;
1579 
1580 public:
1581  virtual ~RiscOperators() {}
1582 
1584  // Static allocating constructors. None needed since this class is abstract.
1585 
1586 
1588  // Virtual constructors.
1589 public:
1593  virtual RiscOperatorsPtr create(const SValuePtr &protoval, SmtSolver *solver=NULL) const = 0;
1594 
1599  virtual RiscOperatorsPtr create(const StatePtr &state, SmtSolver *solver=NULL) const = 0;
1600 
1602  // Dynamic pointer casts. No-op since this is the base class.
1603 public:
1604  static RiscOperatorsPtr promote(const RiscOperatorsPtr &x) {
1605  ASSERT_not_null(x);
1606  return x;
1607  }
1608 
1610  // Other methods part of our API
1611 public:
1615  virtual SValuePtr protoval() const { return protoval_; }
1616 
1617  // [Robb Matzke 2016-01-22]: deprecated
1618  virtual SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
1619  return protoval();
1620  }
1621 
1630  virtual SmtSolver* solver() const { return solver_; }
1631  virtual void solver(SmtSolver *s) { solver_ = s; }
1634  // [Robb Matzke 2016-01-22]: deprecated
1635  virtual void set_solver(SmtSolver *s) ROSE_DEPRECATED("use solver instead") { solver(s); }
1636  virtual SmtSolver *get_solver() const ROSE_DEPRECATED("use solver instead") { return solver(); }
1637 
1649  virtual StatePtr currentState() const { return currentState_; }
1650  virtual void currentState(const StatePtr &s) { currentState_ = s; }
1653  // [Robb Matzke 2016-01-22]: deprecated
1654  virtual StatePtr get_state() const ROSE_DEPRECATED("use currentState instead") {
1655  return currentState();
1656  }
1657 
1658  // [Robb Matzke 2016-01-22]: deprecated
1659  virtual void set_state(const StatePtr &s) ROSE_DEPRECATED("use currentState instead") {
1660  currentState(s);
1661  }
1662 
1700  virtual StatePtr initialState() const { return initialState_; }
1701  virtual void initialState(const StatePtr &s) { initialState_ = s; }
1709  virtual const std::string& name() const { return name_; }
1710  virtual void name(const std::string &s) { name_ = s; }
1713  // [Robb Matzke 2016-01-22]: deprecated
1714  virtual const std::string& get_name() const ROSE_DEPRECATED("use name instead") { return name(); }
1715  virtual void set_name(const std::string &s) ROSE_DEPRECATED("use name instead") { name(s); }
1716 
1719  void print(std::ostream &stream, const std::string prefix="") const {
1720  Formatter fmt;
1721  fmt.set_line_prefix(prefix);
1722  print(stream, fmt);
1723  }
1724  virtual void print(std::ostream &stream, Formatter &fmt) const {
1725  currentState_->print(stream, fmt);
1726  }
1731  RiscOperatorsPtr obj;
1732  Formatter &fmt;
1733  public:
1734  WithFormatter(const RiscOperatorsPtr &obj, Formatter &fmt): obj(obj), fmt(fmt) {}
1735  void print(std::ostream &stream) const { obj->print(stream, fmt); }
1736  };
1737 
1745  WithFormatter with_format(Formatter &fmt) { return WithFormatter(shared_from_this(), fmt); }
1754  virtual size_t nInsns() const { return nInsns_; }
1755  virtual void nInsns(size_t n) { nInsns_ = n; }
1758  // [Robb Matzke 2016-01-22]: deprecated
1759  virtual size_t get_ninsns() const ROSE_DEPRECATED("use nInsns instead") { return nInsns(); }
1760  virtual void set_ninsns(size_t n) ROSE_DEPRECATED("use nInsns instead") { nInsns(n); }
1761 
1767  return currentInsn_;
1768  }
1769 
1770  // [Robb Matzke 2016-01-22]: deprecated
1771  virtual SgAsmInstruction *get_insn() const ROSE_DEPRECATED("use currentInstruction instead") {
1772  return currentInstruction();
1773  }
1774 
1777  virtual void startInstruction(SgAsmInstruction *insn);
1778 
1781  virtual void finishInstruction(SgAsmInstruction *insn) {
1782  ASSERT_not_null(insn);
1783  ASSERT_require(currentInsn_==insn);
1784  currentInsn_ = NULL;
1785  };
1786 
1787 
1789  // Value Construction Operations
1791  // The trailing underscores are necessary for for undefined_() on some machines, so we just add one to the end of all the
1792  // virtual constructors for consistency.
1793 
1795  virtual SValuePtr undefined_(size_t nbits) {
1796  return protoval_->undefined_(nbits);
1797  }
1798  virtual SValuePtr unspecified_(size_t nbits) {
1799  return protoval_->unspecified_(nbits);
1800  }
1801 
1803  virtual SValuePtr number_(size_t nbits, uint64_t value) {
1804  return protoval_->number_(nbits, value);
1805  }
1806 
1808  virtual SValuePtr boolean_(bool value) {
1809  return protoval_->boolean_(value);
1810  }
1811 
1813  virtual SValuePtr bottom_(size_t nbits) {
1814  return protoval_->bottom_(nbits);
1815  }
1816 
1817 
1819  // x86-specific Operations (FIXME)
1821 
1824  virtual SValuePtr filterCallTarget(const SValuePtr &a) {
1825  return a->copy();
1826  }
1827 
1831  virtual SValuePtr filterReturnTarget(const SValuePtr &a) {
1832  return a->copy();
1833  }
1834 
1838  virtual SValuePtr filterIndirectJumpTarget(const SValuePtr &a) {
1839  return a->copy();
1840  }
1841 
1843  virtual void hlt() {}
1844 
1846  virtual void cpuid() {}
1847 
1849  virtual SValuePtr rdtsc() { return unspecified_(64); }
1850 
1851 
1853  // Boolean Operations
1855 
1858  virtual SValuePtr and_(const SValuePtr &a, const SValuePtr &b) = 0;
1859 
1862  virtual SValuePtr or_(const SValuePtr &a, const SValuePtr &b) = 0;
1863 
1866  virtual SValuePtr xor_(const SValuePtr &a, const SValuePtr &b) = 0;
1867 
1869  virtual SValuePtr invert(const SValuePtr &a) = 0;
1870 
1874  virtual SValuePtr extract(const SValuePtr &a, size_t begin_bit, size_t end_bit) = 0;
1875 
1879  virtual SValuePtr concat(const SValuePtr &a, const SValuePtr &b) = 0;
1880 
1883  virtual SValuePtr leastSignificantSetBit(const SValuePtr &a) = 0;
1884 
1887  virtual SValuePtr mostSignificantSetBit(const SValuePtr &a) = 0;
1888 
1892  virtual SValuePtr rotateLeft(const SValuePtr &a, const SValuePtr &nbits) = 0;
1893 
1897  virtual SValuePtr rotateRight(const SValuePtr &a, const SValuePtr &nbits) = 0;
1898 
1902  virtual SValuePtr shiftLeft(const SValuePtr &a, const SValuePtr &nbits) = 0;
1903 
1907  virtual SValuePtr shiftRight(const SValuePtr &a, const SValuePtr &nbits) = 0;
1908 
1913  virtual SValuePtr shiftRightArithmetic(const SValuePtr &a, const SValuePtr &nbits) = 0;
1914 
1915 
1917  // Comparison Operations
1919 
1922  virtual SValuePtr equalToZero(const SValuePtr &a) = 0;
1923 
1927  virtual SValuePtr ite(const SValuePtr &cond, const SValuePtr &a, const SValuePtr &b) = 0;
1928 
1935  SValuePtr equal(const SValuePtr &a, const SValuePtr &b) ROSE_DEPRECATED("use isEqual instead");
1936  virtual SValuePtr isEqual(const SValuePtr &a, const SValuePtr &b);
1937  virtual SValuePtr isNotEqual(const SValuePtr &a, const SValuePtr &b);
1947  virtual SValuePtr isUnsignedLessThan(const SValuePtr &a, const SValuePtr &b);
1948  virtual SValuePtr isUnsignedLessThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1949  virtual SValuePtr isUnsignedGreaterThan(const SValuePtr &a, const SValuePtr &b);
1950  virtual SValuePtr isUnsignedGreaterThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1960  virtual SValuePtr isSignedLessThan(const SValuePtr &a, const SValuePtr &b);
1961  virtual SValuePtr isSignedLessThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1962  virtual SValuePtr isSignedGreaterThan(const SValuePtr &a, const SValuePtr &b);
1963  virtual SValuePtr isSignedGreaterThanOrEqual(const SValuePtr &a, const SValuePtr &b);
1966  // Integer Arithmetic Operations
1969 
1972  virtual SValuePtr unsignedExtend(const SValuePtr &a, size_t new_width) {
1973  return a->copy(new_width);
1974  }
1975 
1978  virtual SValuePtr signExtend(const SValuePtr &a, size_t new_width) = 0;
1979 
1982  virtual SValuePtr add(const SValuePtr &a, const SValuePtr &b) = 0;
1983 
1986  virtual SValuePtr subtract(const SValuePtr &minuend, const SValuePtr &subtrahend);
1987 
2004  virtual SValuePtr addWithCarries(const SValuePtr &a, const SValuePtr &b, const SValuePtr &c,
2005  SValuePtr &carry_out/*output*/) = 0;
2006 
2008  virtual SValuePtr negate(const SValuePtr &a) = 0;
2009 
2011  virtual SValuePtr signedDivide(const SValuePtr &a, const SValuePtr &b) = 0;
2012 
2014  virtual SValuePtr signedModulo(const SValuePtr &a, const SValuePtr &b) = 0;
2015 
2017  virtual SValuePtr signedMultiply(const SValuePtr &a, const SValuePtr &b) = 0;
2018 
2020  virtual SValuePtr unsignedDivide(const SValuePtr &a, const SValuePtr &b) = 0;
2021 
2023  virtual SValuePtr unsignedModulo(const SValuePtr &a, const SValuePtr &b) = 0;
2024 
2026  virtual SValuePtr unsignedMultiply(const SValuePtr &a, const SValuePtr &b) = 0;
2027 
2028 
2030  // Interrupt and system calls
2032 
2037  virtual void interrupt(int majr, int minr) {}
2038 
2039 
2041  // Floating-point operations
2042  //
2043  // For now these all have default implementations that throw NotImplemented, but we might change them to pure virtual
2044  // sometime in the future so they're consistent with most other RISC operators. [Robb P. Matzke 2015-08-03]
2046 
2048  virtual SValuePtr fpFromInteger(const SValuePtr &intValue, SgAsmFloatType *fpType);
2049 
2055  virtual SValuePtr fpToInteger(const SValuePtr &fpValue, SgAsmFloatType *fpType, const SValuePtr &dflt);
2056 
2060  virtual SValuePtr fpConvert(const SValuePtr &a, SgAsmFloatType *aType, SgAsmFloatType *retType);
2061 
2063  virtual SValuePtr fpIsNan(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2064 
2066  virtual SValuePtr fpIsDenormalized(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2067 
2069  virtual SValuePtr fpIsZero(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2070 
2075  virtual SValuePtr fpIsInfinity(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2076 
2080  virtual SValuePtr fpSign(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2081 
2087  virtual SValuePtr fpEffectiveExponent(const SValuePtr &fpValue, SgAsmFloatType *fpType);
2088 
2092  virtual SValuePtr fpAdd(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2093 
2098  virtual SValuePtr fpSubtract(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2099 
2103  virtual SValuePtr fpMultiply(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2104 
2108  virtual SValuePtr fpDivide(const SValuePtr &a, const SValuePtr &b, SgAsmFloatType *fpType);
2109 
2113  virtual SValuePtr fpSquareRoot(const SValuePtr &a, SgAsmFloatType *fpType);
2114 
2118  virtual SValuePtr fpRoundTowardZero(const SValuePtr &a, SgAsmFloatType *fpType);
2119 
2120 
2122  // State Accessing Operations
2124 
2149  virtual SValuePtr readRegister(RegisterDescriptor reg) { // old subclasses can still override this if they want,
2150  return readRegister(reg, undefined_(reg.get_nbits())); // but new subclasses should not override this method.
2151  }
2152  virtual SValuePtr readRegister(RegisterDescriptor reg, const SValuePtr &dflt); // new subclasses override this
2164  virtual void writeRegister(RegisterDescriptor reg, const SValuePtr &a) {
2165  ASSERT_not_null(currentState_);
2166  currentState_->writeRegister(reg, a, this);
2167  }
2168 
2191  virtual SValuePtr readMemory(RegisterDescriptor segreg, const SValuePtr &addr, const SValuePtr &dflt,
2192  const SValuePtr &cond) = 0;
2193 
2204  virtual void writeMemory(RegisterDescriptor segreg, const SValuePtr &addr, const SValuePtr &data,
2205  const SValuePtr &cond) = 0;
2206 
2212  virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt);
2213 };
2214 
2215 
2216 
2218 // Instruction Dispatcher
2220 
2222 typedef boost::shared_ptr<class Dispatcher> DispatcherPtr;
2223 
2226 public:
2227  virtual ~InsnProcessor() {}
2228  virtual void process(const DispatcherPtr &dispatcher, SgAsmInstruction *insn) = 0;
2229 };
2230 
2244 class Dispatcher: public boost::enable_shared_from_this<Dispatcher> {
2245 protected:
2246  RiscOperatorsPtr operators;
2248  size_t addrWidth_;
2251  // Dispatchers keep a table of all the kinds of instructions they can handle. The lookup key is typically some sort of
2252  // instruction identifier, such as from SgAsmX86Instruction::get_kind(), and comes from the iproc_key() virtual method.
2253  typedef std::vector<InsnProcessor*> InsnProcessors;
2254  InsnProcessors iproc_table;
2255 
2256 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
2257 private:
2258  friend class boost::serialization::access;
2259 
2260  template<class S>
2261  void serialize(S &s, const unsigned version) {
2262  s & BOOST_SERIALIZATION_NVP(operators);
2263  s & BOOST_SERIALIZATION_NVP(regdict);
2264  s & BOOST_SERIALIZATION_NVP(addrWidth_);
2265  s & BOOST_SERIALIZATION_NVP(autoResetInstructionPointer_);
2266  //s & iproc_table; -- not saved
2267  }
2268 #endif
2269 
2271  // Real constructors
2272 protected:
2273  // Prototypical constructor
2274  Dispatcher(): regdict(NULL), addrWidth_(0), autoResetInstructionPointer_(true) {}
2275 
2276  // Prototypical constructor
2277  Dispatcher(size_t addrWidth, const RegisterDictionary *regs)
2278  : regdict(regs), addrWidth_(addrWidth), autoResetInstructionPointer_(true) {}
2279 
2280  Dispatcher(const RiscOperatorsPtr &ops, size_t addrWidth, const RegisterDictionary *regs)
2281  : operators(ops), regdict(regs), addrWidth_(addrWidth), autoResetInstructionPointer_(true) {
2282  ASSERT_not_null(operators);
2283  ASSERT_not_null(regs);
2284  }
2285 
2286 public:
2288  typedef DispatcherPtr Ptr;
2289 
2290 public:
2291  virtual ~Dispatcher() {
2292  for (InsnProcessors::iterator iter=iproc_table.begin(); iter!=iproc_table.end(); ++iter)
2293  delete *iter;
2294  }
2295 
2297  // Static allocating constructors. None since this is an abstract class
2298 
2299 
2301  // Virtual constructors
2302 public:
2304  virtual DispatcherPtr create(const RiscOperatorsPtr &ops, size_t addrWidth=0, const RegisterDictionary *regs=NULL) const = 0;
2305 
2307  // Methods to process instructions
2308 public:
2310  virtual void processInstruction(SgAsmInstruction *insn);
2311 
2313  // Instruction processor table operations
2314 public:
2318  virtual InsnProcessor *iproc_lookup(SgAsmInstruction *insn);
2319 
2323  virtual void iproc_replace(SgAsmInstruction *insn, InsnProcessor *iproc);
2324 
2326  virtual int iproc_key(SgAsmInstruction*) const = 0;
2327 
2331  virtual void iproc_set(int key, InsnProcessor *iproc);
2332 
2334  virtual InsnProcessor *iproc_get(int key);
2335 
2337  // Convenience methods that defer the call to some member object
2338 public:
2340  virtual RiscOperatorsPtr get_operators() const { return operators; }
2341 
2344  virtual StatePtr currentState() const { return operators ? operators->currentState() : StatePtr(); }
2345 
2346  // [Robb Matzke 2016-01-22]: deprecated
2347  virtual StatePtr get_state() const ROSE_DEPRECATED("use currentState instead") {
2348  return currentState();
2349  }
2350 
2352  virtual SValuePtr protoval() const { return operators ? operators->protoval() : SValuePtr(); }
2353 
2354  // [Robb Matzke 2016-01-22]: deprecated
2355  virtual SValuePtr get_protoval() const ROSE_DEPRECATED("use protoval instead") {
2356  return protoval();
2357  }
2358 
2364  return operators ? operators->currentInstruction() : NULL;
2365  }
2366 
2367  // [Robb Matzke 2016-01-22]: deprecated
2368  virtual SgAsmInstruction *get_insn() const ROSE_DEPRECATED("use currentInstruction instead") {
2369  return currentInstruction();
2370  }
2371 
2373  virtual SValuePtr undefined_(size_t nbits) const {
2374  ASSERT_not_null(operators);
2375  return operators->undefined_(nbits);
2376  }
2377  virtual SValuePtr unspecified_(size_t nbits) const {
2378  ASSERT_not_null(operators);
2379  return operators->unspecified_(nbits);
2380  }
2381 
2383  virtual SValuePtr number_(size_t nbits, uint64_t number) const {
2384  ASSERT_not_null(operators);
2385  return operators->number_(nbits, number);
2386  }
2387 
2389  // Methods related to registers
2390 public:
2403  return regdict;
2404  }
2405  virtual void set_register_dictionary(const RegisterDictionary *regdict) {
2406  this->regdict = regdict;
2407  }
2414  virtual RegisterDescriptor findRegister(const std::string &regname, size_t nbits=0, bool allowMissing=false) const;
2415 
2422  size_t addressWidth() const { return addrWidth_; }
2423  void addressWidth(size_t nbits);
2427  virtual RegisterDescriptor instructionPointerRegister() const = 0;
2428 
2430  virtual RegisterDescriptor stackPointerRegister() const = 0;
2431 
2438  bool autoResetInstructionPointer() const { return autoResetInstructionPointer_; }
2439  void autoResetInstructionPointer(bool b) { autoResetInstructionPointer_ = b; }
2443  // Miscellaneous methods that tend to be the same for most dispatchers
2445 public:
2446 
2455  virtual void advanceInstructionPointer(SgAsmInstruction*);
2456 
2460  virtual RegisterDescriptor segmentRegister(SgAsmMemoryReferenceExpression*);
2461 
2465  virtual void incrementRegisters(SgAsmExpression*);
2466 
2470  virtual void decrementRegisters(SgAsmExpression*);
2471 
2475  virtual SValuePtr effectiveAddress(SgAsmExpression*, size_t nbits=0);
2476 
2482  virtual SValuePtr read(SgAsmExpression*, size_t value_nbits=0, size_t addr_nbits=0);
2483 
2487  virtual void write(SgAsmExpression*, const SValuePtr &value, size_t addr_nbits=0);
2488 };
2489 
2490 
2491 
2493 // Printing
2495 
2496 std::ostream& operator<<(std::ostream&, const Exception&);
2497 std::ostream& operator<<(std::ostream&, const SValue&);
2498 std::ostream& operator<<(std::ostream&, const SValue::WithFormatter&);
2499 std::ostream& operator<<(std::ostream&, const MemoryState&);
2500 std::ostream& operator<<(std::ostream&, const MemoryState::WithFormatter&);
2501 std::ostream& operator<<(std::ostream&, const RegisterState&);
2502 std::ostream& operator<<(std::ostream&, const RegisterState::WithFormatter&);
2503 std::ostream& operator<<(std::ostream&, const State&);
2504 std::ostream& operator<<(std::ostream&, const State::WithFormatter&);
2505 std::ostream& operator<<(std::ostream&, const RiscOperators&);
2506 std::ostream& operator<<(std::ostream&, const RiscOperators::WithFormatter&);
2507 
2508 } // namespace
2509 } // namespace
2510 } // namespace
2511 } // namespace
2512 
2513 #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 SmtSolver * solver() const
Property: Satisfiability module theory (SMT) solver.
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 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.
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 bool may_equal(const SValuePtr &other, SmtSolver *solver=NULL) const =0
Returns true if two values could be equal.
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.
static const size_t n_st
Number of ST registers (not counting _st_top pseudo register).
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.
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 void solver(SmtSolver *s)
Property: Satisfiability module theory (SMT) solver.
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.
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.
virtual bool must_equal(const SValuePtr &other, SmtSolver *solver=NULL) const =0
Returns true if two values must be equal.
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 Sawyer::Optional< SValuePtr > createOptionalMerge(const SValuePtr &other, const MergerPtr &merger, SmtSolver *solver) const =0
Possibly create a new value by merging two existing values.
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.
SValuePtr createMerged(const SValuePtr &other, const MergerPtr &merger, SmtSolver *solver) const
Create a new value by merging two existing values.
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.
Interface to Satisfiability Modulo Theory (SMT) solvers.
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.
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.
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.