ROSE  0.11.31.0
DataFlowSemantics2.h
1 #ifndef Rose_BinaryAnalysis_DataFlowSemantics_H
2 #define Rose_BinaryAnalysis_DataFlowSemantics_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include "AbstractLocation.h"
7 #include "BaseSemantics2.h"
8 #include "MultiSemantics2.h"
9 #include "NullSemantics2.h"
10 
11 #include <boost/foreach.hpp>
12 #include <Sawyer/Assert.h>
13 #include <Sawyer/Graph.h>
14 
15 namespace Rose {
16 namespace BinaryAnalysis {
17 namespace InstructionSemantics2 {
18 namespace DataFlowSemantics {
19 
23 struct DataFlowEdge {
37  enum EdgeType {
40  };
41 
42  size_t sequence;
44  DataFlowEdge(): sequence(INVALID_INDEX), edgeType(CLOBBER) {}
45  DataFlowEdge(size_t sequence, EdgeType edgeType): sequence(sequence), edgeType(edgeType) {}
46 };
47 
53 
55 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
56 
67 
68  const RegisterDictionary *regdict_; // register dictionary used to print abstract locations
69  size_t innerDomainId_; // subdomain identifier for the dataflow's inner domain
70  size_t userDomainId_; // subdomain identifier for the user-supplied domain (memory addrs)
71  DataFlowGraph dflow_; // dataflow graph accumulated over processInstruction() calls.
72 
73  void init(const BaseSemantics::RiscOperatorsPtr &userDomain);
74 
75  // The normal C++ constructors; protected because this object is reference counted
76 protected:
77  explicit RiscOperators(const BaseSemantics::RiscOperatorsPtr &userDomain)
79  init(userDomain);
80  }
81 
82 public:
87  static RiscOperatorsPtr instance(const BaseSemantics::RiscOperatorsPtr &childOps) {
88  return RiscOperatorsPtr(new RiscOperators(childOps));
89  }
90 
91  // Virtual constructors inherited from the super class. These are disabled because users are expected to create this
92  // dataflow semantics framework only through the "instance" method. (But we still must override them.)
93 private:
95  const SmtSolverPtr &solver = SmtSolverPtr()) const ROSE_OVERRIDE {
96  ASSERT_not_reachable("should not be called by user code");
97 #ifdef _MSC_VER
99 #endif
100  }
101 
102  virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::StatePtr &state,
103  const SmtSolverPtr &solver = SmtSolverPtr()) const ROSE_OVERRIDE {
104  ASSERT_not_reachable("should not be called by user code");
105 #ifdef _MSC_VER
107 #endif
108  }
109 
110  // Dynamic pointer cast
111 public:
114  static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x) {
115  RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(x);
116  ASSERT_not_null(retval);
117  return retval;
118  }
119 
120 public:
124  void clearGraph() { dflow_.clear(); }
125 
127  const DataFlowGraph& getGraph() const { return dflow_; }
128 
129 private:
130  // Temporarily disables a subdomain, restoring it the its original state when this object is canceled or destroyed.
131  class TemporarilyDeactivate {
133  size_t id_;
134  bool wasActive_, canceled_;
135  public:
136  TemporarilyDeactivate(MultiSemantics::RiscOperators *ops, size_t id)
137  : ops_(ops), id_(id), wasActive_(ops->is_active(id)), canceled_(false) {
138  ops->set_active(id, false);
139  }
140  ~TemporarilyDeactivate() {
141  cancel();
142  }
143  void cancel() {
144  if (!canceled_) {
145  ops_->set_active(id_, wasActive_);
146  canceled_ = true;
147  }
148  }
149  };
150 
151  // Insert edges (and vertices if necessary) into the data flow graph, dgraph_
152  void insertDataFlowEdge(const AbstractLocation &source, const AbstractLocation &target, DataFlowEdge::EdgeType);
153  void insertDataFlowEdges(const BaseSemantics::SValuePtr &svalue, const AbstractLocation &target);
154 
155  // Override state-accessing methods. These methods do the normal thing in the user domain, but in the dataflow domain they
156  // behave differently. When reading, they return the set of abstract locations that were read (either a register or the
157  // address for the bytes of memory); when writing they add vertices and edges to the dataflow graph.
158 public:
159  virtual BaseSemantics::SValuePtr readRegister(RegisterDescriptor reg,
160  const BaseSemantics::SValuePtr &dflt) ROSE_OVERRIDE;
161  virtual BaseSemantics::SValuePtr peekRegister(RegisterDescriptor reg,
162  const BaseSemantics::SValuePtr &dflt) ROSE_OVERRIDE;
163 
164  virtual void writeRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &a_) ROSE_OVERRIDE;
165 
166  virtual BaseSemantics::SValuePtr readMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
167  const BaseSemantics::SValuePtr &dflt_,
168  const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE;
169 
170  virtual BaseSemantics::SValuePtr peekMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
171  const BaseSemantics::SValuePtr &dflt_) ROSE_OVERRIDE;
172 
173  virtual void writeMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
174  const BaseSemantics::SValuePtr &data_, const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE;
175 
176 protected:
177  BaseSemantics::SValuePtr readOrPeekMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr,
178  const BaseSemantics::SValuePtr &dflt,
179  const BaseSemantics::SValuePtr &cond, bool allowSideEffects);
180 
181 };
182 
183 } // namespace
184 } // namespace
185 } // namespace
186 } // namespace
187 
188 #endif
189 #endif
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
virtual BaseSemantics::SValuePtr peekMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &dflt_) ROSE_OVERRIDE
Read memory without side effects.
static SValuePtr instance()
Construct a prototypical value.
virtual bool is_active(size_t idx) const
Returns true if a subdomain is active.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
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.
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.
virtual void set_active(size_t idx, bool status)
Makes a subdomain active or inactive.
EdgeType edgeType
Whether edge resets or augments previous flows to target.
void clear()
Remove all vertices and edges.
Definition: Graph.h:1978
virtual void writeRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &a_) ROSE_OVERRIDE
Writes a value to a register.
Defines registers available for a particular architecture.
Definition: Registers.h:38
virtual SmtSolverPtr 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 size_t INVALID_INDEX(-1)
Invalid array index.
std::shared_ptr< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
const DataFlowGraph & getGraph() const
Return the dataflow graph.
virtual void writeMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &data_, const BaseSemantics::SValuePtr &cond) ROSE_OVERRIDE
Writes a value to memory.