ROSE  0.11.98.0
Variables.h
1 #ifndef ROSE_BinaryAnalysis_Variables_H
2 #define ROSE_BinaryAnalysis_Variables_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics/Types.h>
7 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics/MemoryCellState.h>
8 #include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
9 #include <Rose/BinaryAnalysis/SymbolicExpr.h>
10 
11 #include <Sawyer/IntervalMap.h>
12 #include <Sawyer/Message.h>
13 #include <Sawyer/Optional.h>
14 #include <Sawyer/Set.h>
15 
16 #include <boost/serialization/access.hpp>
17 #include <boost/serialization/split_member.hpp>
18 
19 namespace Rose {
20 namespace BinaryAnalysis {
21 
23 namespace Variables {
24 
26 // Basic types
28 
31 
33 typedef std::map<int64_t /*offset*/, AddressSet> OffsetToAddresses;
34 
36 typedef std::map<rose_addr_t /*globalVa*/, AddressSet /*insns*/> AddressToAddresses;
37 
40 
42 // Global variables
44 
47 
49 // Global utilities
51 
53 void initDiagnostics();
54 
56 std::string offsetStr(int64_t offset);
57 
59 std::string sizeStr(uint64_t size);
60 
62 // Base class for variable descriptors
64 
66 class BaseVariable {
67  rose_addr_t maxSizeBytes_ = 0; // maximum possible size of this variable in bytes
68  AddressSet insnVas_; // instructions where the variable was detected that reference the variable
70  std::string name_; // optional variable name
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(maxSizeBytes_);
79  s & BOOST_SERIALIZATION_NVP(insnVas_);
80  s & BOOST_SERIALIZATION_NVP(ioProperties_);
81  s & BOOST_SERIALIZATION_NVP(name_);
82  }
83 #endif
84 
85 protected:
89  BaseVariable();
90 
92  BaseVariable(size_t maxSizeBytes, const AddressSet &definingInstructionVas, const std::string &name);
93 
94 public:
95  BaseVariable(const BaseVariable&);
96  ~BaseVariable();
97 
98 public:
105  rose_addr_t maxSizeBytes() const;
106  void maxSizeBytes(rose_addr_t size);
115  const AddressSet& definingInstructionVas() const;
116  AddressSet& definingInstructionVas();
117  void definingInstructionVas(const AddressSet &vas);
136  const std::string& name() const;
137  void name(const std::string &s);
139 };
140 
142 // Local variable descriptors
144 
147 public:
149  enum class Purpose {
151  FRAME_POINTER,
152  SPILL_AREA,
153  NORMAL,
154  UNKNOWN,
155  OTHER
156  };
157 
162  struct Boundary {
163  int64_t frameOffset = 0;
164  AddressSet definingInsns;
166  };
167 
169  using Boundaries = std::vector<Boundary>;
170 
171 private:
172  Partitioner2::FunctionPtr function_; // function in which local variable exists
173  int64_t frameOffset_ = 0; // offset where variable is located in the function's stack frame
174  Purpose purpose_ = Purpose::UNKNOWN;
175 
176 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
177 private:
178  friend class boost::serialization::access;
179 
180  template<class S>
181  void serialize(S &s, const unsigned version) {
182  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BaseVariable);
183  s & BOOST_SERIALIZATION_NVP(function_);
184  s & BOOST_SERIALIZATION_NVP(frameOffset_);
185  if (version >= 1)
186  s & BOOST_SERIALIZATION_NVP(purpose_);
187  }
188 #endif
189 
190 public:
194  StackVariable();
195 
198  const AddressSet &definingInstructionVas = AddressSet(), const std::string &name = "");
199 
201  ~StackVariable();
202 
208  Partitioner2::FunctionPtr function() const;
209  void function(const Partitioner2::FunctionPtr&);
219  int64_t frameOffset() const;
220  void frameOffset(int64_t offset);
228  Purpose purpose() const;
229  void purpose(Purpose p);
235  const std::string& setDefaultName();
236 
243  bool operator==(const StackVariable &other) const;
244  bool operator!=(const StackVariable &other) const;
248  OffsetInterval interval() const;
249 
253  static Boundary& insertBoundary(Boundaries& /*in,out*/, int64_t frameOffset, rose_addr_t insnVa);
254 
258  void print(std::ostream&) const;
259  std::string toString() const;
263  friend std::ostream& operator<<(std::ostream&, const Rose::BinaryAnalysis::Variables::StackVariable&);
264 };
265 
268 
273 void print(const StackVariables&, const Partitioner2::Partitioner&, std::ostream &out, const std::string &prefix = "");
274 
276 // Global variable descriptors
278 
281  rose_addr_t address_ = 0; // starting (lowest) virtual address
282 
283 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
284 private:
285  friend class boost::serialization::access;
286 
287  template<class S>
288  void serialize(S &s, const unsigned /*version*/) {
289  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(BaseVariable);
290  s & BOOST_SERIALIZATION_NVP(address_);
291  }
292 #endif
293 
294 public:
298  GlobalVariable();
299 
305  GlobalVariable(rose_addr_t startingAddress, rose_addr_t maxSizeBytes,
306  const AddressSet &definingInstructionVas = AddressSet(), const std::string &name = "");
307 
308  ~GlobalVariable();
309 
315  rose_addr_t address() const;
316  void address(rose_addr_t va);
322  const std::string& setDefaultName();
323 
329  bool operator==(const GlobalVariable &other) const;
330  bool operator!=(const GlobalVariable &other) const;
334  AddressInterval interval() const;
335 
339  void print(std::ostream&) const;
340  std::string toString() const;
344  friend std::ostream& operator<<(std::ostream&, const Rose::BinaryAnalysis::Variables::GlobalVariable&);
345 };
346 
353 
358 void print(const GlobalVariables&,const Partitioner2::Partitioner&, std::ostream &out, const std::string &prefix = "");
359 
361 // StackFrame
363 
387 struct StackFrame {
388  enum Direction {
391  };
392 
398  std::string rule;
399 };
400 
402 // Analyzer
404 
407 public:
409  struct Settings {};
410 
413 
414 private:
415  Settings settings_;
416 
417 protected:
418  explicit VariableFinder(const Settings&);
419 public:
420  ~VariableFinder();
421 
422 public:
424  static Ptr instance(const Settings &settings = Settings());
425 
429  const Settings& settings() const { return settings_; }
430  Settings& settings() { return settings_; }
466  GlobalVariables findGlobalVariables(const Partitioner2::Partitioner&);
467 
474  void evict(const Partitioner2::FunctionPtr&);
475  void evict(const Partitioner2::Partitioner&);
482  bool isCached(const Partitioner2::FunctionPtr&);
483 
486 
494  StackVariable::Boundaries &boundaries /*in,out*/);
495 
496 #if 0 // [Robb Matzke 2021-10-27]
497 
502  OffsetInterval referencedFrameArea(const Partitioner2::Partitioner&,
504  const SymbolicExpr::Ptr &address, size_t nBytes);
505 #endif
506 
511  std::set<int64_t> findFrameOffsets(const StackFrame&, const Partitioner2::Partitioner&, SgAsmInstruction*);
512 
518 
554  AddressToAddresses findGlobalVariableVas(const Partitioner2::Partitioner&);
555 
559  std::set<rose_addr_t> findConstants(const SymbolicExpr::Ptr&);
560 
562  std::set<rose_addr_t> findConstants(SgAsmInstruction*);
563 
568 
573 
574 #if 0 // [Robb Matzke 2021-10-27]
575 
579  symbolicAddress(const Partitioner2::Partitioner&, const StackVariable&,
581 #endif
582 
591  StackVariable::Boundaries &sortedBoundaries /*in,out*/);
592 };
593 
594 } // namespace
595 } // namespace
596 } // namespace
597 
598 // Class versions must be at global scope
599 BOOST_CLASS_VERSION(Rose::BinaryAnalysis::Variables::StackVariable, 1);
600 
601 #endif
602 #endif
std::string toString() const
Printing global variable.
friend std::ostream & operator<<(std::ostream &, const Rose::BinaryAnalysis::Variables::StackVariable &)
Print local variable descriptor.
const Settings & settings() const
Settings for this analysis.
Definition: Variables.h:429
const AddressSet & definingInstructionVas() const
Property: Addresses of instructions related to this variable.
New frames are added at higher addresses than old frames.
Definition: Variables.h:389
Description of a global variable.
Definition: Variables.h:280
void initializeFrameBoundaries(const StackFrame &, const Partitioner2::Partitioner &, const Partitioner2::FunctionPtr &, StackVariable::Boundaries &boundaries)
Initilialize offsets for function prologue.
Sawyer::Message::Facility mlog
Diagnostic facility.
std::set< int64_t > findFrameOffsets(const StackFrame &, const Partitioner2::Partitioner &, SgAsmInstruction *)
Find stack variable addresses.
int64_t frameOffset
Address of boundary with respect to frame pointer.
Definition: Variables.h:163
boost::shared_ptr< class MemoryCellState > MemoryCellStatePtr
Shared-ownership pointer to a cell-based memory state.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Base class for machine instructions.
Collection of streams.
Definition: Message.h:1606
std::set< SymbolicExpr::Ptr > getMemoryAddresses(const InstructionSemantics::BaseSemantics::MemoryCellStatePtr &)
Find addresses in memory state.
AddressInterval interval() const
Location of variable in memory.
Analysis to find variable locations.
Definition: Variables.h:406
Sawyer::SharedPointer< VariableFinder > VariableFinderPtr
Reference counting pointer.
std::vector< Boundary > Boundaries
List of boundaries.
Definition: Variables.h:169
Describes a local or global variable.
Definition: Variables.h:66
const std::string & name() const
Property: Optional variable name.
const std::string & setDefaultName()
Give variable a defult name.
void evict(const Partitioner2::FunctionPtr &)
Removed cached information.
const InstructionSemantics::BaseSemantics::InputOutputPropertySet & ioProperties() const
Property: I/O properties.
AddressToAddresses findGlobalVariableVas(const Partitioner2::Partitioner &)
Find global variable addresses.
void removeOutliers(const StackFrame &, const Partitioner2::Partitioner &, const Partitioner2::FunctionPtr &, StackVariable::Boundaries &sortedBoundaries)
Remove boundaries that are outside a stack frame.
friend std::ostream & operator<<(std::ostream &, const Rose::BinaryAnalysis::Variables::GlobalVariable &)
Print global variable descriptor.
bool operator==(const StackVariable &other) const
Compare two local variables.
void print(const StackVariables &, const Partitioner2::Partitioner &, std::ostream &out, const std::string &prefix="")
Print info about multiple local variables.
void initDiagnostics()
Initialize diagnostic output.
Main namespace for the ROSE library.
std::map< rose_addr_t, AddressSet > AddressToAddresses
Mapping from addresses to address sets.
Definition: Variables.h:36
static Ptr instance(const Settings &settings=Settings())
Allocating constructor.
New frames are added at lower addresses than old frames.
Definition: Variables.h:390
rose_addr_t address() const
Property: Starting address.
Sawyer::Optional< int64_t > minOffset
Minimum frame offset w.r.t.
Definition: Variables.h:396
OffsetInterval interval() const
Location within the function stack frame.
std::string sizeStr(uint64_t size)
Format size as a string.
Purpose purpose() const
Property: Purpose.
void print(std::ostream &) const
Printing global variable.
std::map< int64_t, AddressSet > OffsetToAddresses
Mapping from stack offsets to address sets.
Definition: Variables.h:33
Sawyer::Optional< uint64_t > size
Size of the frame in bytes if known.
Definition: Variables.h:397
Describes (part of) a physical CPU register.
Direction growthDirection
Direction that the stack grows when pushing a new frame.
Definition: Variables.h:393
bool isCached(const Partitioner2::FunctionPtr &)
Test whether local variable information is cached.
static Boundary & insertBoundary(Boundaries &, int64_t frameOffset, rose_addr_t insnVa)
Insert a new boundary or adjust an existing boundary.
rose_addr_t maxSizeBytes() const
Property: Maximum variable size in bytes.
std::set< rose_addr_t > findConstants(const SymbolicExpr::Ptr &)
Find address constants in an expression.
std::string offsetStr(int64_t offset)
Format a stack offset as a string.
Information about a stack frame.
Definition: Variables.h:387
Purpose purpose
Purpose of addresses above this boundary.
Definition: Variables.h:165
Settings that control this analysis.
Definition: Variables.h:409
const std::string & setDefaultName()
Give variable a defult name.
Sawyer::Optional< int64_t > maxOffset
Maximum frame offset w.r.t.
Definition: Variables.h:395
bool operator!=(const StackVariable &other) const
Compare two local variables.
Binary analysis.
AddressSet definingInsns
Instructions that define this boundary.
Definition: Variables.h:164
Sawyer::Container::Set< rose_addr_t > AddressSet
Set of addresses.
Definition: Variables.h:30
Base class for reference counted objects.
Definition: SharedObject.h:64
std::string toString() const
Printing local variable.
RegisterDescriptor framePointerRegister
Optional descriptor for register pointing to latest frame.
Definition: Variables.h:394
Range of values delimited by endpoints.
Definition: Interval.h:33
std::string rule
Informal rule name used to detect frame characteristics.
Definition: Variables.h:398
StackFrame detectFrameAttributes(const Partitioner2::Partitioner &, const Partitioner2::FunctionPtr &)
Figure out attributes describing the stack frame for the specified function.
int64_t frameOffset() const
Property: Frame offset.
void print(std::ostream &) const
Printing local variable.
std::set< rose_addr_t > findAddressConstants(const InstructionSemantics::BaseSemantics::MemoryCellStatePtr &)
Find constants in memory.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:294
Sawyer::Container::IntervalMap< AddressInterval, GlobalVariable > GlobalVariables
Maps virtual addresses to global variables.
Definition: Variables.h:352
Partitioner2::FunctionPtr functionForInstruction(const Partitioner2::Partitioner &, SgAsmInstruction *)
Function that owns an instruction.
Sawyer::Container::Interval< int64_t > OffsetInterval
Interval of signed offsets.
Definition: Variables.h:39
StackVariables findStackVariables(const Partitioner2::Partitioner &, const Partitioner2::FunctionPtr &)
Find local variables in a function.
GlobalVariables findGlobalVariables(const Partitioner2::Partitioner &)
Find global variables.
Description of a local stack variable within a function.
Definition: Variables.h:146
Settings & settings()
Settings for this analysis.
Definition: Variables.h:430
bool operator!=(const GlobalVariable &other) const
Compare two global variable descriptors.
bool operator==(const GlobalVariable &other) const
Compare two global variable descriptors.