ROSE  0.11.31.0
frontend/Partitioner2/Semantics.h
1 #ifndef ROSE_BinaryAnalysis_Partitioner_Semantics_H
2 #define ROSE_BinaryAnalysis_Partitioner_Semantics_H
3 
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 
7 #include <Partitioner2/BasicTypes.h>
8 #include "SymbolicSemantics2.h"
9 
10 #include <boost/serialization/access.hpp>
11 #include <boost/serialization/base_object.hpp>
12 #include <boost/serialization/export.hpp>
13 #include <boost/serialization/vector.hpp>
14 
15 namespace Rose {
16 namespace BinaryAnalysis {
17 namespace Partitioner2 {
18 
25 namespace Semantics {
26 
29 
32 
35 
38 
40 typedef InstructionSemantics2::BaseSemantics::State State;
41 
44 
46 // Memory State
48 
55 template<class Super = InstructionSemantics2::SymbolicSemantics::MemoryListState> // or MemoryMapState
56 class MemoryState: public Super {
57 public:
59  typedef boost::shared_ptr<MemoryState> Ptr;
60 
61 private:
62  MemoryMap::Ptr map_;
63  std::vector<SValuePtr> addressesRead_;
64  bool enabled_;
65 
66 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
67 private:
68  friend class boost::serialization::access;
69 
70  template<class S>
71  void serialize(S &s, const unsigned /*version*/) {
72  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
73  s & BOOST_SERIALIZATION_NVP(map_);
74  s & BOOST_SERIALIZATION_NVP(addressesRead_);
75  s & BOOST_SERIALIZATION_NVP(enabled_);
76  }
77 #endif
78 
79 protected:
80  MemoryState() // for serialization
81  : enabled_(true) {}
82 
83  explicit MemoryState(const InstructionSemantics2::BaseSemantics::MemoryCellPtr &protocell)
84  : Super(protocell), enabled_(true) {}
85 
86  MemoryState(const InstructionSemantics2::BaseSemantics::SValuePtr &addrProtoval,
88  : Super(addrProtoval, valProtoval), enabled_(true) {}
89 
90 public:
93  return Ptr(new MemoryState(protocell));
94  }
95 
99  return Ptr(new MemoryState(addrProtoval, valProtoval));
100  }
101 
103  static Ptr instance(const Ptr &other) {
104  return Ptr(new MemoryState(*other));
105  }
106 
107 public:
111  const InstructionSemantics2::BaseSemantics::SValuePtr &valProtoval) const ROSE_OVERRIDE {
112  return instance(addrProtoval, valProtoval);
113  }
114 
117  create(const InstructionSemantics2::BaseSemantics::MemoryCellPtr &protocell) const ROSE_OVERRIDE {
118  return instance(protocell);
119  }
120 
123  clone() const ROSE_OVERRIDE {
124  return Ptr(new MemoryState(*this));
125  }
126 
127 public:
130  static Ptr
132  Ptr retval = boost::dynamic_pointer_cast<MemoryState>(x);
133  assert(x!=NULL);
134  return retval;
135  }
136 
137 public:
144  bool enabled() const { return enabled_; }
145  void enabled(bool b) { enabled_ = b; }
155  MemoryMap::Ptr memoryMap() const { return map_; }
156  void memoryMap(const MemoryMap::Ptr &map) { map_ = map; }
162  const std::vector<SValuePtr>& addressesRead() const { return addressesRead_; }
163  std::vector<SValuePtr>& addressesRead() { return addressesRead_; }
166 public:
172 
173  virtual void
174  writeMemory(const InstructionSemantics2::BaseSemantics::SValuePtr &addr,
178 
184 
185 private:
187  readOrPeekMemory(const InstructionSemantics2::BaseSemantics::SValuePtr &addr,
191  bool withSideEffects);
192 
193 public:
194  void print(std::ostream&, InstructionSemantics2::BaseSemantics::Formatter&) const ROSE_OVERRIDE;
195 };
196 
198 typedef MemoryState<InstructionSemantics2::SymbolicSemantics::MemoryListState> MemoryListState;
199 
201 typedef MemoryState<InstructionSemantics2::SymbolicSemantics::MemoryMapState> MemoryMapState;
202 
204 typedef boost::shared_ptr<MemoryListState> MemoryListStatePtr;
205 
207 typedef boost::shared_ptr<MemoryMapState> MemoryMapStatePtr;
208 
210 // RISC Operators
212 
214 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
215 
220 class RiscOperators: public InstructionSemantics2::SymbolicSemantics::RiscOperators {
221 public:
223 
224 private:
225  static const size_t TRIM_THRESHOLD_DFLT = 100;
226 
228  // Serialization
229 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
230 private:
231  friend class boost::serialization::access;
232 
233  template<class S>
234  void serialize(S &s, const unsigned /*version*/) {
235  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
236  }
237 #endif
238 
240  // Real constructors
241 protected:
242  RiscOperators() {} // for serialization
243 
244  explicit RiscOperators(const InstructionSemantics2::BaseSemantics::SValuePtr &protoval,
245  const SmtSolverPtr &solver = SmtSolverPtr())
247  name("PartitionerSemantics");
248  (void)SValue::promote(protoval); // make sure its dynamic type is appropriate
249  trimThreshold(TRIM_THRESHOLD_DFLT);
250  }
251 
252  explicit RiscOperators(const InstructionSemantics2::BaseSemantics::StatePtr &state,
253  const SmtSolverPtr &solver = SmtSolverPtr())
255  name("PartitionerSemantics");
256  (void)SValue::promote(state->protoval());
257  trimThreshold(TRIM_THRESHOLD_DFLT);
258  }
259 
261  // Static allocating constructors
262 public:
264  static RiscOperatorsPtr instance(const RegisterDictionary *regdict, const SmtSolverPtr &solver = SmtSolverPtr(),
265  SemanticMemoryParadigm memoryParadigm = LIST_BASED_MEMORY) {
269  switch (memoryParadigm) {
270  case LIST_BASED_MEMORY:
271  memory = MemoryListState::instance(protoval, protoval);
272  break;
273  case MAP_BASED_MEMORY:
274  memory = MemoryMapState::instance(protoval, protoval);
275  break;
276  }
277  InstructionSemantics2::BaseSemantics::StatePtr state = State::instance(registers, memory);
278  return RiscOperatorsPtr(new RiscOperators(state, solver));
279  }
280 
282  static RiscOperatorsPtr
284  return RiscOperatorsPtr(new RiscOperators(protoval, solver));
285  }
286 
288  static RiscOperatorsPtr
290  return RiscOperatorsPtr(new RiscOperators(state, solver));
291  }
292 
294  // Virtual constructors
295 public:
298  const SmtSolverPtr &solver = SmtSolverPtr()) const ROSE_OVERRIDE {
299  return instance(protoval, solver);
300  }
301 
304  const SmtSolverPtr &solver = SmtSolverPtr()) const ROSE_OVERRIDE {
305  return instance(state, solver);
306  }
307 
309  // Dynamic pointer casts
310 public:
313  static RiscOperatorsPtr
315  RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(x);
316  assert(retval!=NULL);
317  return retval;
318  }
319 
321  // Override methods from base class.
322 public:
323  virtual void startInstruction(SgAsmInstruction*) ROSE_OVERRIDE;
324 };
325 
327 // Memory State
329 
330 template<class Super>
331 InstructionSemantics2::BaseSemantics::SValuePtr
332 MemoryState<Super>::readMemory(const InstructionSemantics2::BaseSemantics::SValuePtr &addr,
333  const InstructionSemantics2::BaseSemantics::SValuePtr &dflt,
334  InstructionSemantics2::BaseSemantics::RiscOperators *addrOps,
335  InstructionSemantics2::BaseSemantics::RiscOperators *valOps) {
336  return readOrPeekMemory(addr, dflt, addrOps, valOps, true/*with side effects*/);
337 }
338 
339 template<class Super>
341 MemoryState<Super>::peekMemory(const InstructionSemantics2::BaseSemantics::SValuePtr &addr,
345  return readOrPeekMemory(addr, dflt, addrOps, valOps, false/*no side effects*/);
346 }
347 
348 template<class Super>
350 MemoryState<Super>::readOrPeekMemory(const InstructionSemantics2::BaseSemantics::SValuePtr &addr,
354  bool withSideEffects) {
355  using namespace InstructionSemantics2;
356 
357  if (!enabled_)
358  return dflt->copy();
359 
360  addressesRead_.push_back(SValue::promote(addr));
361  if (map_ && addr->toUnsigned()) {
362  ASSERT_require2(8==dflt->nBits(), "multi-byte reads should have been handled above this call");
363  rose_addr_t va = addr->toUnsigned().get();
364  bool isModifiable = map_->at(va).require(MemoryMap::WRITABLE).exists();
365  bool isInitialized = map_->at(va).require(MemoryMap::INITIALIZED).exists();
366  if (!isModifiable || isInitialized) {
367  uint8_t byte;
368  if (1 == map_->at(va).limit(1).read(&byte).size()) {
370  if (isModifiable) {
372  expr = SymbolicExpr::makeSet(expr, indet, valOps->solver());
373  }
374  SymbolicSemantics::SValuePtr val = SymbolicSemantics::SValue::promote(valOps->undefined_(8));
375  val->set_expression(expr);
376  return val;
377  }
378  }
379  }
380 
381  if (withSideEffects) {
382  return Super::readMemory(addr, dflt, addrOps, valOps);
383  } else {
384  return Super::peekMemory(addr, dflt, addrOps, valOps);
385  }
386 }
387 
388 template<class Super>
389 void
390 MemoryState<Super>::writeMemory(const InstructionSemantics2::BaseSemantics::SValuePtr &addr,
392  InstructionSemantics2::BaseSemantics::RiscOperators *addrOps,
393  InstructionSemantics2::BaseSemantics::RiscOperators *valOps) {
394  if (!enabled_)
395  return;
396  Super::writeMemory(addr, value, addrOps, valOps);
397 }
398 
399 template<class Super>
400 void
401 MemoryState<Super>::print(std::ostream &out, InstructionSemantics2::BaseSemantics::Formatter &fmt) const {
402  if (map_) {
403  map_->dump(out, fmt.get_line_prefix());
404  } else {
405  out <<fmt.get_line_prefix() <<"no memory map\n";
406  }
407 
408  Super::print(out, fmt);
409 }
410 
411 } // namespace
412 } // namespace
413 } // namespace
414 } // namespace
415 
416 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
420 #endif
421 
422 #endif
423 #endif
static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionary *regdict)
Instantiate a new register state.
boost::shared_ptr< class MemoryCell > MemoryCellPtr
Shared-ownership pointer to a semantic memory cell.
Definition: MemoryCell.h:17
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
void memoryMap(const MemoryMap::Ptr &map)
The memory map for the specimen.
static RiscOperatorsPtr promote(const InstructionSemantics2::BaseSemantics::RiscOperatorsPtr &x)
Run-time promotion of a base RiscOperators pointer to our operators.
Defines RISC operators for the SymbolicSemantics domain.
boost::shared_ptr< class RegisterStateGeneric > RegisterStateGenericPtr
Shared-ownership pointer to generic register states.
std::vector< SValuePtr > & addressesRead()
Property: concrete virtual addresses that were read.
static Ptr promote(const InstructionSemantics2::BaseSemantics::MemoryStatePtr &x)
Recasts a base pointer to a symbolic memory state.
Base class for machine instructions.
InstructionSemantics2::BaseSemantics::RegisterStateGeneric RegisterState
Register state for the partitioner.
boost::shared_ptr< MemoryState > MemoryStatePtr
Shared-ownership pointer to a memory state.
boost::shared_ptr< class RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to the RISC operators object.
LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0)
Leaf constructor.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
static SValuePtr promote(const BaseSemantics::SValuePtr &v)
Promote a base value to a SymbolicSemantics value.
boost::shared_ptr< MemoryMapState > MemoryMapStatePtr
Shared-ownership pointer to a MemoryMapState.
LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0)
Leaf constructor.
virtual InstructionSemantics2::BaseSemantics::MemoryStatePtr create(const InstructionSemantics2::BaseSemantics::SValuePtr &addrProtoval, const InstructionSemantics2::BaseSemantics::SValuePtr &valProtoval) const ROSE_OVERRIDE
Virtual constructor.
const std::vector< SValuePtr > & addressesRead() const
Property: concrete virtual addresses that were read.
virtual InstructionSemantics2::BaseSemantics::RiscOperatorsPtr create(const InstructionSemantics2::BaseSemantics::SValuePtr &protoval, const SmtSolverPtr &solver=SmtSolverPtr()) const ROSE_OVERRIDE
Virtual allocating constructor.
static Ptr instance(const InstructionSemantics2::BaseSemantics::MemoryCellPtr &protocell)
Instantiates a new memory state having specified prototypical cells and value.
Main namespace for the ROSE library.
InstructionSemantics2::SymbolicSemantics::SValuePtr SValuePtr
Reference counting pointer to semantic value.
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
static RiscOperatorsPtr instance(const RegisterDictionary *regdict, const SmtSolverPtr &solver=SmtSolverPtr(), SemanticMemoryParadigm memoryParadigm=LIST_BASED_MEMORY)
Instantiate a new RiscOperators object and configure it using default values.
MemoryMap::Ptr memoryMap() const
The memory map for the specimen.
InstructionSemantics2::BaseSemantics::State State
Total state (registers and memory) for the partitioner.
static Ptr instance(const Ptr &other)
Instantiates a new deep copy of an existing state.
virtual InstructionSemantics2::BaseSemantics::MemoryStatePtr clone() const ROSE_OVERRIDE
Virtual copy constructor.
static SValuePtr instance()
Instantiate a new prototypical value.
boost::shared_ptr< MemoryState > Ptr
Shared-ownership pointer to a MemoryState.
SemanticMemoryParadigm
Organization of semantic memory.
Definition: BasicTypes.h:85
virtual InstructionSemantics2::BaseSemantics::RiscOperatorsPtr create(const InstructionSemantics2::BaseSemantics::StatePtr &state, const SmtSolverPtr &solver=SmtSolverPtr()) const ROSE_OVERRIDE
Virtual allocating constructor.
ROSE_DLL_API bool isInitialized()
Checks whether the library has been initialized.
Base class for most instruction semantics RISC operators.
static RiscOperatorsPtr instance(const InstructionSemantics2::BaseSemantics::SValuePtr &protoval, const SmtSolverPtr &solver=SmtSolverPtr())
Instantiate a new RiscOperators object with specified prototypical values.
static RiscOperatorsPtr instance(const InstructionSemantics2::BaseSemantics::StatePtr &state, const SmtSolverPtr &solver=SmtSolverPtr())
Instantiate a new RiscOperators with specified state.
InstructionSemantics2::BaseSemantics::StatePtr StatePtr
Reference counting pointer to total state.
virtual InstructionSemantics2::BaseSemantics::MemoryStatePtr create(const InstructionSemantics2::BaseSemantics::MemoryCellPtr &protocell) const ROSE_OVERRIDE
Virtual constructor.
Type of values manipulated by the SymbolicSemantics domain.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
static Ptr instance(const InstructionSemantics2::BaseSemantics::SValuePtr &addrProtoval, const InstructionSemantics2::BaseSemantics::SValuePtr &valProtoval)
Instantiates a new memory state having specified prototypical value.
Ptr makeSet(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Defines registers available for a particular architecture.
Definition: Registers.h:38
virtual SmtSolverPtr solver() const
Property: Satisfiability module theory (SMT) solver.
InstructionSemantics2::BaseSemantics::RegisterStateGenericPtr RegisterStatePtr
Reference counting pointer to register state.
InstructionSemantics2::SymbolicSemantics::SValue SValue
Semantic value in the partitioner.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
std::shared_ptr< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
boost::shared_ptr< MemoryListState > MemoryListStatePtr
Shared-ownership pointer to a MemoryListState.