ROSE  0.11.101.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/Types.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()); }
123  };
124 
126  typedef std::vector<RegPair> RegPairs;
127 
130 
131 
133  // Types for Boolean properties
135 public:
142 
147 
148 
150  // Types for storing addresses
152 public:
155 
158 
161 
162 
164  // Data members
166 private:
167  RegisterProperties properties_; // Boolean properties for each bit of each register.
168  RegisterAddressSet writers_; // Writing instruction address set for each bit of each register
169  bool accessModifiesExistingLocations_; // Can read/write modify existing locations?
170  bool accessCreatesLocations_; // Can new locations be created?
171 
172 protected:
181  Registers registers_;
182 
184  // Serialization
186 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
187 private:
188  friend class boost::serialization::access;
189 
190  template<class S>
191  void serialize(S &s, const unsigned /*version*/) {
192  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(RegisterState);
193  s & BOOST_SERIALIZATION_NVP(properties_);
194  s & BOOST_SERIALIZATION_NVP(writers_);
195  s & BOOST_SERIALIZATION_NVP(accessModifiesExistingLocations_);
196  s & BOOST_SERIALIZATION_NVP(accessCreatesLocations_);
197  s & BOOST_SERIALIZATION_NVP(registers_);
198  }
199 #endif
200 
202  // Normal constructors
203  //
204  // These are protected because objects of this class are reference counted and always allocated on the heap.
206 protected:
207  RegisterStateGeneric() // for serialization
208  : accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {}
209 
210  explicit RegisterStateGeneric(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict)
211  : RegisterState(protoval, regdict), accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {
212  clear();
213  }
214 
215  RegisterStateGeneric(const RegisterStateGeneric &other)
216  : RegisterState(other), properties_(other.properties_), writers_(other.writers_),
217  accessModifiesExistingLocations_(other.accessModifiesExistingLocations_),
218  accessCreatesLocations_(other.accessCreatesLocations_), registers_(other.registers_) {
219  deep_copy_values();
220  }
221 
222 
224  // Static allocating constructors
226 public:
233  static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict) {
234  return RegisterStateGenericPtr(new RegisterStateGeneric(protoval, regdict));
235  }
236 
238  static RegisterStateGenericPtr instance(const RegisterStateGenericPtr &other) {
239  return RegisterStateGenericPtr(new RegisterStateGeneric(*other));
240  }
241 
242 
244  // Virtual constructors
246 public:
247  virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict) const override {
248  return instance(protoval, regdict);
249  }
250 
251  virtual RegisterStatePtr clone() const override {
253  }
254 
256  // Dynamic pointer casts
258 public:
261  static RegisterStateGenericPtr promote(const RegisterStatePtr &from) {
262  RegisterStateGenericPtr retval = boost::dynamic_pointer_cast<RegisterStateGeneric>(from);
263  ASSERT_not_null(retval);
264  return retval;
265  }
266 
267 
269  // Object properties
271 public:
286  bool accessModifiesExistingLocations() const /*final*/ { return accessModifiesExistingLocations_; }
287  virtual void accessModifiesExistingLocations(bool b) { accessModifiesExistingLocations_ = b; }
295  RegisterStateGeneric *rstate_;
296  bool savedValue_;
297  public:
299  : rstate_(rstate), savedValue_(rstate->accessModifiesExistingLocations()) {
300  rstate_->accessModifiesExistingLocations(newValue);
301  }
303  rstate_->accessModifiesExistingLocations(savedValue_);
304  }
305  };
306 
314  bool accessCreatesLocations() const /*final*/ { return accessCreatesLocations_; }
315  virtual void accessCreatesLocations(bool b) { accessCreatesLocations_ = b; }
323  RegisterStateGeneric *rstate_;
324  bool savedValue_;
325  public:
326  AccessCreatesLocationsGuard(RegisterStateGeneric *rstate, bool newValue)
327  : rstate_(rstate), savedValue_(rstate->accessCreatesLocations()) {
328  rstate_->accessCreatesLocations(newValue);
329  }
331  rstate_->accessCreatesLocations(savedValue_);
332  }
333  };
334 
335 
337  // Inherited non-constructors
339 public:
340  virtual void clear() override;
341  virtual void zero() override;
342  virtual SValuePtr readRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators*) override;
343  virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators*) override;
344  virtual void writeRegister(RegisterDescriptor, const SValuePtr &value, RiscOperators*) override;
345  virtual void print(std::ostream&, Formatter&) const override;
346  virtual bool merge(const RegisterStatePtr &other, RiscOperators*) override;
347  virtual void hash(Combinatorics::Hasher&, RiscOperators*) const override;
348 
349 
351  // Initialization
353 public:
357  virtual void initialize_large();
358 
363  virtual void initialize_small();
364 
369  void initialize_nonoverlapping(const std::vector<RegisterDescriptor>&, bool initialize_to_zero);
370 
371 
373  // Value storage queries
375 public:
385  virtual RegPairs get_stored_registers() const;
386 
397  virtual bool is_partly_stored(RegisterDescriptor) const;
398 
401  virtual bool is_wholly_stored(RegisterDescriptor) const;
402 
407  virtual bool is_exactly_stored(RegisterDescriptor) const;
408 
415 
420  virtual RegPairs overlappingRegisters(RegisterDescriptor) const;
421 
426 
427 
429  // Traversals
431 public:
433  class Visitor {
434  public:
435  virtual ~Visitor() {}
436  virtual SValuePtr operator()(RegisterDescriptor, const SValuePtr&) = 0;
437  };
438 
472  virtual void traverse(Visitor&);
473 
474 
476  // Writer addresses
478 public:
486  virtual bool hasWritersAny(RegisterDescriptor) const;
487  virtual bool hasWritersAll(RegisterDescriptor) const;
495  virtual AddressSet getWritersUnion(RegisterDescriptor) const;
496 
502  virtual AddressSet getWritersIntersection(RegisterDescriptor) const;
503 
509  virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas);
510 
516  virtual void eraseWriters(RegisterDescriptor, const AddressSet &writerVas);
517 
522  virtual void setWriters(RegisterDescriptor, const AddressSet &writers);
523 
530  virtual void eraseWriters(RegisterDescriptor);
531  virtual void eraseWriters();
535  // Per-register bit Boolean properties
538 public:
566 
573 
579 
585  virtual void eraseProperties(RegisterDescriptor);
586  virtual void eraseProperties();
593  virtual std::vector<RegisterDescriptor>
594  findProperties(const InputOutputPropertySet &required,
595  const InputOutputPropertySet &prohibited = InputOutputPropertySet()) const;
596 
602 
608 
610  // Non-public APIs
612 protected:
613  void deep_copy_values();
614 
615  // Given a register descriptor return information about what's stored in the state. The two return values are:
616  //
617  // accessedParts represent the parts of the reigster (matching major and minor numbers) that are present in the
618  // state and overlap with the specified register.
619  //
620  // preservedParts represent the parts of the register that are present in the state but don't overlap with the
621  // specified register.
622  void scanAccessedLocations(RegisterDescriptor reg, RiscOperators *ops,
623  RegPairs &accessedParts /*out*/, RegPairs &preservedParts /*out*/) const;
624 
625  // Given a register descriptor, zero out all the stored parts of the same register (by matching major and minor numbers)
626  // if the stored part overlaps with the specified register.
627  void clearOverlappingLocations(RegisterDescriptor);
628 
629  void assertStorageConditions(const std::string &where, RegisterDescriptor what) const;
630 };
631 
632 } // namespace
633 } // namespace
634 } // namespace
635 } // namespace
636 
637 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
639 #endif
640 
641 #endif
642 #endif
Base classes for instruction semantics.
Definition: Dispatcher.h:18
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 updateReadProperties(RegisterDescriptor)
Update read properties.
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.
virtual void updateWriteProperties(RegisterDescriptor, InputOutputProperty)
Update write properties.
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 print(std::ostream &, Formatter &) const override
Print the register contents.
virtual void setWriters(RegisterDescriptor, const AddressSet &writers)
Set writer information.
RegisterStatePtr Ptr
Shared-ownership pointer for a RegisterState object.
Definition: RegisterState.h:33
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.
Binary analysis.
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:48
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.