ROSE  0.11.51.0
ExecutionEvent.h
1 #ifndef ROSE_BinaryAnalysis_Concolic_ExecutionEvent_H
2 #define ROSE_BinaryAnalysis_Concolic_ExecutionEvent_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_CONCOLIC_TESTING
5 
6 #include <Rose/BinaryAnalysis/Concolic/BasicTypes.h>
7 #include <Rose/BinaryAnalysis/Concolic/Database.h>
8 #include <Rose/BinaryAnalysis/Concolic/ExecutionLocation.h>
9 #include <Rose/BinaryAnalysis/Debugger.h>
10 #include <Combinatorics.h> // rose
11 
12 namespace Rose {
13 namespace BinaryAnalysis {
14 namespace Concolic {
15 
63 class ExecutionEvent: public Sawyer::SharedObject, public Sawyer::SharedFromThis<ExecutionEvent> {
64 public:
66  using Ptr = ExecutionEventPtr;
67 
69  enum class Action {
71  NONE,
72 
76  BULK_MEMORY_MAP,
77 
81  BULK_MEMORY_UNMAP,
82 
87  BULK_MEMORY_WRITE,
88 
93  BULK_MEMORY_HASH,
94 
99  MEMORY_WRITE,
100 
105  BULK_REGISTER_WRITE,
106 
111  REGISTER_WRITE,
112 
121  OS_SYSCALL,
122 
138  OS_SHARED_MEMORY
139  };
140 
141 private:
142  // These are the data members that get read/written to the database. The API properties defined for the various event
143  // types are not necessarily a 1:1 mapping to these data members.
144 
145  // Event identification data members
146  std::string timestamp_; // time of creation, needed by the database
147  TestCasePtr testCase_; // each event belongs to a particular test case
148  std::string name_; // optional name for debugging
149  ExecutionLocation location_; // location event occurs
150  rose_addr_t ip_ = 0; // address of instruction associated with event
151 
152  // These data members map to properties, but not necessarily 1:1. It's done this way for efficiency in the database.
153  Action action_ = Action::NONE; // type of action
154  AddressInterval memoryVas_; // affected memory
155  unsigned u_ = 0; // permission bits, register, or syscall function number
156  std::vector<uint8_t> bytes_; // byte data, hash digest, or syscall arguments
157  SymbolicExprPtr variable_, value_, expression_; // for computing concrete result from input
158  InputType inputType_ = InputType::NONE; // what kind of input is variable_?
159  size_t idx1_ = INVALID_INDEX; // indices for the input type, such as argv[i][j]
160  size_t idx2_ = INVALID_INDEX;
161 
162 protected:
163  ExecutionEvent();
164 public:
165  ~ExecutionEvent();
166 
167 public:
169  // Event constructors. These have camelCase names identical to the action.
171 
173  Ptr copy() const;
174 
176  static Ptr instance();
177 
179  static Ptr noAction(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip);
180 
181 
183  static Ptr bulkMemoryMap(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
184  const AddressInterval &where, unsigned permissions);
185 
187  static Ptr bulkMemoryUnmap(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
188  const AddressInterval &where);
189 
193  static Ptr bulkMemoryWrite(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
194  const AddressInterval &where, const std::vector<uint8_t> &bytes);
195 
199  static Ptr bulkMemoryHash(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
200  const AddressInterval &where, const Combinatorics::Hasher::Digest&);
201 
203  static Ptr memoryWrite(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
204  const AddressInterval &where, const SymbolicExprPtr &variable,
205  const SymbolicExprPtr &value, const SymbolicExprPtr &expression);
206 
208  static Ptr bulkRegisterWrite(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
209  const Debugger::AllRegisters&);
210 
212  static Ptr registerWrite(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
213  RegisterDescriptor where, const SymbolicExprPtr &variable,
214  const SymbolicExprPtr &value, const SymbolicExprPtr &expression);
215 
217  static Ptr osSyscall(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
218  unsigned function, const std::vector<uint64_t> &arguments);
219 
221  static Ptr osSharedMemory(const TestCasePtr&, const ExecutionLocation&, rose_addr_t ip,
222  const AddressInterval &where, const SymbolicExprPtr &variable,
223  const SymbolicExprPtr &value, const SymbolicExprPtr &expression);
224 
226  // Properties that are used by all event types.
228 
236  TestCasePtr testCase() const;
237  void testCase(const TestCasePtr&);
250  const std::string& timestamp() const;
251  void timestamp(const std::string&);
262  std::string name() const;
263  void name(const std::string&);
273  ExecutionLocation location() const;
274  void location(const ExecutionLocation&);
286  rose_addr_t instructionPointer() const;
287  void instructionPointer(rose_addr_t);
297  Action action() const;
298  void action(Action);
301  // Properties specific to certain types of events.
304 
313  AddressInterval memoryLocation() const;
314  void memoryLocation(const AddressInterval&);
325  RegisterDescriptor registerDescriptor() const;
326  void registerDescriptor(RegisterDescriptor);
337  unsigned permissions() const;
338  void permissions(unsigned);
349  const std::vector<uint8_t>& bytes() const;
350  void bytes(const std::vector<uint8_t>&);
358  Debugger::AllRegisters registerValues() const;
359  void registerValues(const Debugger::AllRegisters&);
370  const Combinatorics::Hasher::Digest& hash() const;
371  void hash(const Combinatorics::Hasher::Digest&);
383  SymbolicExprPtr variable() const;
384  void variable(const SymbolicExprPtr&);
397  SymbolicExprPtr value() const;
398  void value(const SymbolicExprPtr&);
414  SymbolicExprPtr expression() const;
415  void expression(const SymbolicExprPtr&);
425  unsigned syscallFunction() const;
426  void syscallFunction(unsigned);
438  std::vector<uint64_t> syscallArguments() const;
439  void syscallArguments(const std::vector<uint64_t>&);
442  // Properties related to test case input variables.
445 
457  InputType inputType() const;
458  void inputType(InputType, size_t idx1, size_t idx2);
459  std::pair<size_t, size_t> inputIndices() const;
462  // Actions valid for all events
465 
472  SymbolicExprPtr inputVariable() const;
473 
475  // Actions defined for some event types.
477 
478 
487  SymbolicExprPtr calculateResult(const SymbolicExpr::ExprExprHashMap &bindings) const;
488 
496  std::string printableName(const DatabasePtr &db = DatabasePtr());
497 
504  void toYaml(std::ostream&, const DatabasePtr&, std::string prefix);
505 
507  // Database operations
509 private:
510  friend class DatabaseAccess;
511 
512  // Recreate the table for storing execution events. Is only called from the database layer.
513  static void recreateTable(Sawyer::Database::Connection);
514 
515  // Save this object to the database. Is only called from the database layer.
516  void toDatabase(const DatabasePtr&, ExecutionEventId);
517 
518  // Restore this object from the database. Is only called from the database layer.
519  void fromDatabase(const DatabasePtr&, ExecutionEventId);
520 };
521 
522 } // namespace
523 } // namespace
524 } // namespace
525 
526 #endif
527 #endif
Sawyer::SharedPointer< Node > Ptr
Shared-ownership pointer to an expression Node.
Definition: SymbolicExpr.h:156
void copy(const Word *src, const BitRange &srcRange, Word *dst, const BitRange &dstRange)
Copy some bits.
const char * Action(int64_t)
Convert Rose::BinaryAnalysis::FeasiblePath::PathProcessor::Action enum constant to a string...
Main namespace for the ROSE library.
std::vector< uint8_t > Digest
The digest of the input message.
Creates SharedPointer from this.
Base class for reference counted objects.
Definition: SharedObject.h:64
Range of values delimited by endpoints.
Definition: Interval.h:33
const size_t INVALID_INDEX(-1)
Invalid array index.
Hash hash(const std::vector< Ptr > &)
Hash zero or more expressions.