ROSE  0.11.145.0
Partitioner.h
1 #ifndef ROSE_BinaryAnalysis_Partitioner2_Partitioner_H
2 #define ROSE_BinaryAnalysis_Partitioner2_Partitioner_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 #include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
6 
7 #include <Rose/BinaryAnalysis/Partitioner2/AddressUsageMap.h>
8 #include <Rose/BinaryAnalysis/Partitioner2/Configuration.h>
9 #include <Rose/BinaryAnalysis/Partitioner2/ControlFlowGraph.h>
10 #include <Rose/BinaryAnalysis/Partitioner2/Semantics.h>
11 
12 #include <Rose/BinaryAnalysis/InstructionProvider.h>
13 #include <Rose/BinaryAnalysis/InstructionSemantics/SymbolicSemantics.h>
14 #include <Rose/BinaryAnalysis/SerialIo.h>
15 #include <Rose/BinaryAnalysis/SourceLocations.h>
16 #include <Rose/BinaryAnalysis/Unparser/Settings.h>
17 #include <Rose/Progress.h>
18 
19 #include <Sawyer/Attribute.h>
20 #include <Sawyer/Callbacks.h>
21 #include <Sawyer/IntervalSet.h>
22 #include <Sawyer/Map.h>
23 #include <Sawyer/Message.h>
24 #include <Sawyer/Optional.h>
25 #include <Sawyer/ProgressBar.h>
26 #include <Sawyer/SharedObject.h>
27 #include <Sawyer/SharedPointer.h>
28 
29 #include <boost/filesystem.hpp>
30 #include <boost/format.hpp>
31 #include <boost/move/utility_core.hpp>
32 #include <boost/serialization/access.hpp>
33 #include <boost/serialization/split_member.hpp>
34 #include <boost/serialization/version.hpp>
35 
36 #include <ostream>
37 #include <set>
38 #include <string>
39 #include <vector>
40 
41 // Derived classes needed for serialization
42 #include <Rose/BinaryAnalysis/Z3Solver.h>
43 #include <Rose/BinaryAnalysis/InstructionSemantics/DispatcherAarch32.h>
44 #include <Rose/BinaryAnalysis/InstructionSemantics/DispatcherAarch64.h>
45 #include <Rose/BinaryAnalysis/InstructionSemantics/DispatcherM68k.h>
46 #include <Rose/BinaryAnalysis/InstructionSemantics/DispatcherPowerpc.h>
47 #include <Rose/BinaryAnalysis/InstructionSemantics/DispatcherX86.h>
48 
49 // [Robb Matzke 2022-06-22]: deprecated. Needed because some user code doesn't include the old InstructionSemantics2 header
50 // files where this same thing is defined, yet they use InstructionSemantics2 because such things were once declared by this
51 // header file due to it originally including InstructionSemantics2 headers (which it no longer does).
52 namespace Rose { namespace BinaryAnalysis { namespace InstructionSemantics2 = InstructionSemantics; }}
53 
54 // Define ROSE_PARTITIONER_MOVE if boost::move works. Mainly this is to work around a GCC bug that reports this error:
55 //
56 // prototype for
57 // 'Rose::BinaryAnalysis::Partitioner2::Partitioner::Partitioner(boost::rv<Rose::BinaryAnalysis::Partitioner2::Partitioner>&)'
58 // does not match any in class 'Rose::BinaryAnalysis::Partitioner2::Partitioner'
59 //
60 // followed by saying that the exact same signature is one of the candidates:
61 //
62 // candidates are:
63 // Rose::BinaryAnalysis::Partitioner2::Partitioner::Partitioner(boost::rv<Rose::BinaryAnalysis::Partitioner2::Partitioner>&)
64 //
65 // This is apparently GCC issue 49377 [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49377] fixed in GCC-6.1.0.
66 #if __cplusplus >= 201103L
67  #define ROSE_PARTITIONER_MOVE
68 #elif defined(__GNUC__)
69  #if __GNUC__ > 5
70  #define ROSE_PARTITIONER_MOVE
71  #elif BOOST_VERSION >= 106900 // 1.68.0 might be okay too, but ROSE blacklists it for other reasons
72  #define ROSE_PARTITIONER_MOVE
73  #endif
74 #endif
75 
76 namespace Rose {
77 namespace BinaryAnalysis {
78 namespace Partitioner2 {
79 
293 class ROSE_DLL_API Partitioner /*final*/
294  : public Sawyer::SharedObject, public Sawyer::SharedFromThis<Partitioner>, public Sawyer::Attribute::Storage<> {
295 #ifdef ROSE_PARTITIONER_MOVE
296  BOOST_MOVABLE_BUT_NOT_COPYABLE(Partitioner)
297 #endif
298 
301  //
302  // Types
303  //
306 public:
314  // Callback list types
317  typedef std::vector<FunctionPrologueMatcherPtr> FunctionPrologueMatchers;
318  typedef std::vector<FunctionPaddingMatcherPtr> FunctionPaddingMatchers;
321  struct Thunk {
323  rose_addr_t target;
324  Thunk(const BasicBlockPtr&, rose_addr_t target);
325  ~Thunk();
326  };
327 
330 
333  //
334  // Data members
335  //
338 private:
339  BasePartitionerSettings settings_; // settings adjustable from the command-line
340  Configuration config_; // configuration information about functions, blocks, etc.
341  InstructionProvider::Ptr instructionProvider_; // cache for all disassembled instructions
342  MemoryMap::Ptr memoryMap_; // description of memory, especially insns and non-writable
343  SgAsmInterpretation *interpretation_; // Interpretation corresponding to the memory map
344  ControlFlowGraph cfg_; // basic blocks that will become part of the ROSE AST
345  CfgVertexIndex vertexIndex_; // Vertex-by-address index for the CFG
346  AddressUsageMap aum_; // How addresses are used for each address represented by the CFG
347  SmtSolverPtr solver_; // Satisfiable modulo theory solver used by semantic expressions
348  Functions functions_; // List of all attached functions by entry address
349  bool autoAddCallReturnEdges_; // Add E_CALL_RETURN edges when blocks are attached to CFG?
350  bool assumeFunctionsReturn_; // Assume that unproven functions return to caller?
351  size_t stackDeltaInterproceduralLimit_; // Max depth of call stack when computing stack deltas
352  AddressNameMap addressNames_; // Names for various addresses
353  SourceLocations sourceLocations_; // Mapping between source locations and addresses
354  SemanticMemoryParadigm semanticMemoryParadigm_; // Slow and precise, or fast and imprecise?
355  Unparser::BasePtr unparser_; // For unparsing things to pseudo-assembly
356  Unparser::BasePtr insnUnparser_; // For unparsing single instructions in diagnostics
357  Unparser::BasePtr insnPlainUnparser_; // For unparsing just instruction mnemonic and operands
358 
359  // Callback lists
360  CfgAdjustmentCallbacks cfgAdjustmentCallbacks_;
361  BasicBlockCallbacks basicBlockCallbacks_;
362  FunctionPrologueMatchers functionPrologueMatchers_;
363  FunctionPaddingMatchers functionPaddingMatchers_;
364 
365  // Special CFG vertices.
366  ControlFlowGraph::VertexIterator undiscoveredVertex_;
367  ControlFlowGraph::VertexIterator indeterminateVertex_;
368  ControlFlowGraph::VertexIterator nonexistingVertex_;
369  static const size_t nSpecialVertices = 3;
370 
371  // Optional cached information
372  Sawyer::Optional<rose_addr_t> elfGotVa_; // address of ELF GOT, set by findElfGotVa
373 
374  // Protects the following data members
375  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
376  Progress::Ptr progress_; // Progress reporter to update, or null
377  mutable size_t cfgProgressTotal_; // Expected total for the CFG progress bar; initialized at first report
378 
381  //
382  // Serialization
383  //
386 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
387 private:
388  friend class boost::serialization::access;
389 
390  template<class S>
391  void serializeCommon(S &s, const unsigned version) {
392  s.template register_type<InstructionSemantics::SymbolicSemantics::SValue>();
393  s.template register_type<InstructionSemantics::SymbolicSemantics::RiscOperators>();
394 #ifdef ROSE_ENABLE_ASM_AARCH64
395  s.template register_type<InstructionSemantics::DispatcherAarch64>();
396 #endif
397 #ifdef ROSE_ENABLE_ASM_AARCH32
398  s.template register_type<InstructionSemantics::DispatcherAarch32>();
399 #endif
400  s.template register_type<InstructionSemantics::DispatcherX86>();
401  s.template register_type<InstructionSemantics::DispatcherM68k>();
402  s.template register_type<InstructionSemantics::DispatcherPowerpc>();
403  s.template register_type<SymbolicExpression::Interior>();
404  s.template register_type<SymbolicExpression::Leaf>();
405  s.template register_type<Z3Solver>();
406  s.template register_type<Semantics::SValue>();
407  s.template register_type<Semantics::MemoryListState>();
408  s.template register_type<Semantics::MemoryMapState>();
409  s.template register_type<Semantics::RegisterState>();
410  s.template register_type<Semantics::State>();
411  s.template register_type<Semantics::RiscOperators>();
412  s & BOOST_SERIALIZATION_NVP(settings_);
413  // s & config_; -- FIXME[Robb P Matzke 2016-11-08]
414  s & BOOST_SERIALIZATION_NVP(instructionProvider_);
415  s & BOOST_SERIALIZATION_NVP(memoryMap_);
416  s & BOOST_SERIALIZATION_NVP(cfg_);
417  // s & vertexIndex_; -- initialized by rebuildVertexIndices
418  s & BOOST_SERIALIZATION_NVP(aum_);
419  // s & BOOST_SERIALIZATION_NVP(solver_); -- not saved/restored in order to override from command-line
420  s & BOOST_SERIALIZATION_NVP(functions_);
421  s & BOOST_SERIALIZATION_NVP(autoAddCallReturnEdges_);
422  s & BOOST_SERIALIZATION_NVP(assumeFunctionsReturn_);
423  s & BOOST_SERIALIZATION_NVP(stackDeltaInterproceduralLimit_);
424  s & BOOST_SERIALIZATION_NVP(addressNames_);
425  if (version >= 1)
426  s & BOOST_SERIALIZATION_NVP(sourceLocations_);
427  s & BOOST_SERIALIZATION_NVP(semanticMemoryParadigm_);
428  // s & unparser_; -- not saved; restored from disassembler
429  // s & cfgAdjustmentCallbacks_; -- not saved/restored
430  // s & basicBlockCallbacks_; -- not saved/restored
431  // s & functionPrologueMatchers_; -- not saved/restored
432  // s & functionPaddingMatchers_; -- not saved/restored
433  // s & undiscoveredVertex_; -- initialized by rebuildVertexIndices
434  // s & indeterminateVertex_; -- initialized by rebuildVertexIndices
435  // s & nonexistingVertex_; -- initialized by rebuildVertexIndices
436  if (version >= 2)
437  s & BOOST_SERIALIZATION_NVP(elfGotVa_);
438  // s & progress_; -- not saved/restored
439  // s & cfgProgressTotal_; -- not saved/restored
440  }
441 
442  template<class S>
443  void save(S &s, const unsigned version) const {
444  const_cast<Partitioner*>(this)->serializeCommon(s, version);
445  if (version >= 3)
446  saveAst(s, interpretation_);
447  }
448 
449  template<class S>
450  void load(S &s, const unsigned version) {
451  serializeCommon(s, version);
452  if (version >= 3) {
453  SgNode *node = restoreAst(s);
454  interpretation_ = isSgAsmInterpretation(node);
455  ASSERT_require(!node || interpretation_);
456  }
457  rebuildVertexIndices();
458  }
459 
460  BOOST_SERIALIZATION_SPLIT_MEMBER();
461 #endif
462 
465  //
466  // Constructors
467  //
470 private:
471  // Partitioner objects are reference counted and always allocated on the heap. Use the `instance` methods to construct
472  // these objects. Also, since the Partitioner class is final, we make the constructors private instead of the usual
473  // protected constructors elsewhere in ROSE.
474  Partitioner();
475  Partitioner(const Disassembler::BasePtr&, const MemoryMap::Ptr&);
476 public:
477  ~Partitioner();
478 
479 public:
484  static Ptr instance();
485 
490  static Ptr instance(const Disassembler::BasePtr&, const MemoryMap::Ptr&);
491 
496  static PartitionerPtr instanceFromRbaFile(const boost::filesystem::path&, SerialIo::Format = SerialIo::BINARY);
497 
499  void saveAsRbaFile(const boost::filesystem::path &name, SerialIo::Format fmt) const;
500 
501 #ifdef ROSE_PARTITIONER_MOVE
502 
503  Partitioner(BOOST_RV_REF(Partitioner));
504 
506  Partitioner& operator=(BOOST_RV_REF(Partitioner));
507 #else
508  // These are unsafe
509  Partitioner(const Partitioner&);
510  Partitioner& operator=(const Partitioner&);
511 #endif
512 
519  bool isDefaultConstructed() const;
520 
522  void clear();
523 
531  Configuration& configuration();
532  const Configuration& configuration() const;
540  InstructionProvider& instructionProvider();
541  const InstructionProvider& instructionProvider() const;
551  MemoryMap::Ptr memoryMap() const;
552 
556  SgAsmInterpretation *interpretation() const;
557  void interpretation(SgAsmInterpretation*);
563  bool addressIsExecutable(rose_addr_t) const;
564 
565 
568  //
569  // Unparsing
570  //
573 public:
583  Unparser::BasePtr unparser() const;
584  void unparser(const Unparser::BasePtr&);
596  Unparser::BasePtr insnUnparser() const;
597  void insnUnparser(const Unparser::BasePtr&);
601  void configureInsnUnparser(const Unparser::BasePtr&) const;
602 
606  void configureInsnPlainUnparser(const Unparser::BasePtr&) const;
607 
616  std::string unparse(SgAsmInstruction*) const;
617  void unparse(std::ostream&, SgAsmInstruction*) const;
618  void unparse(std::ostream&, const BasicBlockPtr&) const;
619  void unparse(std::ostream&, const DataBlockPtr&) const;
620  void unparse(std::ostream&, const FunctionPtr&) const;
621  void unparse(std::ostream&) const;
627  std::string unparsePlain(SgAsmInstruction*) const;
628 
631  //
632  // Partitioner CFG queries
633  //
636 public:
642  size_t nBytes() const;
643 
651  ControlFlowGraph::VertexIterator undiscoveredVertex();
652  ControlFlowGraph::ConstVertexIterator undiscoveredVertex() const;
665  ControlFlowGraph::VertexIterator indeterminateVertex();
666  ControlFlowGraph::ConstVertexIterator indeterminateVertex() const;
678  ControlFlowGraph::VertexIterator nonexistingVertex();
679  ControlFlowGraph::ConstVertexIterator nonexistingVertex() const;
688  const ControlFlowGraph& cfg() const;
689 
696  const AddressUsageMap& aum() const;
697 
699  AddressUsageMap aum(const FunctionPtr&) const;
700 
705  std::vector<AddressUser> users(rose_addr_t) const;
706 
714  std::set<rose_addr_t> ghostSuccessors() const;
715 
744  bool isEdgeIntraProcedural(ControlFlowGraph::ConstEdgeIterator edge, const FunctionPtr&) const;
745  bool isEdgeIntraProcedural(const ControlFlowGraph::Edge &edge, const FunctionPtr&) const;
746  bool isEdgeIntraProcedural(ControlFlowGraph::ConstEdgeIterator edge) const;
747  bool isEdgeIntraProcedural(const ControlFlowGraph::Edge &edge) const;
784  bool isEdgeInterProcedural(ControlFlowGraph::ConstEdgeIterator edge) const;
785  bool isEdgeInterProcedural(ControlFlowGraph::ConstEdgeIterator edge, const FunctionPtr &sourceFunction) const;
786  bool isEdgeInterProcedural(ControlFlowGraph::ConstEdgeIterator edge, const FunctionPtr &sourceFunction,
787  const FunctionPtr &targetFunction) const;
788 
789  bool isEdgeInterProcedural(const ControlFlowGraph::Edge &edge) const;
790  bool isEdgeInterProcedural(const ControlFlowGraph::Edge &edge, const FunctionPtr &sourceFunction) const;
791  bool isEdgeInterProcedural(const ControlFlowGraph::Edge &edge, const FunctionPtr &sourceFunction,
792  const FunctionPtr &targetFunction) const;
797  //
800  // Partitioner instruction operations
801  //
804 public:
810  size_t nInstructions() const;
811 
821  AddressUser instructionExists(rose_addr_t startVa) const;
822  AddressUser instructionExists(SgAsmInstruction *insn) const;
831  ControlFlowGraph::ConstVertexIterator instructionVertex(rose_addr_t insnVa) const;
832 
841  std::vector<SgAsmInstruction*> instructionsOverlapping(const AddressInterval&) const;
842 
851  std::vector<SgAsmInstruction*> instructionsSpanning(const AddressInterval&) const;
852 
862  std::vector<SgAsmInstruction*> instructionsContainedIn(const AddressInterval&) const;
863 
871  AddressInterval instructionExtent(SgAsmInstruction*) const;
872 
885  SgAsmInstruction* discoverInstruction(rose_addr_t startVa) const;
886 
891  CrossReferences instructionCrossReferences(const AddressIntervalSet &restriction) const;
892 
893 
894 
897  //
898  // Partitioner basic block placeholder operations
899  //
902 public:
912  size_t nPlaceholders() const;
913 
922  bool placeholderExists(rose_addr_t startVa) const;
923 
934  ControlFlowGraph::VertexIterator findPlaceholder(rose_addr_t startVa);
935  ControlFlowGraph::ConstVertexIterator findPlaceholder(rose_addr_t startVa) const;
954  ControlFlowGraph::VertexIterator insertPlaceholder(rose_addr_t startVa);
955 
969  BasicBlockPtr erasePlaceholder(const ControlFlowGraph::ConstVertexIterator &placeholder) /*final*/;
970  BasicBlockPtr erasePlaceholder(rose_addr_t startVa) /*final*/;
975  //
978  // Partitioner basic block operations
979  //
982 public:
996  bool basicBlockSemanticsAutoDrop() const;
997  void basicBlockSemanticsAutoDrop(bool);
1008  void basicBlockDropSemantics() const;
1009 
1018  size_t nBasicBlocks() const;
1019 
1027  std::vector<BasicBlockPtr> basicBlocks() const;
1028 
1050  BasicBlockPtr basicBlockExists(rose_addr_t startVa) const;
1051  BasicBlockPtr basicBlockExists(const BasicBlockPtr&) const;
1063  std::vector<BasicBlockPtr> basicBlocksOverlapping(const AddressInterval&) const;
1064 
1075  std::vector<BasicBlockPtr> basicBlocksSpanning(const AddressInterval&) const;
1076 
1086  std::vector<BasicBlockPtr> basicBlocksContainedIn(const AddressInterval&) const;
1087 
1094  BasicBlockPtr basicBlockContainingInstruction(rose_addr_t insnVa) const;
1095 
1105  AddressIntervalSet basicBlockInstructionExtent(const BasicBlockPtr&) const;
1106 
1112  AddressIntervalSet basicBlockDataExtent(const BasicBlockPtr&) const;
1113 
1138  BasicBlockPtr detachBasicBlock(rose_addr_t startVa);
1139  BasicBlockPtr detachBasicBlock(const BasicBlockPtr &basicBlock);
1140  BasicBlockPtr detachBasicBlock(const ControlFlowGraph::ConstVertexIterator &placeholder);
1154  ControlFlowGraph::VertexIterator truncateBasicBlock(const ControlFlowGraph::ConstVertexIterator &basicBlock,
1155  SgAsmInstruction *insn);
1156 
1189  void attachBasicBlock(const BasicBlockPtr&);
1190  void attachBasicBlock(const ControlFlowGraph::ConstVertexIterator &placeholder, const BasicBlockPtr&);
1278  BasicBlockPtr discoverBasicBlock(rose_addr_t startVa) const;
1279  BasicBlockPtr discoverBasicBlock(const ControlFlowGraph::ConstVertexIterator &placeholder) const;
1296  BasicBlockSuccessors basicBlockSuccessors(const BasicBlockPtr&, Precision::Level precision = Precision::HIGH) const;
1297 
1306  std::vector<rose_addr_t> basicBlockConcreteSuccessors(const BasicBlockPtr&, bool *isComplete=NULL) const;
1307 
1326  std::set<rose_addr_t> basicBlockGhostSuccessors(const BasicBlockPtr&) const;
1327 
1337  bool basicBlockIsFunctionCall(const BasicBlockPtr&, Precision::Level precision = Precision::HIGH) const;
1338 
1349  bool basicBlockIsFunctionReturn(const BasicBlockPtr&) const;
1350 
1355  bool basicBlockPopsStack(const BasicBlockPtr&) const;
1356 
1398  basicBlockStackDeltaIn(const BasicBlockPtr&, const FunctionPtr &function) const;
1399 
1401  basicBlockStackDeltaOut(const BasicBlockPtr&, const FunctionPtr &function) const;
1412  void forgetStackDeltas() const;
1413  void forgetStackDeltas(const FunctionPtr&) const;
1425  size_t stackDeltaInterproceduralLimit() const;
1426  void stackDeltaInterproceduralLimit(size_t);
1479  Sawyer::Optional<bool> basicBlockOptionalMayReturn(const BasicBlockPtr&) const;
1480  Sawyer::Optional<bool> basicBlockOptionalMayReturn(const ControlFlowGraph::ConstVertexIterator&) const;
1489  void basicBlockMayReturnReset() const;
1490 
1491 private:
1492  // Per-vertex data used during may-return analysis
1493  struct MayReturnVertexInfo {
1494  enum State {INIT, CALCULATING, FINISHED};
1495  State state; // current state of vertex
1496  bool processedCallees; // have we processed BBs this vertex calls?
1497  boost::logic::tribool anyCalleesReturn; // do any of those called BBs have a true may-return value?
1498  boost::logic::tribool result; // final result (eventually cached in BB)
1499  MayReturnVertexInfo(): state(INIT), processedCallees(false), anyCalleesReturn(false), result(boost::indeterminate) {}
1500  };
1501 
1502  // Is edge significant for analysis? See .C file for full documentation.
1503  bool mayReturnIsSignificantEdge(const ControlFlowGraph::ConstEdgeIterator &edge,
1504  std::vector<MayReturnVertexInfo> &vertexInfo) const;
1505 
1506  // Determine (and cache in vertexInfo) whether any callees return.
1507  boost::logic::tribool mayReturnDoesCalleeReturn(const ControlFlowGraph::ConstVertexIterator &vertex,
1508  std::vector<MayReturnVertexInfo> &vertexInfo) const;
1509 
1510  // Maximum may-return result from significant successors including phantom call-return edge.
1511  boost::logic::tribool mayReturnDoesSuccessorReturn(const ControlFlowGraph::ConstVertexIterator &vertex,
1512  std::vector<MayReturnVertexInfo> &vertexInfo) const;
1513 
1514  // The guts of the may-return analysis
1515  Sawyer::Optional<bool> basicBlockOptionalMayReturn(const ControlFlowGraph::ConstVertexIterator &start,
1516  std::vector<MayReturnVertexInfo> &vertexInfo) const;
1517 
1518 
1519 
1522  //
1523  // Partitioner data block operations
1524  //
1527 public:
1533  size_t nDataBlocks() const;
1534 
1541  DataBlockPtr dataBlockExists(const DataBlockPtr&) const;
1542 
1551  DataBlockPtr findBestDataBlock(const AddressInterval&) const;
1552 
1564  DataBlockPtr attachDataBlock(const DataBlockPtr&);
1565 
1572  void detachDataBlock(const DataBlockPtr&);
1573 
1583  DataBlockPtr attachDataBlockToFunction(const DataBlockPtr&, const FunctionPtr&);
1584 
1597  DataBlockPtr attachDataBlockToBasicBlock(const DataBlockPtr&, const BasicBlockPtr&);
1598 
1608  std::vector<DataBlockPtr> dataBlocksOverlapping(const AddressInterval&) const;
1609 
1619  std::vector<DataBlockPtr> dataBlocksSpanning(const AddressInterval&) const;
1620 
1630  std::vector<DataBlockPtr> dataBlocksContainedIn(const AddressInterval&) const;
1631 
1638  AddressInterval dataBlockExtent(const DataBlockPtr&) const;
1639 
1645  std::vector<DataBlockPtr> dataBlocks() const;
1646 
1647 
1648 
1651  //
1652  // Partitioner function operations
1653  //
1656 public:
1662  size_t nFunctions() const;
1663 
1682  FunctionPtr functionExists(rose_addr_t entryVa) const;
1683  FunctionPtr functionExists(const BasicBlockPtr &entryBlock) const;
1684  FunctionPtr functionExists(const FunctionPtr &function) const;
1692  std::vector<FunctionPtr> functions() const;
1693 
1703  std::vector<FunctionPtr> functionsOverlapping(const AddressInterval&) const;
1704 
1715  std::vector<FunctionPtr> functionsSpanning(const AddressInterval&) const;
1716 
1726  std::vector<FunctionPtr> functionsContainedIn(const AddressInterval&) const;
1727 
1744  AddressIntervalSet functionExtent(const FunctionPtr&) const;
1745  void functionExtent(const FunctionPtr &function, AddressIntervalSet &retval /*in,out*/) const;
1746  AddressIntervalSet functionBasicBlockExtent(const FunctionPtr &function) const;
1747  void functionBasicBlockExtent(const FunctionPtr &function, AddressIntervalSet &retval /*in,out*/) const;
1748  AddressIntervalSet functionDataBlockExtent(const FunctionPtr &function) const;
1749  void functionDataBlockExtent(const FunctionPtr &function, AddressIntervalSet &retval /*in,out*/) const;
1771  size_t attachFunction(const FunctionPtr&);
1772  size_t attachFunctions(const Functions&);
1788  FunctionPtr attachOrMergeFunction(const FunctionPtr&);
1789 
1806  size_t attachFunctionBasicBlocks(const Functions&);
1807  size_t attachFunctionBasicBlocks(const FunctionPtr&);
1823  void detachFunction(const FunctionPtr&);
1824 
1859  std::vector<FunctionPtr>
1860  functionsOwningBasicBlock(const ControlFlowGraph::Vertex&, bool doSort = true) const;
1861 
1862  std::vector<FunctionPtr>
1863  functionsOwningBasicBlock(const ControlFlowGraph::ConstVertexIterator&, bool doSort = true) const;
1864 
1865  std::vector<FunctionPtr>
1866  functionsOwningBasicBlock(rose_addr_t bblockVa, bool doSort = true) const;
1867 
1868  std::vector<FunctionPtr>
1869  functionsOwningBasicBlock(const BasicBlockPtr&, bool doSort = true) const;
1870 
1871  template<class Container> // container can hold any type accepted by functionsOwningBasicBlock
1872  std::vector<FunctionPtr>
1873  functionsOwningBasicBlocks(const Container &bblocks) const {
1874  std::vector<FunctionPtr> retval;
1875  for (const typename Container::value_type& bblock: bblocks) {
1876  for (const FunctionPtr &function: functionsOwningBasicBlock(bblock, false))
1877  insertUnique(retval, function, sortFunctionsByAddress);
1878  }
1879  return retval;
1880  }
1892  std::vector<FunctionPtr> discoverCalledFunctions() const;
1893 
1905  std::vector<FunctionPtr> discoverFunctionEntryVertices() const;
1906 
1916  Sawyer::Optional<Thunk> functionIsThunk(const FunctionPtr&) const;
1917 
1928  void discoverFunctionBasicBlocks(const FunctionPtr &function) const;
1929 
1936  std::set<rose_addr_t> functionGhostSuccessors(const FunctionPtr&) const;
1937 
1945  FunctionCallGraph functionCallGraph(AllowParallelEdges::Type allowParallelEdges) const;
1946 
1966  InstructionSemantics::BaseSemantics::SValuePtr functionStackDelta(const FunctionPtr &function) const;
1967 
1971  void allFunctionStackDelta() const;
1972 
1979  Sawyer::Optional<bool> functionOptionalMayReturn(const FunctionPtr &function) const;
1980 
1984  void allFunctionMayReturn() const;
1985 
2014  const CallingConvention::Analysis& functionCallingConvention(const FunctionPtr&) const;
2015  const CallingConvention::Analysis& functionCallingConvention(const FunctionPtr&,
2016  const CallingConvention::Definition::Ptr &dflt) const;
2033  void allFunctionCallingConvention() const;
2034  void allFunctionCallingConvention(const CallingConvention::Definition::Ptr &dflt) const;
2035 
2065  CallingConvention::Dictionary functionCallingConventionDefinitions(const FunctionPtr&) const;
2066  CallingConvention::Dictionary functionCallingConventionDefinitions(const FunctionPtr&,
2067  const CallingConvention::Definition::Ptr&) const;
2084  void allFunctionCallingConventionDefinition() const;
2085  void allFunctionCallingConventionDefinition(const CallingConvention::Definition::Ptr&) const;
2096  void fixInterFunctionEdges();
2097  void fixInterFunctionEdge(const ControlFlowGraph::ConstEdgeIterator&);
2117  bool functionIsNoop(const FunctionPtr&) const;
2118 
2124  void allFunctionIsNoop() const;
2125 
2133  void forgetFunctionIsNoop() const;
2134  void forgetFunctionIsNoop(const FunctionPtr&) const;
2141  std::set<rose_addr_t> functionDataFlowConstants(const FunctionPtr&) const;
2142 
2143 
2144 
2147  //
2148  // Callbacks
2149  //
2152 public:
2170  CfgAdjustmentCallbacks& cfgAdjustmentCallbacks();
2171  const CfgAdjustmentCallbacks& cfgAdjustmentCallbacks() const;
2182  BasicBlockCallbacks& basicBlockCallbacks();
2183  const BasicBlockCallbacks& basicBlockCallbacks() const;
2186 public:
2194  FunctionPrologueMatchers& functionPrologueMatchers();
2195  const FunctionPrologueMatchers& functionPrologueMatchers() const;
2222  std::vector<FunctionPtr> nextFunctionPrologue(rose_addr_t startVa);
2223  std::vector<FunctionPtr> nextFunctionPrologue(rose_addr_t startVa, rose_addr_t &lastSearchedVa /*out*/);
2226 public:
2232  FunctionPaddingMatchers& functionPaddingMatchers();
2233  const FunctionPaddingMatchers& functionPaddingMatchers() const;
2243  DataBlockPtr matchFunctionPadding(const FunctionPtr&);
2244 
2245 
2246 
2249  //
2250  // Partitioner miscellaneous
2251  //
2254 public:
2266  void dumpCfg(std::ostream&, const std::string &prefix="", bool showBlocks=true, bool computeProperties=true) const;
2267 
2281  void cfgGraphViz(std::ostream&, const AddressInterval &restrict = AddressInterval::whole(), bool showNeighbors=true) const;
2282 
2288  static std::string vertexName(const ControlFlowGraph::Vertex&);
2289  std::string vertexName(const ControlFlowGraph::ConstVertexIterator&) const;
2295  static std::string vertexNameEnd(const ControlFlowGraph::Vertex&);
2296 
2302  static std::string edgeNameSrc(const ControlFlowGraph::Edge&);
2303  std::string edgeNameSrc(const ControlFlowGraph::ConstEdgeIterator&) const;
2311  static std::string edgeNameDst(const ControlFlowGraph::Edge&);
2312  std::string edgeNameDst(const ControlFlowGraph::ConstEdgeIterator&) const;
2320  static std::string edgeName(const ControlFlowGraph::Edge&);
2321  std::string edgeName(const ControlFlowGraph::ConstEdgeIterator&) const;
2327  static std::string basicBlockName(const BasicBlockPtr&);
2328 
2332  static std::string dataBlockName(const DataBlockPtr&);
2333 
2337  static std::string functionName(const FunctionPtr&);
2338 
2343  void expandIndeterminateCalls();
2344 
2362  Progress::Ptr progress() const;
2363  void progress(const Progress::Ptr&);
2370  void updateProgress(const std::string &phase, double completion) const;
2371 
2373  void showStatistics() const;
2374 
2375  // Checks consistency of internal data structures when debugging is enable (when NDEBUG is not defined).
2376  void checkConsistency() const;
2377 
2384 
2388  Sawyer::Optional<rose_addr_t> elfGotVa() const;
2389 
2390 
2391 
2394  //
2395  // Settings
2396  //
2399 public:
2400 
2408  const BasePartitionerSettings& settings() const;
2409  void settings(const BasePartitionerSettings&);
2420  void enableSymbolicSemantics(bool = true);
2421  void disableSymbolicSemantics();
2422  bool usingSymbolicSemantics() const;
2446  void autoAddCallReturnEdges(bool);
2447  bool autoAddCallReturnEdges() const;
2464  void assumeFunctionsReturn(bool);
2465  bool assumeFunctionsReturn() const;
2477  void addressName(rose_addr_t, const std::string&);
2478  const std::string& addressName(rose_addr_t) const;
2479  const AddressNameMap& addressNames() const;
2487  const SourceLocations& sourceLocations() const;
2488  SourceLocations& sourceLocations();
2489  void sourceLocations(const SourceLocations&);
2499  bool checkingCallBranch() const;
2500  void checkingCallBranch(bool);
2505  //
2508  // Instruction semantics
2509  //
2512 public:
2522  SemanticMemoryParadigm semanticMemoryParadigm() const;
2523  void semanticMemoryParadigm(SemanticMemoryParadigm);
2532  SmtSolverPtr smtSolver() const;
2533 
2556  newDispatcher(const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&) const;
2557 
2558 
2559 
2562  //
2563  // Python API support functions
2564  //
2567 #ifdef ROSE_ENABLE_PYTHON_API
2568  void pythonUnparse() const;
2569 #endif
2570 
2571 
2572 
2575  //
2576  // Partitioner internal utilities
2577  //
2580 private:
2581  void init(const Disassembler::BasePtr&, const MemoryMap::Ptr&);
2582  void init(const Partitioner&);
2583  void updateCfgProgress();
2584 
2585 private:
2586  // Convert a CFG vertex iterator from one partitioner to another. This is called during copy construction when the source
2587  // and destination CFGs are identical.
2588  ControlFlowGraph::VertexIterator convertFrom(const Partitioner &other,
2589  ControlFlowGraph::ConstVertexIterator otherIter);
2590 
2591  // Adjusts edges for a placeholder vertex. This method erases all outgoing edges for the specified placeholder vertex and
2592  // then inserts a single edge from the placeholder to the special "undiscovered" vertex. */
2593  ControlFlowGraph::EdgeIterator adjustPlaceholderEdges(const ControlFlowGraph::VertexIterator &placeholder);
2594 
2595  // Adjusts edges for a non-existing basic block. This method erases all outgoing edges for the specified vertex and
2596  // then inserts a single edge from the vertex to the special "non-existing" vertex. */
2597  ControlFlowGraph::EdgeIterator adjustNonexistingEdges(const ControlFlowGraph::VertexIterator &vertex);
2598 
2599  // Implementation for the discoverBasicBlock methods. The startVa must not be the address of an existing placeholder.
2600  BasicBlockPtr discoverBasicBlockInternal(rose_addr_t startVa) const;
2601 
2602  // This method is called whenever a new placeholder is inserted into the CFG or a new basic block is attached to the
2603  // CFG/AUM. The call happens immediately after the CFG/AUM are updated.
2604  void bblockAttached(const ControlFlowGraph::VertexIterator &newVertex);
2605 
2606  // This method is called whenever a basic block is detached from the CFG/AUM or when a placeholder is erased from the CFG.
2607  // The call happens immediately after the CFG/AUM are updated.
2608  void bblockDetached(rose_addr_t startVa, const BasicBlockPtr &removedBlock);
2609 
2610  // Rebuild the vertexIndex_ and other cache-like data members from the control flow graph
2611  void rebuildVertexIndices();
2612 };
2613 
2614 } // namespace
2615 } // namespace
2616 } // namespace
2617 
2618 // Class versions must be at global scope
2619 BOOST_CLASS_VERSION(Rose::BinaryAnalysis::Partitioner2::Partitioner, 3);
2620 
2621 #endif
2622 #endif
Represents information about a thunk.
Definition: Partitioner.h:321
Contiguous region of a file.
Sawyer::Callbacks< BasicBlockCallbackPtr > BasicBlockCallbacks
See basicBlockCallbacks.
Definition: Partitioner.h:316
Represents the file header of an ELF binary container.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Base class for machine instructions.
std::vector< FunctionPrologueMatcherPtr > FunctionPrologueMatchers
See functionPrologueMatchers.
Definition: Partitioner.h:317
Bidirectional mapping between addresses and source locations.
Sawyer::Container::Graph< CfgVertex, CfgEdge > ControlFlowGraph
Control flow graph.
Main namespace for the ROSE library.
Sawyer::Container::Map< rose_addr_t, std::string > AddressNameMap
Map address to name.
Definition: Partitioner.h:329
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
Sawyer::SharedPointer< Function > FunctionPtr
Shared-ownership pointer for Function.
Sawyer::SharedPointer< BasicBlock > BasicBlockPtr
Shared-ownersip pointer for BasicBlock.
MemoryMapPtr Ptr
Reference counting pointer.
Definition: MemoryMap.h:115
BasicBlockPtr bblock
The one and only basic block for the thunk.
Definition: Partitioner.h:322
Sawyer::SharedPointer< Partitioner > PartitionerPtr
Shared-ownership pointer for Partitioner.
std::vector< Definition::Ptr > Dictionary
A ordered collection of calling convention definitions.
rose_addr_t target
The one and only successor for the basic block.
Definition: Partitioner.h:323
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:9846
std::vector< FunctionPtr > functionsOwningBasicBlocks(const Container &bblocks) const
Finds functions that own the specified basic block.
Definition: Partitioner.h:1873
static Interval whole()
Construct an interval that covers the entire domain.
Definition: Interval.h:180
Creates SharedPointer from this.
Sawyer::SharedPointer< const Partitioner > PartitionerConstPtr
Shared-ownership pointer for Partitioner.
std::vector< BasicBlockSuccessor > BasicBlockSuccessors
All successors in no particular order.
std::vector< FunctionPaddingMatcherPtr > FunctionPaddingMatchers
See functionPaddingMatchers.
Definition: Partitioner.h:318
Sawyer::Container::Map< Reference, ReferenceSet > CrossReferences
Cross references.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
Base class for reference counted objects.
Definition: SharedObject.h:64
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
Format
Format of the state file.
Definition: SerialIo.h:118
API and storage for attributes.
Definition: Attribute.h:215
Sawyer::Container::Map< rose_addr_t, FunctionPtr > Functions
Mapping from address to function.
Sawyer::SharedPointer< DataBlock > DataBlockPtr
Shared-ownership pointer for DataBlock.
Sawyer::SharedPointer< Base > BasePtr
Reference counted pointer for disassemblers.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:293
Binary state files are smaller and faster than the other formats, but are not portable across archite...
Definition: SerialIo.h:119
Represents an interpretation of a binary container.
Sawyer::Callbacks< CfgAdjustmentCallback::Ptr > CfgAdjustmentCallbacks
See cfgAdjustmentCallbacks.
Definition: Partitioner.h:315
State
Decoder state.
Definition: String.h:198