ROSE  0.9.9.109
DataFlowSemantics2.h
1 #ifndef Rose_BinaryAnalysis_DataFlowSemantics_H
2 #define Rose_BinaryAnalysis_DataFlowSemantics_H
3 
4 #include "AbstractLocation.h"
5 #include "BaseSemantics2.h"
6 #include "MultiSemantics2.h"
7 #include "NullSemantics2.h"
8 
9 #include <boost/foreach.hpp>
10 #include <Sawyer/Assert.h>
11 #include <Sawyer/Graph.h>
12 
13 namespace Rose {
14 namespace BinaryAnalysis {
15 namespace InstructionSemantics2 {
16 namespace DataFlowSemantics {
17 
21 struct DataFlowEdge {
35  enum EdgeType {
38  };
39 
40  size_t sequence;
42  DataFlowEdge(): sequence((size_t)(-1)), edgeType(CLOBBER) {}
43  DataFlowEdge(size_t sequence, EdgeType edgeType): sequence(sequence), edgeType(edgeType) {}
44 };
45 
51 
53 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
54 
65 
66  const RegisterDictionary *regdict_; // register dictionary used to print abstract locations
67  size_t innerDomainId_; // subdomain identifier for the dataflow's inner domain
68  size_t userDomainId_; // subdomain identifier for the user-supplied domain (memory addrs)
69  DataFlowGraph dflow_; // dataflow graph accumulated over processInstruction() calls.
70 
71  void init(const BaseSemantics::RiscOperatorsPtr &userDomain);
72 
73  // The normal C++ constructors; protected because this object is reference counted
74 protected:
75  explicit RiscOperators(const BaseSemantics::RiscOperatorsPtr &userDomain)
77  init(userDomain);
78  }
79 
80 public:
85  static RiscOperatorsPtr instance(const BaseSemantics::RiscOperatorsPtr &childOps) {
86  return RiscOperatorsPtr(new RiscOperators(childOps));
87  }
88 
89  // Virtual constructors inherited from the super class. These are disabled because users are expected to create this
90  // dataflow semantics framework only through the "instance" method. (But we still must override them.)
91 private:
93  SMTSolver *solver=NULL) const ROSE_OVERRIDE {
94  ASSERT_not_reachable("should not be called by user code");
95 #ifdef _MSC_VER
97 #endif
98  }
99 
100  virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::StatePtr &state,
101  SMTSolver *solver=NULL) const ROSE_OVERRIDE {
102  ASSERT_not_reachable("should not be called by user code");
103 #ifdef _MSC_VER
105 #endif
106  }
107 
108  // Dynamic pointer cast
109 public:
112  static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x) {
113  RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(x);
114  ASSERT_not_null(retval);
115  return retval;
116  }
117 
118 public:
122  void clearGraph() { dflow_.clear(); }
123 
125  const DataFlowGraph& getGraph() const { return dflow_; }
126 
127 private:
128  // Temporarily disables a subdomain, restoring it the its original state when this object is canceled or destroyed.
129  class TemporarilyDeactivate {
131  size_t id_;
132  bool wasActive_, canceled_;
133  public:
134  TemporarilyDeactivate(MultiSemantics::RiscOperators *ops, size_t id)
135  : ops_(ops), id_(id), wasActive_(ops->is_active(id)), canceled_(false) {
136  ops->set_active(id, false);
137  }
138  ~TemporarilyDeactivate() {
139  cancel();
140  }
141  void cancel() {
142  if (!canceled_) {
143  ops_->set_active(id_, wasActive_);
144  canceled_ = true;
145  }
146  }
147  };
148 
149  // Insert edges (and vertices if necessary) into the data flow graph, dgraph_
150  void insertDataFlowEdge(const AbstractLocation &source, const AbstractLocation &target, DataFlowEdge::EdgeType);
151  void insertDataFlowEdges(const BaseSemantics::SValuePtr &svalue, const AbstractLocation &target);
152 
153  // Override state-accessing methods. These methods do the normal thing in the user domain, but in the dataflow domain they
154  // behave differently. When reading, they return the set of abstract locations that were read (either a register or the
155  // address for the bytes of memory); when writing they add vertices and edges to the dataflow graph.
156 public:
158  const BaseSemantics::SValuePtr &dflt) ROSE_OVERRIDE;
160  const BaseSemantics::SValuePtr &dflt) ROSE_OVERRIDE;
161 
162  virtual void writeRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &a_) ROSE_OVERRIDE;
163 
165  const BaseSemantics::SValuePtr &dflt_,
166  const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE;
167 
168  virtual void writeMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
169  const BaseSemantics::SValuePtr &data_, const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE;
170 };
171 
172 } // namespace
173 } // namespace
174 } // namespace
175 } // namespace
176 
177 #endif
static SValuePtr instance()
Construct a prototypical value.
virtual bool is_active(size_t idx) const
Returns true if a subdomain is active.
static RiscOperatorsPtr instance(const BaseSemantics::RiscOperatorsPtr &childOps)
Static allocating constructor.
virtual SValuePtr protoval() const
Property: Prototypical semantic value.
Main namespace for the ROSE library.
virtual BaseSemantics::SValuePtr readRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &dflt) ROSE_OVERRIDE
Reads a value from a register.
Describes (part of) a physical CPU register.
static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x)
Run-time promotion of a base RiscOperators pointer to operators for this domain.
virtual BaseSemantics::SValuePtr readMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &dflt_, const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE
Reads a value from memory.
Defines RISC operators for the MultiSemantics domain.
size_t sequence
Edge sequence number unique and constant within graph.
boost::shared_ptr< class State > StatePtr
Shared-ownership pointer to a semantic state.
virtual void set_active(size_t idx, bool status)
Makes a subdomain active or inactive.
boost::shared_ptr< class RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
EdgeType edgeType
Whether edge resets or augments previous flows to target.
Defines registers available for a particular architecture.
Definition: Registers.h:32
void clear()
Remove all vertices and edges.
Definition: Graph.h:1990
virtual void writeRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &a_) ROSE_OVERRIDE
Writes a value to a register.
virtual SMTSolver * solver() const
Property: Satisfiability module theory (SMT) solver.
virtual BaseSemantics::SValuePtr peekRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &dflt) ROSE_OVERRIDE
Obtain a register value without side effects.
const DataFlowGraph & getGraph() const
Return the dataflow graph.
Interface to Satisfiability Modulo Theory (SMT) solvers.
Definition: SMTSolver.h:19
virtual void writeMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &data_, const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE
Writes a value to memory.