ROSE  0.11.2.0
BinaryConcolic.h
1 #ifndef ROSE_BinaryAnalysis_Concolic_H
2 #define ROSE_BinaryAnalysis_Concolic_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_CONCOLIC_TESTING
5 
6 // Which database implementation should be used
7 // Version 1 was implemented as part of ROSE in 2019 and supports only SQLite
8 // Version 2 is from Sawyer and supports SQLite and PostgreSQL
9 #ifndef ROSE_CONCOLIC_DB_VERSION
10 #define ROSE_CONCOLIC_DB_VERSION 2
11 #endif
12 
13 // ROSE headers
14 #include <Diagnostics.h>
15 #include <Partitioner2/BasicTypes.h>
16 #include <rose_isnan.h>
17 #include <rose_strtoull.h>
18 #include <RoseException.h>
19 #if ROSE_CONCOLIC_DB_VERSION == 1
20  #include <SqlDatabase.h>
21 #else
22  #include <Sawyer/Database.h>
23 #endif
24 
25 // Non-ROSE headers
26 #include <boost/filesystem.hpp>
27 
28 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
29 #include <boost/serialization/export.hpp>
30 #include <boost/serialization/access.hpp>
31 #include <boost/serialization/nvp.hpp>
32 #include <boost/serialization/base_object.hpp>
33 #include <boost/archive/text_iarchive.hpp>
34 #include <boost/archive/text_oarchive.hpp>
35 #include <boost/archive/xml_iarchive.hpp>
36 #include <boost/archive/xml_oarchive.hpp>
37 #endif /* ROSE_HAVE_BOOST_SERIALIZATION_LIB */
38 
39 #include <boost/numeric/conversion/cast.hpp>
40 #include <memory>
41 #include <Sawyer/BiMap.h>
42 #include <Sawyer/SharedObject.h>
43 #include <Sawyer/SharedPointer.h>
44 #include <Sawyer/Synchronization.h>
45 #include <stdexcept>
46 #include <string>
47 #include <vector>
48 
49 namespace Rose {
50 namespace BinaryAnalysis {
51 
74 namespace Concolic {
75 
77 // Flags and enums
79 
80 namespace Update {
81 enum Flag { NO, YES };
82 } // namespace
83 
85 // Exceptions, errors, etc.
87 
89 extern Sawyer::Message::Facility mlog;
90 
91 // Internal: called by Rose::Diagnostics::initialize
92 void initDiagnostics();
93 
95 class Exception: public Rose::Exception {
96 public:
97  explicit Exception(const std::string &mesg): Rose::Exception(mesg) {}
98  ~Exception() throw () {}
99 };
100 
102 // Forward references
104 
105 class Specimen;
106 typedef Sawyer::SharedPointer<Specimen> SpecimenPtr;
107 
108 class TestCase;
109 typedef Sawyer::SharedPointer<TestCase> TestCasePtr;
110 
111 class ConcreteExecutor;
112 typedef Sawyer::SharedPointer<ConcreteExecutor> ConcreteExecutorPtr;
113 
114 class LinuxExecutor;
115 typedef Sawyer::SharedPointer<LinuxExecutor> LinuxExecutorPtr;
116 
117 class ConcolicExecutor;
118 typedef Sawyer::SharedPointer<ConcolicExecutor> ConcolicExecutorPtr;
119 
120 class TestSuite;
121 typedef Sawyer::SharedPointer<TestSuite> TestSuitePtr;
122 
123 class Database;
124 typedef Sawyer::SharedPointer<Database> DatabasePtr;
125 
126 class ExecutionManager;
127 typedef Sawyer::SharedPointer<ExecutionManager> ExecutionManagerPtr;
128 
129 class LinuxExitStatus;
130 typedef Sawyer::SharedPointer<LinuxExitStatus> LinuxExitStatusPtr;
131 
133 // Specimens
135 
140 class Specimen: public Sawyer::SharedObject, public Sawyer::SharedFromThis<Specimen> {
141 public:
144 
146  typedef std::vector<uint8_t> BinaryData;
147 
148 private:
149  mutable SAWYER_THREAD_TRAITS::Mutex mutex_; // protects the following data members
150  std::string name_; // name of specimen (e.g., for debugging)
151  std::string timestamp_; // time of creation
152  BinaryData content_; // content of the binary executable file
153  mutable bool read_only_; // safe guards from writing content after it has been shared;
154  bool empty_; // indicates if this object is empty
155 
156 private:
157  friend class boost::serialization::access;
158 
159  template<class S>
160  void serialize(S &s, const unsigned /*version*/) {
161  s & BOOST_SERIALIZATION_NVP(name_);
162  s & BOOST_SERIALIZATION_NVP(content_);
163  s & BOOST_SERIALIZATION_NVP(empty_);
164  }
165 
166 protected:
167  Specimen()
168  : read_only_(false), empty_(false)
169  {}
170 
171 public:
174  static Ptr instance(const boost::filesystem::path &executableName);
175  static Ptr instance();
184  void open(const boost::filesystem::path &executableName);
185 
192  void close();
193 
199  bool isEmpty() const;
200 
209  std::string name() const; // value return is intentional for thread safety
210  void name(const std::string&);
218  std::string printableName(const DatabasePtr &db = DatabasePtr());
219 
230  std::string timestamp() const;
231  void timestamp(const std::string&);
240  const std::vector<uint8_t>& content() const;
241 
242  // FIXME[Robb Matzke 2019-08-12]: content is read-only, created by constructor. Therefore this member shouldn't be defined,
243  // or at least should be private.
246  void content(std::vector<uint8_t> binary_data);
247 };
248 
250 // Test cases
252 
254 typedef std::pair<std::string /*name*/, std::string /*value*/> EnvValue;
255 
259 class TestCase: public Sawyer::SharedObject, public Sawyer::SharedFromThis<TestCase> {
260 public:
263 
264 private:
265  mutable SAWYER_THREAD_TRAITS::Mutex mutex_; // protects the following data members
266  std::string name_; // name for debugging
267  std::string timestamp_; // time of creation
268  std::string executor_; // name of execution environment
269  Specimen::Ptr specimen_; // the thing to run
270  std::vector<std::string> args_; // command line arguments
271  std::vector<EnvValue> env_; // environment variables
272  Sawyer::Optional<size_t> concolicResult_; // non-empty if concolically tested
273  Sawyer::Optional<double> concreteRank_; // rank after testing
274  bool concreteIsInteresting_; // concrete results present and interesting?
275 
276 protected:
277  TestCase()
278  : concreteIsInteresting_(false) {}
279 
280 public:
282  static Ptr instance() {
283  return Ptr(new TestCase);
284  }
285 
287  static Ptr instance(const Specimen::Ptr &specimen);
288 
297  std::string name() const; // value return is intentional for thread safety
298  void name(const std::string&);
306  std::string printableName(const DatabasePtr &db = DatabasePtr());
307 
318  std::string timestamp() const;
319  void timestamp(const std::string&);
329  Specimen::Ptr specimen() const;
330  void specimen(const Specimen::Ptr&);
338  std::vector<std::string> args() const;
339  void args(std::vector<std::string> arguments);
344  std::vector<EnvValue> env() const;
345  void env(std::vector<EnvValue> envvars);
353  Sawyer::Optional<size_t> concolicResult() const {
354  return concolicResult_;
355  }
356  void concolicResult(const Sawyer::Optional<size_t> &x) {
357  concolicResult_ = x;
358  }
362  bool hasConcolicTest() const;
363 
369  Sawyer::Optional<double> concreteRank() const;
370  void concreteRank(Sawyer::Optional<double> val);
381  bool concreteIsInteresting() const;
382  void concreteIsInteresting(bool);
388  bool hasConcreteTest() const;
389 
393  const std::string& executor() const {
394  return executor_;
395  }
396  void executor(const std::string &x) {
397  executor_ = x;
398  }
401  // We'll need to add additional information about how to run the specimen:
402  // 3. Auxilliary vector (auxv)
403  // 4. System calls that provide input (e.g., virtual file system, network, etc.)
404  // Some of this information might need to be separated into subclasses that support different architectures since the
405  // info for testing a Linux ELF executable is different from a Windows PE executable, which is different from how one
406  // would run firmware.
407 };
408 
409 
411 // Concrete executors and their results
413 
414 extern const char* const tagConcreteExecutorResult;
415 extern const char* const tagLinuxExecutorResult;
416 
427 class ConcreteExecutor: public Sawyer::SharedObject {
428 public:
431 
442  class Result {
443  private:
444  double rank_;
445  bool isInteresting_;
446 
447  public:
448  Result()
449  : rank_(0.0), isInteresting_(true) {}
450 
451  explicit Result(double rank)
452  : rank_(rank), isInteresting_(true) {
453  ASSERT_forbid(rose_isnan(rank));
454  }
455 
456  virtual ~Result() {}
457 
458  double rank() const { return rank_; }
459  void rank(double r) { rank_ = r; }
460 
461  bool isInteresting() const { return isInteresting_; }
462  void isInteresting(bool b) { isInteresting_ = b; }
463 
464  private:
465  friend class boost::serialization::access;
466 
467  template<class S>
468  void serialize(S &s, const unsigned /*version*/) {
469  s & BOOST_SERIALIZATION_NVP(rank_);
470  }
471  };
472 
473 private:
474  DatabasePtr db_;
475 
476 protected:
477  // Allocating constructors should be implemente by the non-abstract subclasses.
478  explicit ConcreteExecutor(const DatabasePtr&);
479 
480 public:
482  DatabasePtr database() const;
483 
488  virtual Result* execute(const TestCase::Ptr&) = 0;
489 
490  // FIXME[Robb Matzke 2020-07-14]: This should be in a subclass
513  void executionMonitor(const boost::filesystem::path& executorName)
514  {
515  execmon = executorName;
516  }
517 
518  // FIXME[Robb Matzke 2020-07-14]: This should be in a subclass
519  boost::filesystem::path executionMonitor() const
520  {
521  return execmon;
522  }
525 private:
526  // FIXME[Robb Matzke 2020-07-14]: This should be in a subclass
527  boost::filesystem::path execmon; // the execution monitor
528 };
529 
533 class LinuxTraceExecutor: public ConcreteExecutor {
534 public:
537 
539  class Result: public ConcreteExecutor::Result {
540  public:
541  int exitStatus; // as returned by wait
542  AddressSet executedVas;
543 
544  private:
545  friend class boost::serialization::access;
546 
547  template<class S>
548  void serialize(S &s, const unsigned /*version*/) {
549  s & boost::serialization::make_nvp("base", boost::serialization::base_object<ConcreteExecutor::Result>(*this));
550  s & BOOST_SERIALIZATION_NVP(executedVas);
551  }
552  };
553 
554 protected:
555  explicit LinuxTraceExecutor(const DatabasePtr&);
556 
557 public:
559  static Ptr instance(const DatabasePtr&);
560 
562  static int exitStatus(const ConcreteExecutor::Result*);
563 
565  const AddressSet& executedVas(const ConcreteExecutor::Result*);
566 
567  ConcreteExecutor::Result* execute(const TestCase::Ptr&) override;
568 };
569 
571 class LinuxExecutor: public ConcreteExecutor {
572 public:
575 
577  typedef Sawyer::Optional<unsigned long> Persona;
578 
580  class Result: public ConcreteExecutor::Result {
581  protected:
582  int exitStatus_;
583  std::string exitKind_;
584  std::string capturedOut_;
585  std::string capturedErr_;
587  private:
588  friend class boost::serialization::access;
589 
590  template<class S>
591  void serialize(S &s, const unsigned /*version*/) {
592  // was: s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(ConcreteExecutor::Result);
593  // nvp of a base class in a different namespace seems to produce
594  // invalid results.
595  s & boost::serialization::make_nvp( tagConcreteExecutorResult,
596  boost::serialization::base_object<ConcreteExecutor::Result>(*this)
597  );
598  s & BOOST_SERIALIZATION_NVP(exitStatus_);
599  s & BOOST_SERIALIZATION_NVP(exitKind_);
600  s & BOOST_SERIALIZATION_NVP(capturedOut_);
601  s & BOOST_SERIALIZATION_NVP(capturedErr_);
602  }
603 
604  public:
605  Result(double rank, int exitStatus);
606 
607  Result() {} // required for boost serialization
608 
616  int exitStatus() const { return exitStatus_; }
617  void exitStatus(int x);
623  std::string out() const { return capturedOut_; }
624  void out(const std::string& output) { capturedOut_ = output; }
625 
626  std::string err() const { return capturedErr_; }
627  void err(const std::string& output) { capturedErr_ = output; }
633  std::string exitKind() const { return exitKind_; }
634  /* @} */
635  };
636 
637 protected:
638  bool useAddressRandomization_; // enable/disable address space randomization in the OS
639 
640 protected:
641  explicit LinuxExecutor(const DatabasePtr&);
642 
643 public:
645  static Ptr instance(const DatabasePtr&);
646 
653  bool useAddressRandomization() const { return useAddressRandomization_; }
654  void useAddressRandomization(bool b) { useAddressRandomization_ = b; }
657  virtual
658  Result* execute(const TestCase::Ptr&) ROSE_OVERRIDE;
659 };
660 
662 // Concolic (concrete + symbolic) executors
664 
665 } // namespace
666 } // namespace
667 } // namespace
668 
669 #include <Concolic/ConcolicExecutor.h>
670 
671 namespace Rose {
672 namespace BinaryAnalysis {
673 namespace Concolic {
674 
676 // Test suites
678 
691 class TestSuite: public Sawyer::SharedObject, public Sawyer::SharedFromThis<TestSuite> {
692 public:
695 
696 private:
697  mutable SAWYER_THREAD_TRAITS::Mutex mutex_; // protects the following data members
698  std::string name_; // unique and non-empty within a database
699  std::string timestamp_; // time of creation
700 
701 protected:
702  TestSuite() {}
703 
704 public:
706  static Ptr instance(const std::string &name = "");
707 
716  std::string name() const; // value return is intentional for thread safety
717  void name(const std::string&);
725  std::string printableName(const DatabasePtr &db = DatabasePtr());
726 
737  std::string timestamp() const;
738  void timestamp(const std::string&);
740 };
741 
743 // Databases
745 
747 template <class Tag>
748 class ObjectId: public Sawyer::Optional<size_t> {
749 public:
750  typedef size_t Value;
751  typedef Sawyer::Optional<Value> Super;
752  typedef Tag Object;
754  ObjectId() {}
755 
756  explicit
757  ObjectId(const Value& v)
758  : Super(v) {}
759 
760  ObjectId(const ObjectId& rhs)
761  : Super(rhs) {}
762 
763  explicit ObjectId(const Sawyer::Optional<size_t> &id)
764  : Super(id) {}
765 
771  explicit ObjectId(const std::string &s) {
772  char *rest = NULL;
773  uint64_t id = rose_strtoull(s.c_str(), &rest, 0);
774  while (*rest && isspace(*rest)) ++rest;
775  if (*rest)
776  throw Exception("invalid syntax for object ID: \"" + StringUtility::cEscape(s) + "\"");
777  try {
778  *this = boost::numeric_cast<Value>(id);
779  } catch (const boost::bad_numeric_cast&) {
780  throw Exception("parsed object ID out of range: \"" + StringUtility::cEscape(s) + "\"");
781  }
782  }
783 
785  ObjectId<Tag>& operator=(const ObjectId<Tag>& lhs) {
786  this->Super::operator=(lhs);
787  return *this;
788  }
789 
791  ObjectId<Tag>& operator=(const Value& v) {
792  this->Super::operator=(v);
793  return *this;
794  }
795 
796  explicit operator bool() const { // because it's not explicit in the super class due to C++03 support
797  return isEqual(Sawyer::Nothing()) ? false : true;
798  }
799 
801  template<class _Tag>
802  friend
803  bool operator<(const ObjectId<_Tag>& lhs, const ObjectId<_Tag>& rhs);
804 };
805 
807 template<class Tag>
808 inline
809 bool operator<(const ObjectId<Tag>& lhs, const ObjectId<Tag>& rhs)
810 {
811  if (!rhs) return false;
812  if (!lhs) return true;
813 
814  return lhs.get() < rhs.get();
815 }
816 
817 typedef ObjectId<TestSuite> TestSuiteId;
818 typedef ObjectId<Specimen> SpecimenId;
819 typedef ObjectId<TestCase> TestCaseId;
824 template<class T>
825 struct ObjectTraits {
826  using Id = void;
827 };
828 
829 template<>
830 struct ObjectTraits<TestSuite> {
831  using Id = TestSuiteId;
832 };
833 
834 template<>
835 struct ObjectTraits<Specimen> {
836  using Id = SpecimenId;
837 };
838 
839 template<>
840 struct ObjectTraits<TestCase> {
841  using Id = TestCaseId;
842 };
843 
856 class Database: public Sawyer::SharedObject, public Sawyer::SharedFromThis<Database>, boost::noncopyable {
857 public:
860 
861  typedef ::Rose::BinaryAnalysis::Concolic::TestSuiteId TestSuiteId;
862  typedef ::Rose::BinaryAnalysis::Concolic::SpecimenId SpecimenId;
863  typedef ::Rose::BinaryAnalysis::Concolic::TestCaseId TestCaseId;
864 
865 private:
866 #if ROSE_CONCOLIC_DB_VERSION == 1
867  SqlDatabase::ConnectionPtr dbconn_; // connection to database
868 #else
869  Sawyer::Database::Connection connection_;
870 #endif
871 
872  // Memoization of ID to object mappings
876 
877  TestSuiteId testSuiteId_; // database scope is restricted to this single test suite
878 
879 protected:
880  Database() {}
881 
882 public:
889  static Ptr instance(const std::string &url);
890 
892 #if ROSE_CONCOLIC_DB_VERSION == 1
893  SqlDatabase::ConnectionPtr connection() {
894  return dbconn_;
895  }
896 #else
897  Sawyer::Database::Connection connection() {
898  return connection_;
899  }
900 #endif
901 
912  static Ptr create(const std::string &url);
913  static Ptr create(const std::string &url, const std::string &testSuiteName);
915  //------------------------------------------------------------------------------------------------------------------------
916  // Test suites
917  //------------------------------------------------------------------------------------------------------------------------
918 
923  std::vector<TestSuiteId> testSuites();
924 
932  TestSuite::Ptr testSuite();
933  TestSuiteId testSuite(const TestSuite::Ptr&);
936  //------------------------------------------------------------------------------------------------------------------------
937  // Specimens
938  //------------------------------------------------------------------------------------------------------------------------
939 
944  std::vector<SpecimenId> specimens();
945 
946  //------------------------------------------------------------------------------------------------------------------------
947  // Test cases
948  //------------------------------------------------------------------------------------------------------------------------
949 
954  std::vector<TestCaseId> testCases();
955 
956  //------------------------------------------------------------------------------------------------------------------------
957  // Overloaded methods for all objects.
958  //------------------------------------------------------------------------------------------------------------------------
959 
966  TestSuite::Ptr object(TestSuiteId, Update::Flag update = Update::YES);
967  TestCase::Ptr object(TestCaseId, Update::Flag update = Update::YES);
968  Specimen::Ptr object(SpecimenId, Update::Flag update = Update::YES);
971 #if ROSE_CONCOLIC_DB_VERSION == 1
972 
976  Specimen::Ptr object_ns(SqlDatabase::TransactionPtr tx, SpecimenId id);
977 #endif
978 
987  TestSuiteId id(const TestSuite::Ptr&, Update::Flag update = Update::YES);
988  TestCaseId id(const TestCase::Ptr&, Update::Flag update = Update::YES);
989  SpecimenId id(const Specimen::Ptr&, Update::Flag update = Update::YES);
996  template<class ObjectPointer>
997  typename ObjectTraits<typename ObjectPointer::Pointee>::Id save(const ObjectPointer &obj) {
998  return id(obj);
999  }
1000 
1001 #if ROSE_CONCOLIC_DB_VERSION == 1
1002 
1008  TestSuiteId id_ns(SqlDatabase::TransactionPtr, const TestSuite::Ptr&, Update::Flag update = Update::YES);
1009  TestCaseId id_ns(SqlDatabase::TransactionPtr, const TestCase::Ptr&, Update::Flag update = Update::YES);
1010  SpecimenId id_ns(SqlDatabase::TransactionPtr, const Specimen::Ptr&, Update::Flag update = Update::YES);
1011 #endif
1012 
1019  TestSuite::Ptr findTestSuite(const std::string &nameOrId);
1020 
1025  std::vector<SpecimenId> findSpecimensByName(const std::string &name);
1026 
1027  //------------------------------------------------------------------------------------------------------------------------
1028  // Cached info about disassembly. This is large data. Each specimen has zero or one associated RBA data blob.
1029  //------------------------------------------------------------------------------------------------------------------------
1030 
1037  bool rbaExists(SpecimenId);
1038 
1047  void saveRbaFile(const boost::filesystem::path&, SpecimenId);
1048 
1057  void extractRbaFile(const boost::filesystem::path&, SpecimenId);
1058 
1064  void eraseRba(SpecimenId);
1065 
1066  //------------------------------------------------------------------------------------------------------------------------
1067  // Cached concrete execution results. This is large data. Each test case has zero or one associated concrete results.
1068  //------------------------------------------------------------------------------------------------------------------------
1069 
1074  bool concreteResultExists(TestCaseId);
1075 
1083  void saveConcreteResult(const TestCase::Ptr&, const ConcreteExecutor::Result*);
1084 
1089  std::unique_ptr<ConcreteExecutor::Result> readConcreteResult(TestCaseId);
1090 
1099  void assocTestCaseWithTestSuite(TestCaseId, TestSuiteId);
1100 
1105  std::vector<TestCaseId> needConcreteTesting(size_t n = UNLIMITED);
1106 
1111  std::vector<TestCaseId> needConcolicTesting(size_t n = UNLIMITED);
1112 
1113 #if 0 // [Robb Matzke 2020-07-15]
1114  // Use saveConcreteResults instead, which allows concrete results to also be removed.
1122  void insertConcreteResults(const TestCase::Ptr &testCase, const ConcreteExecutor::Result& details);
1123 #endif
1124 
1129  bool hasUntested();
1130 
1131 private:
1132 #if ROSE_CONCOLIC_DB_VERSION == 2
1133  static Ptr create(const std::string &url, const Sawyer::Optional<std::string> &testSuiteName);
1134 #endif
1135 };
1136 
1137 
1139 // Execution manager
1141 
1146 class ExecutionManager: boost::noncopyable, public Sawyer::SharedObject {
1147 public:
1150 
1151 private:
1152  Database::Ptr database_;
1153 
1154 protected:
1155  // Subclasses should implement allocating constructors
1156  explicit ExecutionManager(const Database::Ptr &db)
1157  : database_(db) {
1158  ASSERT_not_null(db);
1159  }
1160 
1161 public:
1162  virtual ~ExecutionManager() {}
1163 
1167  Database::Ptr database() const;
1168 
1175  virtual std::vector<Database::TestCaseId> pendingConcreteResults(size_t n = UNLIMITED);
1176  Database::TestCaseId pendingConcreteResult() /*final*/;
1184  virtual void insertConcreteResults(const TestCase::Ptr&, const ConcreteExecutor::Result &details);
1185 
1192  virtual std::vector<Database::TestCaseId> pendingConcolicResults(size_t n = UNLIMITED);
1193  Database::TestCaseId pendingConcolicResult() /*final*/;
1201  virtual void insertConcolicResults(const TestCase::Ptr &original, const std::vector<TestCase::Ptr> &newCases);
1202 
1206  virtual bool isFinished() const;
1207 
1212  virtual void run() = 0;
1213 };
1214 
1216 // Example execution manager
1218 
1223 class LinuxExitStatus: public ExecutionManager {
1224 public:
1227 
1228 protected:
1229  explicit LinuxExitStatus(const Database::Ptr &db): ExecutionManager(db) {}
1230 
1231 public:
1236  static Ptr create(const std::string databaseUrl, const boost::filesystem::path &executableName,
1237  const std::vector<std::string> &arguments);
1238 
1244  static Ptr instance(const std::string& databaseUri, const std::string &testSuiteName = "");
1245 
1246  virtual void run() ROSE_OVERRIDE;
1247 };
1248 
1251 void writeDBSchema(std::ostream& os);
1252 
1255 void writeSqlStmts(std::ostream& os);
1256 
1257 
1258 } // namespace
1259 } // namespace
1260 } // namespace
1261 
1262 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1263 //~ BOOST_CLASS_EXPORT_GUID(LinuxExecutor::Result, "LinuxExecutor::Result")
1264 
1265 //~ BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::Concolic::ConcreteExecutor::Result)
1266 //~ BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::Concolic::LinuxExecutor::Result)
1267 
1268 BOOST_CLASS_EXPORT_KEY2( Rose::BinaryAnalysis::Concolic::ConcreteExecutor::Result,
1269  Rose::BinaryAnalysis::Concolic::tagConcreteExecutorResult
1270  )
1271 BOOST_CLASS_EXPORT_KEY2( Rose::BinaryAnalysis::Concolic::LinuxExecutor::Result,
1272  Rose::BinaryAnalysis::Concolic::tagLinuxExecutorResult
1273  )
1274 
1275 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::Concolic::LinuxTraceExecutor::Result);
1276 #endif /* ROSE_HAVE_BOOST_SERIALIZATION_LIB */
1277 
1278 #endif
1279 #endif
Sawyer::SharedPointer< Node > Ptr
Shared-ownership pointer to an expression Node.
const size_t UNLIMITED(-1)
Effictively unlimited size.
Allow parallel edges, so each edge has a unit count.
Definition: BasicTypes.h:39
Collection of streams.
Definition: Message.h:1599
boost::shared_ptr< Transaction > TransactionPtr
Shared-ownership pointer to a transaction.
Definition: SqlDatabase.h:147
Enum type for allowing parallel edges.
Definition: BasicTypes.h:38
STL namespace.
Main namespace for the ROSE library.
ROSE_UTIL_API std::string cEscape(const std::string &, char context= '"')
Escapes characters that are special to C/C++.
One-to-one mapping between source and target values.
Definition: BiMap.h:26
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
Flag
Flag to pass as type stringification style.
Creates SharedPointer from this.
size_t Id
Attribute identification.
Definition: Attribute.h:140
boost::shared_ptr< Connection > ConnectionPtr
Shared-ownership pointer to a database connection.
Definition: SqlDatabase.h:137
Base class for reference counted objects.
Definition: SharedObject.h:64
Represents no value.
Definition: Optional.h:32
Base class for all ROSE exceptions.
Definition: RoseException.h:9