ROSE  0.11.145.0
DataFlowSemantics.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics_DataFlowSemantics_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics_DataFlowSemantics_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/AbstractLocation.h>
7 #include <Rose/BinaryAnalysis/BasicTypes.h>
8 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics.h>
9 #include <Rose/BinaryAnalysis/InstructionSemantics/MultiSemantics.h>
10 #include <Rose/BinaryAnalysis/InstructionSemantics/NullSemantics.h>
11 
12 #include <Sawyer/Assert.h>
13 #include <Sawyer/Graph.h>
14 
15 namespace Rose {
16 namespace BinaryAnalysis {
17 namespace InstructionSemantics {
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 
66 public:
69 
71  using Ptr = RiscOperatorsPtr;
72 
73 private:
74  RegisterDictionaryPtr regdict_; // register dictionary used to print abstract locations
75  size_t innerDomainId_; // subdomain identifier for the dataflow's inner domain
76  size_t userDomainId_; // subdomain identifier for the user-supplied domain (memory addrs)
77  DataFlowGraph dflow_; // dataflow graph accumulated over processInstruction() calls.
78 
79  void init(const BaseSemantics::RiscOperatorsPtr &userDomain);
80 
81  // The normal C++ constructors; protected because this object is reference counted
82 protected:
83  explicit RiscOperators(const BaseSemantics::RiscOperatorsPtr &userDomain)
84  : MultiSemantics::RiscOperators(MultiSemantics::SValue::instance(), SmtSolverPtr()) {
85  init(userDomain);
86  }
87 
88 public:
93  static RiscOperatorsPtr instance(const BaseSemantics::RiscOperatorsPtr &childOps) {
94  return RiscOperatorsPtr(new RiscOperators(childOps));
95  }
96 
97  // Virtual constructors inherited from the super class. These are disabled because users are expected to create this
98  // dataflow semantics framework only through the "instance" method. (But we still must override them.)
99 private:
100  virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::SValuePtr &/*protoval*/,
101  const SmtSolverPtr& = SmtSolverPtr()) const override {
102  ASSERT_not_reachable("should not be called by user code");
103 #ifdef _MSC_VER
105 #endif
106  }
107 
109  const SmtSolverPtr& = SmtSolverPtr()) const override {
110  ASSERT_not_reachable("should not be called by user code");
111 #ifdef _MSC_VER
113 #endif
114  }
115 
116  // Dynamic pointer cast
117 public:
120  static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x) {
121  RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(x);
122  ASSERT_not_null(retval);
123  return retval;
124  }
125 
126 public:
130  void clearGraph() { dflow_.clear(); }
131 
133  const DataFlowGraph& getGraph() const { return dflow_; }
134 
135 private:
136  // Temporarily disables a subdomain, restoring it the its original state when this object is canceled or destroyed.
137  class TemporarilyDeactivate {
139  size_t id_;
140  bool wasActive_, canceled_;
141  public:
142  TemporarilyDeactivate(MultiSemantics::RiscOperators *ops, size_t id)
143  : ops_(ops), id_(id), wasActive_(ops->is_active(id)), canceled_(false) {
144  ops->set_active(id, false);
145  }
146  ~TemporarilyDeactivate() {
147  cancel();
148  }
149  void cancel() {
150  if (!canceled_) {
151  ops_->set_active(id_, wasActive_);
152  canceled_ = true;
153  }
154  }
155  };
156 
157  // Insert edges (and vertices if necessary) into the data flow graph, dgraph_
158  void insertDataFlowEdge(const AbstractLocation &source, const AbstractLocation &target, DataFlowEdge::EdgeType);
159  void insertDataFlowEdges(const BaseSemantics::SValuePtr &svalue, const AbstractLocation &target);
160 
161  // Override state-accessing methods. These methods do the normal thing in the user domain, but in the dataflow domain they
162  // behave differently. When reading, they return the set of abstract locations that were read (either a register or the
163  // address for the bytes of memory); when writing they add vertices and edges to the dataflow graph.
164 public:
165  virtual BaseSemantics::SValuePtr readRegister(RegisterDescriptor reg,
166  const BaseSemantics::SValuePtr &dflt) override;
167  virtual BaseSemantics::SValuePtr peekRegister(RegisterDescriptor reg,
168  const BaseSemantics::SValuePtr &dflt) override;
169 
170  virtual void writeRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &a_) override;
171 
172  virtual BaseSemantics::SValuePtr readMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
173  const BaseSemantics::SValuePtr &dflt_,
174  const BaseSemantics::SValuePtr &cond) override;
175 
176  virtual BaseSemantics::SValuePtr peekMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
177  const BaseSemantics::SValuePtr &dflt_) override;
178 
179  virtual void writeMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_,
180  const BaseSemantics::SValuePtr &data_, const BaseSemantics::SValuePtr &cond) override;
181 
182 protected:
183  BaseSemantics::SValuePtr readOrPeekMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr,
184  const BaseSemantics::SValuePtr &dflt,
185  const BaseSemantics::SValuePtr &cond, bool allowSideEffects);
186 
187 };
188 
189 } // namespace
190 } // namespace
191 } // namespace
192 } // namespace
193 
194 #endif
195 #endif
const DataFlowGraph & getGraph() const
Return the dataflow graph.
Defines RISC operators for the MultiSemantics domain.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x)
Run-time promotion of a base RiscOperators pointer to operators for this domain.
static RiscOperatorsPtr instance(const BaseSemantics::RiscOperatorsPtr &childOps)
Static allocating constructor.
virtual void writeRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &a_) override
Writes a value to a register.
virtual void set_active(size_t idx, bool status)
Makes a subdomain active or inactive.
virtual bool is_active(size_t idx) const
Returns true if a subdomain is active.
virtual BaseSemantics::SValuePtr peekMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &dflt_) override
Read memory without side effects.
Main namespace for the ROSE library.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
virtual void writeMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &data_, const BaseSemantics::SValuePtr &cond) override
Writes a value to memory.
virtual BaseSemantics::SValuePtr peekRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &dflt) override
Obtain a register value without side effects.
EdgeType edgeType
Whether edge resets or augments previous flows to target.
virtual BaseSemantics::SValuePtr readMemory(RegisterDescriptor segreg, const BaseSemantics::SValuePtr &addr_, const BaseSemantics::SValuePtr &dflt_, const BaseSemantics::SValuePtr &cond) override
Reads a value from memory.
void clear()
Remove all vertices and edges.
Definition: Graph.h:2005
size_t sequence
Edge sequence number unique and constant within graph.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
virtual BaseSemantics::SValuePtr readRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &dflt) override
Reads a value from a register.
const size_t INVALID_INDEX(static_cast< size_t >(-1))
Invalid array index.