ROSE  0.11.50.0
BaseSemantics/RegisterStateGeneric.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics2_BaseSemantics_RegisterStateGeneric_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics2_BaseSemantics_RegisterStateGeneric_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/InstructionSemantics2/BaseSemantics/Types.h>
7 #include <Rose/BinaryAnalysis/InstructionSemantics2/BaseSemantics/RegisterState.h>
8 #include <Rose/Exception.h>
9 
10 #include <boost/serialization/access.hpp>
11 #include <boost/serialization/base_object.hpp>
12 #include <boost/serialization/export.hpp>
13 #include <Sawyer/IntervalSetMap.h>
14 
15 namespace Rose {
16 namespace BinaryAnalysis {
17 namespace InstructionSemantics2 {
18 namespace BaseSemantics {
19 
21 typedef boost::shared_ptr<class RegisterStateGeneric> RegisterStateGenericPtr;
22 
40 class RegisterStateGeneric: public RegisterState {
42  // Basic Types
44 public:
46  using Super = RegisterState;
47 
50 
56  RegisterDescriptor desc_;
57  public:
59  : Rose::Exception("accessed register is not available in register state") {}
60  };
61 
66 
71  struct RegStore {
72  unsigned majr, minr;
73 
74 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
75  private:
76  friend class boost::serialization::access;
77 
78  template<class S>
79  void serialize(S &s, const unsigned /*version*/) {
80  s & BOOST_SERIALIZATION_NVP(majr);
81  s & BOOST_SERIALIZATION_NVP(minr);
82  }
83 #endif
84 
85  public:
86  RegStore() // for serialization
87  : majr(0), minr(0) {}
88  RegStore(RegisterDescriptor d) // implicit
89  : majr(d.majorNumber()), minr(d.minorNumber()) {}
90  bool operator<(const RegStore &other) const {
91  return majr<other.majr || (majr==other.majr && minr<other.minr);
92  }
93  };
94 
95 
97  // Types for storing values
99 public:
101  struct RegPair {
102  RegisterDescriptor desc;
103  SValuePtr value;
104 
105 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
106  private:
107  friend class boost::serialization::access;
108 
109  template<class S>
110  void serialize(S &s, const unsigned /*version*/) {
111  s & BOOST_SERIALIZATION_NVP(desc);
112  s & BOOST_SERIALIZATION_NVP(value);
113  }
114 #endif
115 
116  public:
117  RegPair() {} // for serialization
118 
119  public:
120  RegPair(RegisterDescriptor desc, const SValuePtr &value): desc(desc), value(value) {}
121  BitRange location() const { return BitRange::baseSize(desc.offset(), desc.nBits()); }
122  };
123 
125  typedef std::vector<RegPair> RegPairs;
126 
129 
130 
132  // Types for Boolean properties
134 public:
141 
146 
147 
149  // Types for storing addresses
151 public:
154 
157 
160 
161 
163  // Data members
165 private:
166  RegisterProperties properties_; // Boolean properties for each bit of each register.
167  RegisterAddressSet writers_; // Writing instruction address set for each bit of each register
168  bool accessModifiesExistingLocations_; // Can read/write modify existing locations?
169  bool accessCreatesLocations_; // Can new locations be created?
170 
171 protected:
180  Registers registers_;
181 
183  // Serialization
185 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
186 private:
187  friend class boost::serialization::access;
188 
189  template<class S>
190  void serialize(S &s, const unsigned /*version*/) {
191  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(RegisterState);
192  s & BOOST_SERIALIZATION_NVP(properties_);
193  s & BOOST_SERIALIZATION_NVP(writers_);
194  s & BOOST_SERIALIZATION_NVP(accessModifiesExistingLocations_);
195  s & BOOST_SERIALIZATION_NVP(accessCreatesLocations_);
196  s & BOOST_SERIALIZATION_NVP(registers_);
197  }
198 #endif
199 
201  // Normal constructors
202  //
203  // These are protected because objects of this class are reference counted and always allocated on the heap.
205 protected:
206  RegisterStateGeneric() // for serialization
207  : accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {}
208 
209  explicit RegisterStateGeneric(const SValuePtr &protoval, const RegisterDictionary *regdict)
210  : RegisterState(protoval, regdict), accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {
211  clear();
212  }
213 
214  RegisterStateGeneric(const RegisterStateGeneric &other)
215  : RegisterState(other), properties_(other.properties_), writers_(other.writers_),
216  accessModifiesExistingLocations_(other.accessModifiesExistingLocations_),
217  accessCreatesLocations_(other.accessCreatesLocations_), registers_(other.registers_) {
218  deep_copy_values();
219  }
220 
221 
223  // Static allocating constructors
225 public:
232  static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionary *regdict) {
233  return RegisterStateGenericPtr(new RegisterStateGeneric(protoval, regdict));
234  }
235 
237  static RegisterStateGenericPtr instance(const RegisterStateGenericPtr &other) {
238  return RegisterStateGenericPtr(new RegisterStateGeneric(*other));
239  }
240 
241 
243  // Virtual constructors
245 public:
246  virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionary *regdict) const ROSE_OVERRIDE {
247  return instance(protoval, regdict);
248  }
249 
250  virtual RegisterStatePtr clone() const ROSE_OVERRIDE {
251  return RegisterStateGenericPtr(new RegisterStateGeneric(*this));
252  }
253 
255  // Dynamic pointer casts
257 public:
260  static RegisterStateGenericPtr promote(const RegisterStatePtr &from) {
261  RegisterStateGenericPtr retval = boost::dynamic_pointer_cast<RegisterStateGeneric>(from);
262  ASSERT_not_null(retval);
263  return retval;
264  }
265 
266 
268  // Object properties
270 public:
285  bool accessModifiesExistingLocations() const /*final*/ { return accessModifiesExistingLocations_; }
286  virtual void accessModifiesExistingLocations(bool b) { accessModifiesExistingLocations_ = b; }
294  RegisterStateGeneric *rstate_;
295  bool savedValue_;
296  public:
298  : rstate_(rstate), savedValue_(rstate->accessModifiesExistingLocations()) {
299  rstate_->accessModifiesExistingLocations(newValue);
300  }
302  rstate_->accessModifiesExistingLocations(savedValue_);
303  }
304  };
305 
313  bool accessCreatesLocations() const /*final*/ { return accessCreatesLocations_; }
314  virtual void accessCreatesLocations(bool b) { accessCreatesLocations_ = b; }
322  RegisterStateGeneric *rstate_;
323  bool savedValue_;
324  public:
325  AccessCreatesLocationsGuard(RegisterStateGeneric *rstate, bool newValue)
326  : rstate_(rstate), savedValue_(rstate->accessCreatesLocations()) {
327  rstate_->accessCreatesLocations(newValue);
328  }
330  rstate_->accessCreatesLocations(savedValue_);
331  }
332  };
333 
334 
336  // Inherited non-constructors
338 public:
339  virtual void clear() ROSE_OVERRIDE;
340  virtual void zero() ROSE_OVERRIDE;
341  virtual SValuePtr readRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators*) ROSE_OVERRIDE;
342  virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators*) ROSE_OVERRIDE;
343  virtual void writeRegister(RegisterDescriptor, const SValuePtr &value, RiscOperators*) ROSE_OVERRIDE;
344  virtual void print(std::ostream&, Formatter&) const ROSE_OVERRIDE;
345  virtual bool merge(const RegisterStatePtr &other, RiscOperators*) ROSE_OVERRIDE;
346  virtual void hash(Combinatorics::Hasher&, RiscOperators*) const override;
347 
348 
350  // Initialization
352 public:
356  virtual void initialize_large();
357 
362  virtual void initialize_small();
363 
368  void initialize_nonoverlapping(const std::vector<RegisterDescriptor>&, bool initialize_to_zero);
369 
370 
372  // Value storage queries
374 public:
384  virtual RegPairs get_stored_registers() const;
385 
396  virtual bool is_partly_stored(RegisterDescriptor) const;
397 
400  virtual bool is_wholly_stored(RegisterDescriptor) const;
401 
406  virtual bool is_exactly_stored(RegisterDescriptor) const;
407 
413  virtual ExtentMap stored_parts(RegisterDescriptor) const;
414 
419  virtual RegPairs overlappingRegisters(RegisterDescriptor) const;
420 
424  virtual void erase_register(RegisterDescriptor, RiscOperators*);
425 
426 
428  // Traversals
430 public:
432  class Visitor {
433  public:
434  virtual ~Visitor() {}
435  virtual SValuePtr operator()(RegisterDescriptor, const SValuePtr&) = 0;
436  };
437 
471  virtual void traverse(Visitor&);
472 
473 
475  // Writer addresses
477 public:
485  virtual bool hasWritersAny(RegisterDescriptor) const;
486  virtual bool hasWritersAll(RegisterDescriptor) const;
494  virtual AddressSet getWritersUnion(RegisterDescriptor) const;
495 
501  virtual AddressSet getWritersIntersection(RegisterDescriptor) const;
502 
508  virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas);
509 
515  virtual void eraseWriters(RegisterDescriptor, const AddressSet &writerVas);
516 
521  virtual void setWriters(RegisterDescriptor, const AddressSet &writers);
522 
529  virtual void eraseWriters(RegisterDescriptor);
530  virtual void eraseWriters();
534  // Per-register bit Boolean properties
537 public:
565 
572 
578 
584  virtual void eraseProperties(RegisterDescriptor);
585  virtual void eraseProperties();
592  virtual std::vector<RegisterDescriptor>
593  findProperties(const InputOutputPropertySet &required,
594  const InputOutputPropertySet &prohibited = InputOutputPropertySet()) const;
595 
601 
607 
609  // Non-public APIs
611 protected:
612  void deep_copy_values();
613 
614  // Given a register descriptor return information about what's stored in the state. The two return values are:
615  //
616  // accessedParts represent the parts of the reigster (matching major and minor numbers) that are present in the
617  // state and overlap with the specified register.
618  //
619  // preservedParts represent the parts of the register that are present in the state but don't overlap with the
620  // specified register.
621  void scanAccessedLocations(RegisterDescriptor reg, RiscOperators *ops,
622  RegPairs &accessedParts /*out*/, RegPairs &preservedParts /*out*/) const;
623 
624  // Given a register descriptor, zero out all the stored parts of the same register (by matching major and minor numbers)
625  // if the stored part overlaps with the specified register.
626  void clearOverlappingLocations(RegisterDescriptor);
627 
628  void assertStorageConditions(const std::string &where, RegisterDescriptor what) const;
629 };
630 
631 } // namespace
632 } // namespace
633 } // namespace
634 } // namespace
635 
636 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
638 #endif
639 
640 #endif
641 #endif
static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionary *regdict)
Instantiate a new register state.
virtual RegPairs get_stored_registers() const
Returns the list of all registers and their values.
unsigned majorNumber() const
Property: Major number.
virtual void initialize_small()
Initialize all registers of the dictionary.
virtual bool is_partly_stored(RegisterDescriptor) const
Determines if some of the specified register is stored in the state.
size_t nBits() const
Property: Size in bits.
virtual void traverse(Visitor &)
Traverse register/value pairs.
boost::shared_ptr< class RegisterStateGeneric > RegisterStateGenericPtr
Shared-ownership pointer to generic register states.
bool accessCreatesLocations() const
Property: Whether access can create new locations.
virtual std::vector< RegisterDescriptor > findProperties(const InputOutputPropertySet &required, const InputOutputPropertySet &prohibited=InputOutputPropertySet()) const
Get registers having certain properties.
STL namespace.
virtual InputOutputPropertySet getPropertiesIntersection(RegisterDescriptor) const
Get properties.
Mapping from integers to sets.
virtual InputOutputPropertySet getPropertiesUnion(RegisterDescriptor) const
Get properties.
static RegisterStateGenericPtr promote(const RegisterStatePtr &from)
Run-time promotion of a base register state pointer to a RegisterStateGeneric pointer.
virtual void initialize_large()
Initialize all registers of the dictionary.
Main namespace for the ROSE library.
Sawyer::Container::Map< RegStore, BitAddressSet > RegisterAddressSet
Virtual addresses for all registers.
virtual ExtentMap stored_parts(RegisterDescriptor) const
Returns a description of which bits of a register are stored.
static RegisterStateGenericPtr instance(const RegisterStateGenericPtr &other)
Instantiate a new copy of an existing register state.
static Interval baseSize(size_t lo, size_t size)
Construct an interval from one endpoint and a size.
Definition: Interval.h:162
bool accessModifiesExistingLocations() const
Property: Whether stored registers are adapted to access patterns.
Sawyer::Container::Map< RegStore, BitProperties > RegisterProperties
Boolean properties for all registers.
Sawyer::Container::Map< RegStore, RegPairs > Registers
Values for all registers.
Describes (part of) a physical CPU register.
virtual bool hasPropertyAny(RegisterDescriptor, InputOutputProperty) const
Whether a register has the specified property.
virtual AddressSet getWritersIntersection(RegisterDescriptor) const
Get writer information.
virtual void setWriters(RegisterDescriptor, const AddressSet &writers)
Set writer information.
virtual RegPairs overlappingRegisters(RegisterDescriptor) const
Find stored registers overlapping with specified register.
virtual bool insertProperties(RegisterDescriptor, const InputOutputPropertySet &)
Insert Boolean properties.
size_t offset() const
Property: Offset to least-significant bit.
virtual void updateWriteProperties(RegisterDescriptor, InputOutputProperty)
Update write properties.
virtual void setProperties(RegisterDescriptor, const InputOutputPropertySet &)
Assign property set.
virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas)
Insert writer information.
virtual bool is_wholly_stored(RegisterDescriptor) const
Determines if the specified register is wholly stored in the state.
Base class for most instruction semantics RISC operators.
Definition: RiscOperators.h:48
virtual void updateReadProperties(RegisterDescriptor)
Update read properties.
virtual void accessModifiesExistingLocations(bool b)
Property: Whether stored registers are adapted to access patterns.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
virtual bool hasPropertyAll(RegisterDescriptor, InputOutputProperty) const
Whether a register has the specified property.
void initialize_nonoverlapping(const std::vector< RegisterDescriptor > &, bool initialize_to_zero)
Initialize the specified registers of the dictionary.
virtual bool hasWritersAny(RegisterDescriptor) const
Whether a register has writers.
virtual bool is_exactly_stored(RegisterDescriptor) const
Determines if the specified register is stored exactly in the state.
virtual void erase_register(RegisterDescriptor, RiscOperators *)
Cause a register to not be stored.
Sawyer::Container::IntervalSetMap< BitRange, InputOutputPropertySet > BitProperties
Boolean properties per bit.
Sawyer::Container::IntervalSetMap< BitRange, AddressSet > BitAddressSet
Virtual addresses per bit.
Defines registers available for a particular architecture.
Definition: Registers.h:37
unsigned minorNumber() const
Property: Minor number.
Sawyer::Container::Set< InputOutputProperty > InputOutputPropertySet
Set of Boolean properties.
Base class for all ROSE exceptions.
Definition: Rose/Exception.h:9
virtual void accessCreatesLocations(bool b)
Property: Whether access can create new locations.
virtual bool hasWritersAll(RegisterDescriptor) const
Whether a register has writers.
virtual AddressSet getWritersUnion(RegisterDescriptor) const
Get writer information.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.