ROSE  0.11.145.0
RegisterStateGeneric.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics_BaseSemantics_RegisterStateGeneric_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics_BaseSemantics_RegisterStateGeneric_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/BasicTypes.h>
7 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics/BasicTypes.h>
8 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics/RegisterState.h>
9 #include <Rose/Exception.h>
10 
11 #include <boost/serialization/access.hpp>
12 #include <boost/serialization/base_object.hpp>
13 #include <boost/serialization/export.hpp>
14 #include <Sawyer/IntervalSetMap.h>
15 
16 namespace Rose {
17 namespace BinaryAnalysis {
18 namespace InstructionSemantics {
19 namespace BaseSemantics {
20 
22 typedef boost::shared_ptr<class RegisterStateGeneric> RegisterStateGenericPtr;
23 
43  // Basic Types
45 public:
48 
51 
57  RegisterDescriptor desc_;
58  public:
60  : Rose::Exception("accessed register is not available in register state") {}
61  };
62 
67 
72  struct RegStore {
73  unsigned majr, minr;
74 
75 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
76  private:
77  friend class boost::serialization::access;
78 
79  template<class S>
80  void serialize(S &s, const unsigned /*version*/) {
81  s & BOOST_SERIALIZATION_NVP(majr);
82  s & BOOST_SERIALIZATION_NVP(minr);
83  }
84 #endif
85 
86  public:
87  RegStore() // for serialization
88  : majr(0), minr(0) {}
89  RegStore(RegisterDescriptor d) // implicit
90  : majr(d.majorNumber()), minr(d.minorNumber()) {}
91  bool operator<(const RegStore &other) const {
92  return majr<other.majr || (majr==other.majr && minr<other.minr);
93  }
94  };
95 
96 
98  // Types for storing values
100 public:
102  struct RegPair {
103  RegisterDescriptor desc;
104  SValuePtr value;
105 
106 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
107  private:
108  friend class boost::serialization::access;
109 
110  template<class S>
111  void serialize(S &s, const unsigned /*version*/) {
112  s & BOOST_SERIALIZATION_NVP(desc);
113  s & BOOST_SERIALIZATION_NVP(value);
114  }
115 #endif
116 
117  public:
118  RegPair() {} // for serialization
119 
120  public:
121  RegPair(RegisterDescriptor desc, const SValuePtr &value): desc(desc), value(value) {}
122  BitRange location() const { return BitRange::baseSize(desc.offset(), desc.nBits()); }
124  };
125 
127  typedef std::vector<RegPair> RegPairs;
128 
131 
132 
134  // Types for Boolean properties
136 public:
143 
148 
149 
151  // Types for storing addresses
153 public:
156 
159 
162 
163 
165  // Data members
167 private:
168  RegisterProperties properties_; // Boolean properties for each bit of each register.
169  RegisterAddressSet writers_; // Writing instruction address set for each bit of each register
170  bool accessModifiesExistingLocations_; // Can read/write modify existing locations?
171  bool accessCreatesLocations_; // Can new locations be created?
172 
173 protected:
182  Registers registers_;
183 
185  // Serialization
187 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
188 private:
189  friend class boost::serialization::access;
190 
191  template<class S>
192  void serialize(S &s, const unsigned /*version*/) {
193  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(RegisterState);
194  s & BOOST_SERIALIZATION_NVP(properties_);
195  s & BOOST_SERIALIZATION_NVP(writers_);
196  s & BOOST_SERIALIZATION_NVP(accessModifiesExistingLocations_);
197  s & BOOST_SERIALIZATION_NVP(accessCreatesLocations_);
198  s & BOOST_SERIALIZATION_NVP(registers_);
199  }
200 #endif
201 
203  // Normal constructors
204  //
205  // These are protected because objects of this class are reference counted and always allocated on the heap.
207 protected:
208  RegisterStateGeneric() // for serialization
209  : accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {}
210 
211  explicit RegisterStateGeneric(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict)
212  : RegisterState(protoval, regdict), accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {
213  clear();
214  }
215 
216  RegisterStateGeneric(const RegisterStateGeneric &other)
217  : RegisterState(other), properties_(other.properties_), writers_(other.writers_),
218  accessModifiesExistingLocations_(other.accessModifiesExistingLocations_),
219  accessCreatesLocations_(other.accessCreatesLocations_), registers_(other.registers_) {
220  deep_copy_values();
221  }
222 
223 
225  // Static allocating constructors
227 public:
234  static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict) {
235  return RegisterStateGenericPtr(new RegisterStateGeneric(protoval, regdict));
236  }
237 
239  static RegisterStateGenericPtr instance(const RegisterStateGenericPtr &other) {
240  return RegisterStateGenericPtr(new RegisterStateGeneric(*other));
241  }
242 
243 
245  // Virtual constructors
247 public:
248  virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict) const override {
249  return instance(protoval, regdict);
250  }
251 
252  virtual RegisterStatePtr clone() const override {
254  }
255 
257  // Dynamic pointer casts
259 public:
262  static RegisterStateGenericPtr promote(const RegisterStatePtr &from) {
263  RegisterStateGenericPtr retval = boost::dynamic_pointer_cast<RegisterStateGeneric>(from);
264  ASSERT_not_null(retval);
265  return retval;
266  }
267 
268 
270  // Object properties
272 public:
287  bool accessModifiesExistingLocations() const /*final*/ { return accessModifiesExistingLocations_; }
288  virtual void accessModifiesExistingLocations(bool b) { accessModifiesExistingLocations_ = b; }
296  RegisterStateGeneric *rstate_;
297  bool savedValue_;
298  public:
300  : rstate_(rstate), savedValue_(rstate->accessModifiesExistingLocations()) {
301  rstate_->accessModifiesExistingLocations(newValue);
302  }
304  rstate_->accessModifiesExistingLocations(savedValue_);
305  }
306  };
307 
315  bool accessCreatesLocations() const /*final*/ { return accessCreatesLocations_; }
316  virtual void accessCreatesLocations(bool b) { accessCreatesLocations_ = b; }
324  RegisterStateGeneric *rstate_;
325  bool savedValue_;
326  public:
327  AccessCreatesLocationsGuard(RegisterStateGeneric *rstate, bool newValue)
328  : rstate_(rstate), savedValue_(rstate->accessCreatesLocations()) {
329  rstate_->accessCreatesLocations(newValue);
330  }
332  rstate_->accessCreatesLocations(savedValue_);
333  }
334  };
335 
336 
338  // Inherited non-constructors
340 public:
341  virtual void clear() override;
342  virtual void zero() override;
343  virtual SValuePtr readRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators*) override;
344  virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators*) override;
345  virtual void writeRegister(RegisterDescriptor, const SValuePtr &value, RiscOperators*) override;
346  virtual void print(std::ostream&, Formatter&) const override;
347  virtual bool merge(const RegisterStatePtr &other, RiscOperators*) override;
348  virtual void hash(Combinatorics::Hasher&, RiscOperators*) const override;
349 
350 
352  // Initialization
354 public:
358  virtual void initialize_large();
359 
364  virtual void initialize_small();
365 
370  void initialize_nonoverlapping(const std::vector<RegisterDescriptor>&, bool initialize_to_zero);
371 
372 
374  // Value storage queries
376 public:
386  virtual RegPairs get_stored_registers() const;
387 
398  virtual bool is_partly_stored(RegisterDescriptor) const;
399 
402  virtual bool is_wholly_stored(RegisterDescriptor) const;
403 
408  virtual bool is_exactly_stored(RegisterDescriptor) const;
409 
416 
421  virtual RegPairs overlappingRegisters(RegisterDescriptor) const;
422 
427 
428 
430  // Traversals
432 public:
434  class Visitor {
435  public:
436  virtual ~Visitor() {}
437  virtual SValuePtr operator()(RegisterDescriptor, const SValuePtr&) = 0;
438  };
439 
473  virtual void traverse(Visitor&);
474 
475 
477  // Writer addresses
479 public:
487  virtual bool hasWritersAny(RegisterDescriptor) const;
488  virtual bool hasWritersAll(RegisterDescriptor) const;
496  virtual AddressSet getWritersUnion(RegisterDescriptor) const;
497 
503  virtual AddressSet getWritersIntersection(RegisterDescriptor) const;
504 
510  virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas);
511 
517  virtual void eraseWriters(RegisterDescriptor, const AddressSet &writerVas);
518 
523  virtual void setWriters(RegisterDescriptor, const AddressSet &writers);
524 
531  virtual void eraseWriters(RegisterDescriptor);
532  virtual void eraseWriters();
536  // Per-register bit Boolean properties
539 public:
567 
574 
580 
586  virtual void eraseProperties(RegisterDescriptor);
587  virtual void eraseProperties();
594  virtual std::vector<RegisterDescriptor>
595  findProperties(const InputOutputPropertySet &required,
596  const InputOutputPropertySet &prohibited = InputOutputPropertySet()) const;
597 
598  // Documented in super class
600  virtual void updateReadProperties(RegisterDescriptor) override;
601 
603  // Non-public APIs
605 protected:
606  void deep_copy_values();
607 
608  // Given a register descriptor return information about what's stored in the state. The two return values are:
609  //
610  // accessedParts represent the parts of the reigster (matching major and minor numbers) that are present in the
611  // state and overlap with the specified register.
612  //
613  // preservedParts represent the parts of the register that are present in the state but don't overlap with the
614  // specified register.
615  void scanAccessedLocations(RegisterDescriptor reg, RiscOperators *ops,
616  RegPairs &accessedParts /*out*/, RegPairs &preservedParts /*out*/) const;
617 
618  // Given a register descriptor, zero out all the stored parts of the same register (by matching major and minor numbers)
619  // if the stored part overlaps with the specified register.
620  void clearOverlappingLocations(RegisterDescriptor);
621 
622  void assertStorageConditions(const std::string &where, RegisterDescriptor what) const;
623 };
624 
625 } // namespace
626 } // namespace
627 } // namespace
628 } // namespace
629 
630 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
632 #endif
633 
634 #endif
635 #endif
virtual void updateWriteProperties(RegisterDescriptor, InputOutputProperty) override
Update register properties after writing to a register.
unsigned majorNumber() const
Property: Major number.
virtual bool is_wholly_stored(RegisterDescriptor) const
Determines if the specified register is wholly stored in the state.
size_t nBits() const
Property: Size in bits.
Sawyer::Container::IntervalSetMap< BitRange, AddressSet > BitAddressSet
Virtual addresses per bit.
virtual void clear() override
Removes stored values from the register state.
virtual bool hasPropertyAll(RegisterDescriptor, InputOutputProperty) const
Whether a register has the specified property.
virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas)
Insert writer information.
virtual void accessCreatesLocations(bool b)
Property: Whether access can create new locations.
Sawyer::Container::Map< RegStore, BitProperties > RegisterProperties
Boolean properties for all registers.
virtual void erase_register(RegisterDescriptor, RiscOperators *)
Cause a register to not be stored.
void initialize_nonoverlapping(const std::vector< RegisterDescriptor > &, bool initialize_to_zero)
Initialize the specified registers of the dictionary.
virtual bool hasWritersAll(RegisterDescriptor) const
Whether a register has writers.
RegisterDictionaryPtr regdict
Registers that are able to be stored by this state.
Definition: RegisterState.h:40
virtual void setProperties(RegisterDescriptor, const InputOutputPropertySet &)
Assign property set.
virtual void initialize_small()
Initialize all registers of the dictionary.
virtual RegisterStatePtr clone() const override
Make a copy of this register state.
Sawyer::Container::Set< InputOutputProperty > InputOutputPropertySet
Set of Boolean properties.
bool accessModifiesExistingLocations() const
Property: Whether stored registers are adapted to access patterns.
Mapping from integers to sets.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
Sawyer::Container::Interval< size_t > BitRange
A range of bits indexes.
virtual void hash(Combinatorics::Hasher &, RiscOperators *) const override
Hash the register state.
virtual void writeRegister(RegisterDescriptor, const SValuePtr &value, RiscOperators *) override
Write a value to a register.
Main namespace for the ROSE library.
virtual AddressSet getWritersUnion(RegisterDescriptor) const
Get writer information.
virtual void accessModifiesExistingLocations(bool b)
Property: Whether stored registers are adapted to access patterns.
bool accessCreatesLocations() const
Property: Whether access can create new locations.
virtual void zero() override
Set all registers to the zero.
virtual bool hasPropertyAny(RegisterDescriptor, InputOutputProperty) const
Whether a register has the specified property.
static Interval baseSize(size_t lo, size_t size)
Construct an interval from one endpoint and a size.
Definition: Interval.h:162
boost::shared_ptr< class RegisterStateGeneric > RegisterStateGenericPtr
Shared-ownership pointer to generic register states.
static RegisterStateGenericPtr promote(const RegisterStatePtr &from)
Run-time promotion of a base register state pointer to a RegisterStateGeneric pointer.
virtual SValuePtr readRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators *) override
Read a value from a register.
Sawyer::Container::Map< RegStore, BitAddressSet > RegisterAddressSet
Virtual addresses for all registers.
Sawyer::Container::IntervalSetMap< BitRange, InputOutputPropertySet > BitProperties
Boolean properties per bit.
virtual bool insertProperties(RegisterDescriptor, const InputOutputPropertySet &)
Insert Boolean properties.
virtual RegPairs overlappingRegisters(RegisterDescriptor) const
Find stored registers overlapping with specified register.
virtual bool is_partly_stored(RegisterDescriptor) const
Determines if some of the specified register is stored in the state.
Describes (part of) a physical CPU register.
Sawyer::Container::Map< RegStore, RegPairs > Registers
Values for all registers.
virtual InputOutputPropertySet getPropertiesUnion(RegisterDescriptor) const
Get properties.
virtual void updateReadProperties(RegisterDescriptor) override
Update register properties after reading a register.
virtual void print(std::ostream &, Formatter &) const override
Print the register contents.
virtual void setWriters(RegisterDescriptor, const AddressSet &writers)
Set writer information.
Registers registers_
Values for registers that have been accessed.
size_t offset() const
Property: Offset to least-significant bit.
virtual ExtentMap stored_parts(RegisterDescriptor) const
Returns a description of which bits of a register are stored.
virtual InputOutputPropertySet getPropertiesIntersection(RegisterDescriptor) const
Get properties.
static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict)
Instantiate a new register state.
virtual AddressSet getWritersIntersection(RegisterDescriptor) const
Get writer information.
virtual RegPairs get_stored_registers() const
Returns the list of all registers and their values.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
static RegisterStateGenericPtr instance(const RegisterStateGenericPtr &other)
Instantiate a new copy of an existing register state.
Sawyer::Container::Set< rose_addr_t > AddressSet
Set of virtual addresses.
virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators *) override
Read a register without side effects.
Base class for most instruction semantics RISC operators.
Definition: RiscOperators.h:49
virtual bool is_exactly_stored(RegisterDescriptor) const
Determines if the specified register is stored exactly in the state.
virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict) const override
Virtual constructor.
unsigned minorNumber() const
Property: Minor number.
Base class for all ROSE exceptions.
Definition: Rose/Exception.h:9
virtual std::vector< RegisterDescriptor > findProperties(const InputOutputPropertySet &required, const InputOutputPropertySet &prohibited=InputOutputPropertySet()) const
Get registers having certain properties.
virtual void traverse(Visitor &)
Traverse register/value pairs.
virtual bool merge(const RegisterStatePtr &other, RiscOperators *) override
Merge register states for data flow analysis.
virtual bool hasWritersAny(RegisterDescriptor) const
Whether a register has writers.
virtual void initialize_large()
Initialize all registers of the dictionary.