ROSE  0.11.145.0
BasicBlock.h
1 #ifndef ROSE_BinaryAnalysis_Partitioner2_BasicBlock_H
2 #define ROSE_BinaryAnalysis_Partitioner2_BasicBlock_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 #include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
6 
7 #include <Rose/BinaryAnalysis/Partitioner2/Semantics.h>
8 #include <Rose/SourceLocation.h>
9 #include <AstSerialization.h> // rose
10 
11 #include <Sawyer/Attribute.h>
12 #include <Sawyer/Cached.h>
13 #include <Sawyer/Map.h>
14 #include <Sawyer/Optional.h>
15 #include <Sawyer/SharedPointer.h>
16 #include <Sawyer/Synchronization.h>
17 
18 #include <boost/serialization/access.hpp>
19 #include <boost/serialization/base_object.hpp>
20 #include <boost/serialization/set.hpp>
21 #include <boost/serialization/string.hpp>
22 #include <boost/serialization/vector.hpp>
23 
24 namespace Rose {
25 namespace BinaryAnalysis {
26 namespace Partitioner2 {
27 
29 
31 // BasicBlockSemantics
33 
39 public:
47 
53 
59 
65 
71 
73  bool wasDropped;
74 
75 public:
78  : usingDispatcher(false), wasDropped(false) {}
79 
84  bool isSemanticsDropped() const {
85  return dispatcher && !initialState;
86  }
87 
92  bool isSemanticsError() const {
93  return dispatcher && initialState && !usingDispatcher;
94  }
95 
102  return usingDispatcher && operators ? operators->currentState() : BaseSemantics::StatePtr();
103  }
104 };
105 
108 private:
109  Semantics::SValuePtr expr_;
110  EdgeType type_;
111  Confidence confidence_;
112 
113 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
114 private:
115  friend class boost::serialization::access;
116 
117  template<class S>
118  void serialize(S &s, const unsigned /*version*/) {
119  s & BOOST_SERIALIZATION_NVP(expr_);
120  s & BOOST_SERIALIZATION_NVP(type_);
121  s & BOOST_SERIALIZATION_NVP(confidence_);
122  }
123 #endif
124 
125 public: // "protected" fails for boost-1.58.
126  // intentionally undocumented; needed for serialization
128  : type_(E_USER_DEFINED), confidence_(ASSUMED) {}
129 
130 public:
132  : expr_(expr), type_(type), confidence_(confidence) {}
133 
135  const Semantics::SValuePtr& expr() const { return expr_; }
136 
138  EdgeType type() const { return type_; }
139  void type(EdgeType t) { type_ = t; }
140 
144  Confidence confidence() const { return confidence_; }
145  void confidence(Confidence c) { confidence_ = c; }
147 };
148 
150 // BasicBlock
152 
175 public:
178 
181 
184 
185 private:
186  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
187 
188  bool isFrozen_; // True when the object becomes read-only
189  rose_addr_t startVa_; // Starting address, perhaps redundant with insns_[0]->p_address
190  std::string comment_; // Mutli-line plain-text comment
191  std::vector<SgAsmInstruction*> insns_; // Instructions in the order they're executed
192  BasicBlockSemantics semantics_; // All semantics-related information
193  std::vector<DataBlockPtr> dblocks_; // Data blocks owned by this basic block, sorted
194  SourceLocation sourceLocation_; // Optional location of basic block in source code
195 
196  // When a basic block gets lots of instructions some operations become slow due to the linear nature of the instruction
197  // list. Therefore, we also keep a mapping from instruction address to position in the list. The mapping is only used when
198  // the bigBlock size is reached.
199  static const size_t bigBlock_ = 200;
201  InsnAddrMap insnAddrMap_; // maps instruction address to index in insns_ vector
202 
203  // The following members are caches either because their value is seldom needed and expensive to compute, or because
204  // the value is best computed at a higher layer than a single basic block (e.g., in the partitioner) yet it makes the
205  // most sense to store it here. Make sure clearCache() resets these to initial values.
206  Sawyer::Cached<Successors> successors_; // control flow successors out of final instruction
207  Sawyer::Cached<std::set<rose_addr_t> > ghostSuccessors_;// non-followed successors from opaque predicates, all insns
208  Sawyer::Cached<bool> isFunctionCall_; // is this block semantically a function call?
209  Sawyer::Cached<bool> isFunctionReturn_; // is this block semantically a return from the function?
210  Sawyer::Cached<bool> mayReturn_; // a function return is reachable from this basic block in the CFG
211  Sawyer::Cached<bool> popsStack_; // basic block has a net popping effect
212  void clearCacheNS() const;
213 public:
214  void copyCache(const BasicBlockPtr &other);
215 
216 
218  // Serialization
220 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
221 private:
222  friend class boost::serialization::access;
223 
224  template<class S>
225  void serialize(S &s, const unsigned version) {
226  //s & boost::serialization::base_object<Sawyer::Attribute::Storage<> >(*this); -- not saved
227  s & BOOST_SERIALIZATION_NVP(isFrozen_);
228  s & BOOST_SERIALIZATION_NVP(startVa_);
229  s & BOOST_SERIALIZATION_NVP(comment_);
230 
231  size_t nInsns = insns_.size(); // zero when loading
232  s & BOOST_SERIALIZATION_NVP(nInsns);
233  insns_.resize(nInsns); // no-op when saving
234  for (size_t i = 0; i < nInsns; ++i)
235  transferAst(s, insns_[i]);
236 
237  s & BOOST_SERIALIZATION_NVP(insns_);
238  s & boost::serialization::make_nvp("dispatcher_", semantics_.dispatcher);
239  s & boost::serialization::make_nvp("operators_", semantics_.operators);
240  s & boost::serialization::make_nvp("initialState_", semantics_.initialState);
241  s & boost::serialization::make_nvp("usingDispatcher_", semantics_.usingDispatcher);
242  s & boost::serialization::make_nvp("optionalPenultimateState_", semantics_.optionalPenultimateState);
243  s & BOOST_SERIALIZATION_NVP(dblocks_);
244  s & BOOST_SERIALIZATION_NVP(insnAddrMap_);
245  s & BOOST_SERIALIZATION_NVP(successors_);
246  s & BOOST_SERIALIZATION_NVP(ghostSuccessors_);
247  s & BOOST_SERIALIZATION_NVP(isFunctionCall_);
248  s & BOOST_SERIALIZATION_NVP(isFunctionReturn_);
249  s & BOOST_SERIALIZATION_NVP(mayReturn_);
250  if (version >= 1)
251  s & BOOST_SERIALIZATION_NVP(popsStack_);
252  if (version >= 2)
253  s & BOOST_SERIALIZATION_NVP(sourceLocation_);
254  }
255 #endif
256 
257 
259  // Constructors
261 protected:
262  BasicBlock(); // needed for serialization
263 
264  // use instance() instead
265  BasicBlock(rose_addr_t startVa, const PartitionerConstPtr&);
266 public:
267  ~BasicBlock();
268 
269 public:
275  static Ptr instance(rose_addr_t startVa, const PartitionerConstPtr &partitioner) {
276  return Ptr(new BasicBlock(startVa, partitioner));
277  }
278 
284  virtual Ptr create(rose_addr_t startVa, const PartitionerConstPtr &partitioner) const {
285  return instance(startVa, partitioner);
286  }
287 
289  // Cache
291 public:
295  void clearCache() {
296  SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
297  clearCacheNS();
298  }
299 
301  // Status
303 public:
309  bool isFrozen() const {
310  SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
311  return isFrozen_;
312  }
313 
321  const std::string& comment() const { return comment_; }
322  void comment(const std::string &s) { comment_ = s; }
328  const SourceLocation& sourceLocation() const { return sourceLocation_; }
329  void sourceLocation(const SourceLocation &loc) { sourceLocation_ = loc; }
333  // Instructions
336 public:
344  rose_addr_t address() const {
345  SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
346  return startVa_;
347  }
348 
356 
363  rose_addr_t fallthroughVa() const;
364 
368  size_t nInstructions() const {
369  SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
370  return insns_.size();
371  }
372 
380  bool isEmpty() const {
381  SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
382  return insns_.empty();
383  }
384 
391  SgAsmInstruction* instructionExists(rose_addr_t startVa) const;
392 
400 
407  Sawyer::Optional<size_t> instructionIndex(rose_addr_t) const;
418  const std::vector<SgAsmInstruction*>& instructions() const { return insns_; }
419 
438 
445  void pop();
446 
453  std::set<rose_addr_t> explicitConstants() const;
454 
455 
457  // Static data blocks
459 public:
463  size_t nDataBlocks() const;
464 
471 
479 
488  bool insertDataBlock(const DataBlockPtr&);
489 
498 
504  const std::vector<DataBlockPtr>& dataBlocks() const { return dblocks_; }
505 
506 
508  // Semantics
510 public:
518 
526  void dropSemantics(const PartitionerConstPtr&);
527 
536 
537 
538 
540  // Control flow
542 public:
553  const Sawyer::Cached<Successors>& successors() const { return successors_; }
554  void successors(const Successors&);
567  const Sawyer::Cached<std::set<rose_addr_t> >& ghostSuccessors() const { return ghostSuccessors_; }
568 
580  void insertSuccessor(rose_addr_t va, size_t nBits, EdgeType type=E_NORMAL, Confidence confidence=ASSUMED);
586  void clearSuccessors();
587 
588 
590  // Cached properties computed elsewhere
592 public:
601  const Sawyer::Cached<bool>& isFunctionCall() const { return isFunctionCall_; }
602  void isFunctionCall(bool flag) const { isFunctionCall_.set(flag); }
603 
611  const Sawyer::Cached<bool>& isFunctionReturn() const { return isFunctionReturn_; }
612  void isFunctionReturn(bool flag) const { isFunctionReturn_.set(flag); }
613 
620  const Sawyer::Cached<bool>& mayReturn() const { return mayReturn_; }
621  void mayReturn(bool flag) const { mayReturn_.set(flag); }
622 
628  const Sawyer::Cached<bool>& popsStack() const { return popsStack_; }
629  void popsStack(bool flag) const { popsStack_.set(flag); }
630 
631 
633  // Output
635 public:
639  std::string printableName() const;
640 
641 
643  // Private members for the partitioner
645 private:
646  friend class Partitioner;
647  void init(const PartitionerConstPtr&);
648  void freeze() { isFrozen_ = true; semantics_.optionalPenultimateState = Sawyer::Nothing(); }
649  void thaw() { isFrozen_ = false; }
650  BasicBlockSemantics undropSemanticsNS(const PartitionerConstPtr&);
651 
652  // Find an equivalent data block and replace it with the specified data block, or insert the specified data block.
653  void replaceOrInsertDataBlock(const DataBlockPtr&);
654 };
655 
656 } // namespace
657 } // namespace
658 } // namespace
659 
660 // Class versions must be at global scope
661 BOOST_CLASS_VERSION(Rose::BinaryAnalysis::Partitioner2::BasicBlock, 2);
662 
663 #endif
664 #endif
Confidence confidence() const
Confidence level of this successor.
Definition: BasicBlock.h:144
const std::string & comment() const
Comment.
Definition: BasicBlock.h:321
const Semantics::SValuePtr & expr() const
Symbolic expression for the successor address.
Definition: BasicBlock.h:135
DataBlockPtr dataBlockExists(const DataBlockPtr &) const
Determine if this basic block contains the specified data block or equivalent data block...
virtual Ptr create(rose_addr_t startVa, const PartitionerConstPtr &partitioner) const
Virtual constructor.
Definition: BasicBlock.h:284
Information about a source location.
void pop()
Undo the latest append.
const Sawyer::Cached< std::set< rose_addr_t > > & ghostSuccessors() const
Ghost successors.
Definition: BasicBlock.h:567
DataBlockPtr eraseDataBlock(const DataBlockPtr &)
Remove specified or equivalent data block from this basic block.
size_t nDataBlocks() const
Get the number of data blocks owned.
void insertSuccessor(const BaseSemantics::SValuePtr &, EdgeType type=E_NORMAL, Confidence confidence=ASSUMED)
Insert a new successor.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Base class for machine instructions.
void comment(const std::string &s)
Comment.
Definition: BasicBlock.h:322
bool wasDropped
Whether the semantics had been dropped and reconstructed.
Definition: BasicBlock.h:73
bool usingDispatcher
Whether semantic state is up-to-date.
Definition: BasicBlock.h:64
BaseSemantics::StatePtr finalState() const
Return the final semantic state.
Definition: BasicBlock.h:101
BaseSemantics::RiscOperatorsPtr operators
Risc operators.
Definition: BasicBlock.h:52
const std::vector< DataBlockPtr > & dataBlocks() const
Data blocks owned.
Definition: BasicBlock.h:504
void confidence(Confidence c)
Confidence level of this successor.
Definition: BasicBlock.h:145
Information related to instruction semantics.
Definition: BasicBlock.h:38
void clearCache()
Clear all cached data.
Definition: BasicBlock.h:295
Main namespace for the ROSE library.
A container holding a set of values.
Definition: IntervalSet.h:55
Sawyer::Optional< size_t > instructionIndex(rose_addr_t) const
Position of an instruction.
Sawyer::Optional< BaseSemantics::StatePtr > optionalPenultimateState
The state just prior to executing the final instruction.
Definition: BasicBlock.h:70
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
rose_addr_t address() const
Get the address for a basic block.
Definition: BasicBlock.h:344
BasicBlockSemantics()
Construct an empty semantics object.
Definition: BasicBlock.h:77
const Sawyer::Cached< bool > & popsStack() const
Pops stack property.
Definition: BasicBlock.h:628
AddressIntervalSet dataAddresses() const
Addresses that are part of static data.
The value is an assumption without any proof.
bool isSemanticsDropped() const
Determines whether semantics have been dropped.
Definition: BasicBlock.h:84
const Sawyer::Cached< bool > & isFunctionCall() const
Is a function call?
Definition: BasicBlock.h:601
SgAsmInstruction * instructionExists(rose_addr_t startVa) const
Determine if this basic block contains an instruction at a specific address.
std::string printableName() const
A printable name for this basic block.
bool isSemanticsError() const
Determines whether a semantics error was encountered.
Definition: BasicBlock.h:92
void append(const PartitionerConstPtr &, SgAsmInstruction *)
Append an instruction to a basic block.
const SourceLocation & sourceLocation() const
Optional location in source code.
Definition: BasicBlock.h:328
void clearSuccessors()
Clear all successor information.
bool isEmpty() const
Return true if this basic block has no instructions.
Definition: BasicBlock.h:380
Sawyer::SharedPointer< const Partitioner > PartitionerConstPtr
Shared-ownership pointer for Partitioner.
BasicBlockSemantics semantics() const
Return information about semantics.
const Sawyer::Cached< bool > & isFunctionReturn() const
Is a function return?
Definition: BasicBlock.h:611
bool isFrozen() const
Determine if basic block is read-only.
Definition: BasicBlock.h:309
BasicBlockSemantics undropSemantics(const PartitionerConstPtr &)
Undrop semantics.
bool insertDataBlock(const DataBlockPtr &)
Make this basic block own the specified data block or equivalent data block.
std::vector< BasicBlockSuccessor > BasicBlockSuccessors
All successors in no particular order.
void sourceLocation(const SourceLocation &loc)
Optional location in source code.
Definition: BasicBlock.h:329
Sawyer::SharedPointer< BasicBlock > Ptr
Shared pointer to a basic block.
Definition: BasicBlock.h:177
void set(const Value &x) const
Assign a new value.
Definition: Cached.h:101
Base class for reference counted objects.
Definition: SharedObject.h:64
BaseSemantics::DispatcherPtr dispatcher
How instructions are dispatched.
Definition: BasicBlock.h:46
BasicBlockSuccessors Successors
All successors in no particular order.
Definition: BasicBlock.h:183
void dropSemantics(const PartitionerConstPtr &)
Drops semantic information.
static Ptr instance(rose_addr_t startVa, const PartitionerConstPtr &partitioner)
Static allocating constructor.
Definition: BasicBlock.h:275
size_t nInstructions() const
Get the number of instructions in this block.
Definition: BasicBlock.h:368
BaseSemantics::StatePtr initialState
Initial state for semantics.
Definition: BasicBlock.h:58
API and storage for attributes.
Definition: Attribute.h:215
Sawyer::SharedPointer< DataBlock > DataBlockPtr
Shared-ownership pointer for DataBlock.
const Sawyer::Cached< Successors > & successors() const
Control flow successors.
Definition: BasicBlock.h:553
Represents no value.
Definition: Optional.h:32
const std::vector< SgAsmInstruction * > & instructions() const
Get the instructions for this block.
Definition: BasicBlock.h:418
AddressIntervalSet insnAddresses() const
Get all instruction addresses.
const Sawyer::Cached< bool > & mayReturn() const
May-return property.
Definition: BasicBlock.h:620
std::set< rose_addr_t > explicitConstants() const
Set of explicit constants.
rose_addr_t fallthroughVa() const
Get the address after the end of the final instruction.
EdgeType type() const
Type of successor.
Definition: BasicBlock.h:138