ROSE 0.11.145.147
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
16namespace Rose {
17namespace BinaryAnalysis {
18namespace InstructionSemantics {
19namespace BaseSemantics {
20
40 // Basic Types
42public:
45
48
55 public:
57 : Rose::Exception("accessed register is not available in register state") {}
58 };
59
64
69 struct RegStore {
70 unsigned majr, minr;
71
72#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
73 private:
74 friend class boost::serialization::access;
75
76 template<class S>
77 void serialize(S &s, const unsigned /*version*/) {
78 s & BOOST_SERIALIZATION_NVP(majr);
79 s & BOOST_SERIALIZATION_NVP(minr);
80 }
81#endif
82
83 public:
84 RegStore() // for serialization
85 : majr(0), minr(0) {}
86 RegStore(RegisterDescriptor d) // implicit
87 : majr(d.majorNumber()), minr(d.minorNumber()) {}
88 bool operator<(const RegStore &other) const {
89 return majr<other.majr || (majr==other.majr && minr<other.minr);
90 }
91 };
92
93
95 // Types for storing values
97public:
99 struct RegPair {
101 SValuePtr value;
102
103#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
104 private:
105 friend class boost::serialization::access;
106
107 template<class S>
108 void serialize(S &s, const unsigned /*version*/) {
109 s & BOOST_SERIALIZATION_NVP(desc);
110 s & BOOST_SERIALIZATION_NVP(value);
111 }
112#endif
113
114 public:
115 RegPair() {} // for serialization
116
117 public:
118 RegPair(RegisterDescriptor desc, const SValuePtr &value): desc(desc), value(value) {}
119 BitRange location() const { return BitRange::baseSize(desc.offset(), desc.nBits()); }
121 };
122
124 typedef std::vector<RegPair> RegPairs;
125
128
129
131 // Types for Boolean properties
133public:
140
145
146
148 // Types for storing addresses
150public:
153
156
159
160
162 // Data members
164private:
165 RegisterProperties properties_; // Boolean properties for each bit of each register.
166 RegisterAddressSet writers_; // Writing instruction address set for each bit of each register
167 bool accessModifiesExistingLocations_; // Can read/write modify existing locations?
168 bool accessCreatesLocations_; // Can new locations be created?
169
170protected:
180
182 // Serialization
184#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
185private:
186 friend class boost::serialization::access;
187
188 template<class S>
189 void serialize(S &s, const unsigned /*version*/) {
190 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(RegisterState);
191 s & BOOST_SERIALIZATION_NVP(properties_);
192 s & BOOST_SERIALIZATION_NVP(writers_);
193 s & BOOST_SERIALIZATION_NVP(accessModifiesExistingLocations_);
194 s & BOOST_SERIALIZATION_NVP(accessCreatesLocations_);
195 s & BOOST_SERIALIZATION_NVP(registers_);
196 }
197#endif
198
200 // Normal constructors
201 //
202 // These are protected because objects of this class are reference counted and always allocated on the heap.
204protected:
205 RegisterStateGeneric() // for serialization
206 : accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {}
207
208 explicit RegisterStateGeneric(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict)
209 : RegisterState(protoval, regdict), accessModifiesExistingLocations_(true), accessCreatesLocations_(true) {
210 clear();
211 }
212
213 RegisterStateGeneric(const RegisterStateGeneric &other)
214 : RegisterState(other), properties_(other.properties_), writers_(other.writers_),
215 accessModifiesExistingLocations_(other.accessModifiesExistingLocations_),
216 accessCreatesLocations_(other.accessCreatesLocations_), registers_(other.registers_) {
217 deep_copy_values();
218 }
219
220
222 // Static allocating constructors
224public:
234
239
240
242 // Virtual constructors
244public:
246 return instance(protoval, regdict);
247 }
248
249 virtual RegisterStatePtr clone() const override {
251 }
252
254 // Dynamic pointer casts
256public:
260 RegisterStateGenericPtr retval = boost::dynamic_pointer_cast<RegisterStateGeneric>(from);
261 ASSERT_not_null(retval);
262 return retval;
263 }
264
265
267 // Object properties
269public:
284 bool accessModifiesExistingLocations() const /*final*/ { return accessModifiesExistingLocations_; }
285 virtual void accessModifiesExistingLocations(bool b) { accessModifiesExistingLocations_ = b; }
293 RegisterStateGeneric *rstate_;
294 bool savedValue_;
295 public:
297 : rstate_(rstate), savedValue_(rstate->accessModifiesExistingLocations()) {
298 rstate_->accessModifiesExistingLocations(newValue);
299 }
301 rstate_->accessModifiesExistingLocations(savedValue_);
302 }
303 };
304
312 bool accessCreatesLocations() const /*final*/ { return accessCreatesLocations_; }
313 virtual void accessCreatesLocations(bool b) { accessCreatesLocations_ = b; }
321 RegisterStateGeneric *rstate_;
322 bool savedValue_;
323 public:
325 : rstate_(rstate), savedValue_(rstate->accessCreatesLocations()) {
326 rstate_->accessCreatesLocations(newValue);
327 }
329 rstate_->accessCreatesLocations(savedValue_);
330 }
331 };
332
333
335 // Inherited non-constructors
337public:
338 virtual void clear() override;
339 virtual void zero() override;
342 virtual void writeRegister(RegisterDescriptor, const SValuePtr &value, RiscOperators*) override;
343 virtual void print(std::ostream&, Formatter&) const override;
344 virtual bool merge(const RegisterStatePtr &other, RiscOperators*) override;
345 virtual void hash(Combinatorics::Hasher&, RiscOperators*) const override;
346
347
349 // Initialization
351public:
355 virtual void initialize_large();
356
361 virtual void initialize_small();
362
367 void initialize_nonoverlapping(const std::vector<RegisterDescriptor>&, bool initialize_to_zero);
368
369
371 // Value storage queries
373public:
384
396
400
406
413
419
424
425
427 // Traversals
429public:
431 class Visitor {
432 public:
433 virtual ~Visitor() {}
434 virtual SValuePtr operator()(RegisterDescriptor, const SValuePtr&) = 0;
435 };
436
470 virtual void traverse(Visitor&);
471
472
474 // Writer addresses
476public:
494
501
507 virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas);
508
514 virtual void eraseWriters(RegisterDescriptor, const AddressSet &writerVas);
515
520 virtual void setWriters(RegisterDescriptor, const AddressSet &writers);
521
529 virtual void eraseWriters();
534 // Per-register bit Boolean properties
536public:
564
571
577
584 virtual void eraseProperties();
591 virtual std::vector<RegisterDescriptor>
593 const InputOutputPropertySet &prohibited = InputOutputPropertySet()) const;
594
595 // Documented in super class
598
600 // Non-public APIs
602protected:
603 void deep_copy_values();
604
605 // Given a register descriptor return information about what's stored in the state. The two return values are:
606 //
607 // accessedParts represent the parts of the reigster (matching major and minor numbers) that are present in the
608 // state and overlap with the specified register.
609 //
610 // preservedParts represent the parts of the register that are present in the state but don't overlap with the
611 // specified register.
612 void scanAccessedLocations(RegisterDescriptor reg, RiscOperators *ops,
613 RegPairs &accessedParts /*out*/, RegPairs &preservedParts /*out*/) const;
614
615 // Given a register descriptor, zero out all the stored parts of the same register (by matching major and minor numbers)
616 // if the stored part overlaps with the specified register.
617 void clearOverlappingLocations(RegisterDescriptor);
618
619 void assertStorageConditions(const std::string &where, RegisterDescriptor what) const;
620};
621
622} // namespace
623} // namespace
624} // namespace
625} // namespace
626
627#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
629#endif
630
631#endif
632#endif
virtual void updateReadProperties(RegisterDescriptor) override
Update register properties after reading a register.
virtual void zero() override
Set all registers to the zero.
virtual bool insertProperties(RegisterDescriptor, const InputOutputPropertySet &)
Insert Boolean properties.
virtual bool insertWriters(RegisterDescriptor, const AddressSet &writerVas)
Insert writer information.
virtual void accessCreatesLocations(bool b)
Property: Whether access can create new locations.
virtual void print(std::ostream &, Formatter &) const override
Print the register contents.
virtual ExtentMap stored_parts(RegisterDescriptor) const
Returns a description of which bits of a register are stored.
virtual void eraseWriters(RegisterDescriptor)
Erase all writers.
virtual void erase_register(RegisterDescriptor, RiscOperators *)
Cause a register to not be stored.
virtual RegisterStatePtr clone() const override
Make a copy of this register state.
virtual void hash(Combinatorics::Hasher &, RiscOperators *) const override
Hash the register state.
Sawyer::Container::IntervalSetMap< BitRange, AddressSet > BitAddressSet
Virtual addresses per bit.
virtual SValuePtr readRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators *) override
Read a value from a register.
virtual void clear() override
Removes stored values from the register state.
virtual void setWriters(RegisterDescriptor, const AddressSet &writers)
Set writer information.
virtual bool is_wholly_stored(RegisterDescriptor) const
Determines if the specified register is wholly stored in the state.
virtual void traverse(Visitor &)
Traverse register/value pairs.
virtual RegPairs overlappingRegisters(RegisterDescriptor) const
Find stored registers overlapping with specified register.
virtual bool hasWritersAny(RegisterDescriptor) const
Whether a register has writers.
virtual void initialize_large()
Initialize all registers of the dictionary.
virtual bool is_exactly_stored(RegisterDescriptor) const
Determines if the specified register is stored exactly in the state.
static RegisterStateGenericPtr instance(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict)
Instantiate a new register state.
virtual bool is_partly_stored(RegisterDescriptor) const
Determines if some of the specified register is stored in the state.
Sawyer::Container::Interval< size_t > BitRange
A range of bits indexes.
virtual RegisterStatePtr create(const SValuePtr &protoval, const RegisterDictionaryPtr &regdict) const override
Virtual constructor.
virtual void initialize_small()
Initialize all registers of the dictionary.
virtual void eraseProperties(RegisterDescriptor)
Erase all Boolean properties.
virtual bool hasPropertyAny(RegisterDescriptor, InputOutputProperty) const
Whether a register has the specified property.
static RegisterStateGenericPtr promote(const RegisterStatePtr &from)
Run-time promotion of a base register state pointer to a RegisterStateGeneric pointer.
virtual bool hasWritersAll(RegisterDescriptor) const
Whether a register has writers.
virtual AddressSet getWritersIntersection(RegisterDescriptor) const
Get writer information.
virtual AddressSet getWritersUnion(RegisterDescriptor) const
Get writer information.
Sawyer::Container::Map< RegStore, BitAddressSet > RegisterAddressSet
Virtual addresses for all registers.
Sawyer::Container::Map< RegStore, BitProperties > RegisterProperties
Boolean properties for all registers.
virtual bool merge(const RegisterStatePtr &other, RiscOperators *) override
Merge register states for data flow analysis.
virtual SValuePtr peekRegister(RegisterDescriptor, const SValuePtr &dflt, RiscOperators *) override
Read a register without side effects.
virtual void accessModifiesExistingLocations(bool b)
Property: Whether stored registers are adapted to access patterns.
void initialize_nonoverlapping(const std::vector< RegisterDescriptor > &, bool initialize_to_zero)
Initialize the specified registers of the dictionary.
virtual bool eraseProperties(RegisterDescriptor, const InputOutputPropertySet &)
Erase Boolean properties.
virtual void eraseWriters(RegisterDescriptor, const AddressSet &writerVas)
Erase specified writers.
virtual void writeRegister(RegisterDescriptor, const SValuePtr &value, RiscOperators *) override
Write a value to a register.
bool accessModifiesExistingLocations() const
Property: Whether stored registers are adapted to access patterns.
bool accessCreatesLocations() const
Property: Whether access can create new locations.
virtual void updateWriteProperties(RegisterDescriptor, InputOutputProperty) override
Update register properties after writing to a register.
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 bool hasPropertyAll(RegisterDescriptor, InputOutputProperty) const
Whether a register has the specified property.
virtual InputOutputPropertySet getPropertiesUnion(RegisterDescriptor) const
Get properties.
virtual std::vector< RegisterDescriptor > findProperties(const InputOutputPropertySet &required, const InputOutputPropertySet &prohibited=InputOutputPropertySet()) const
Get registers having certain properties.
virtual RegPairs get_stored_registers() const
Returns the list of all registers and their values.
virtual void setProperties(RegisterDescriptor, const InputOutputPropertySet &)
Assign property set.
virtual InputOutputPropertySet getPropertiesIntersection(RegisterDescriptor) const
Get properties.
Sawyer::Container::Map< RegStore, RegPairs > Registers
Values for all registers.
Sawyer::Container::IntervalSetMap< BitRange, InputOutputPropertySet > BitProperties
Boolean properties per bit.
RegisterDictionaryPtr regdict
Registers that are able to be stored by this state.
Base class for most instruction semantics RISC operators.
Describes (part of) a physical CPU register.
size_t offset() const
Property: Offset to least-significant bit.
unsigned minorNumber() const
Property: Minor number.
unsigned majorNumber() const
Property: Major number.
size_t nBits() const
Property: Size in bits.
Base class for all ROSE exceptions.
Mapping from integers to sets.
Range of values delimited by endpoints.
Definition Interval.h:31
static Interval baseSize(size_t lo, size_t size)
Construct an interval from one endpoint and a size.
Definition Interval.h:173
Container associating values with keys.
Definition Sawyer/Map.h:72
Ordered set of values.
Definition Set.h:56
boost::shared_ptr< class RegisterStateGeneric > RegisterStateGenericPtr
Shared-ownership pointer to generic register states.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
Sawyer::Container::Set< InputOutputProperty > InputOutputPropertySet
Set of Boolean properties.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
The ROSE library.