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>
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>
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>
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>
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>
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>
52 namespace Rose {
namespace BinaryAnalysis {
namespace InstructionSemantics2 = InstructionSemantics; }}
66 #if __cplusplus >= 201103L
67 #define ROSE_PARTITIONER_MOVE
68 #elif defined(__GNUC__)
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
77 namespace BinaryAnalysis {
78 namespace Partitioner2 {
295 #ifdef ROSE_PARTITIONER_MOVE
349 bool autoAddCallReturnEdges_;
350 bool assumeFunctionsReturn_;
351 size_t stackDeltaInterproceduralLimit_;
352 AddressNameMap addressNames_;
360 CfgAdjustmentCallbacks cfgAdjustmentCallbacks_;
361 BasicBlockCallbacks basicBlockCallbacks_;
362 FunctionPrologueMatchers functionPrologueMatchers_;
363 FunctionPaddingMatchers functionPaddingMatchers_;
366 ControlFlowGraph::VertexIterator undiscoveredVertex_;
367 ControlFlowGraph::VertexIterator indeterminateVertex_;
368 ControlFlowGraph::VertexIterator nonexistingVertex_;
369 static const size_t nSpecialVertices = 3;
375 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
377 mutable size_t cfgProgressTotal_;
386 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
388 friend class boost::serialization::access;
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>();
397 #ifdef ROSE_ENABLE_ASM_AARCH32
398 s.template register_type<InstructionSemantics::DispatcherAarch32>();
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_);
414 s & BOOST_SERIALIZATION_NVP(instructionProvider_);
415 s & BOOST_SERIALIZATION_NVP(memoryMap_);
416 s & BOOST_SERIALIZATION_NVP(cfg_);
418 s & BOOST_SERIALIZATION_NVP(aum_);
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_);
426 s & BOOST_SERIALIZATION_NVP(sourceLocations_);
427 s & BOOST_SERIALIZATION_NVP(semanticMemoryParadigm_);
437 s & BOOST_SERIALIZATION_NVP(elfGotVa_);
443 void save(S &s,
const unsigned version)
const {
444 const_cast<Partitioner*
>(
this)->serializeCommon(s, version);
446 saveAst(s, interpretation_);
450 void load(S &s,
const unsigned version) {
451 serializeCommon(s, version);
453 SgNode *node = restoreAst(s);
454 interpretation_ = isSgAsmInterpretation(node);
455 ASSERT_require(!node || interpretation_);
457 rebuildVertexIndices();
460 BOOST_SERIALIZATION_SPLIT_MEMBER();
484 static Ptr instance();
499 void saveAsRbaFile(
const boost::filesystem::path &name,
SerialIo::Format fmt)
const;
501 #ifdef ROSE_PARTITIONER_MOVE
503 Partitioner(BOOST_RV_REF(Partitioner));
506 Partitioner& operator=(BOOST_RV_REF(Partitioner));
509 Partitioner(
const Partitioner&);
510 Partitioner& operator=(
const Partitioner&);
519 bool isDefaultConstructed()
const;
531 Configuration& configuration();
532 const Configuration& configuration()
const;
540 InstructionProvider& instructionProvider();
541 const InstructionProvider& instructionProvider()
const;
563 bool addressIsExecutable(rose_addr_t)
const;
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;
606 void configureInsnPlainUnparser(
const Unparser::BasePtr&)
const;
620 void unparse(std::ostream&,
const FunctionPtr&)
const;
621 void unparse(std::ostream&)
const;
642 size_t nBytes()
const;
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;
696 const AddressUsageMap& aum()
const;
705 std::vector<AddressUser> users(rose_addr_t)
const;
714 std::set<rose_addr_t> ghostSuccessors()
const;
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,
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,
810 size_t nInstructions()
const;
821 AddressUser instructionExists(rose_addr_t startVa)
const;
831 ControlFlowGraph::ConstVertexIterator instructionVertex(rose_addr_t insnVa)
const;
841 std::vector<SgAsmInstruction*> instructionsOverlapping(
const AddressInterval&)
const;
851 std::vector<SgAsmInstruction*> instructionsSpanning(
const AddressInterval&)
const;
862 std::vector<SgAsmInstruction*> instructionsContainedIn(
const AddressInterval&)
const;
912 size_t nPlaceholders()
const;
922 bool placeholderExists(rose_addr_t startVa)
const;
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);
969 BasicBlockPtr erasePlaceholder(
const ControlFlowGraph::ConstVertexIterator &placeholder) ;
996 bool basicBlockSemanticsAutoDrop()
const;
997 void basicBlockSemanticsAutoDrop(
bool);
1008 void basicBlockDropSemantics()
const;
1018 size_t nBasicBlocks()
const;
1027 std::vector<BasicBlockPtr> basicBlocks()
const;
1063 std::vector<BasicBlockPtr> basicBlocksOverlapping(
const AddressInterval&)
const;
1075 std::vector<BasicBlockPtr> basicBlocksSpanning(
const AddressInterval&)
const;
1086 std::vector<BasicBlockPtr> basicBlocksContainedIn(
const AddressInterval&)
const;
1094 BasicBlockPtr basicBlockContainingInstruction(rose_addr_t insnVa)
const;
1140 BasicBlockPtr detachBasicBlock(
const ControlFlowGraph::ConstVertexIterator &placeholder);
1154 ControlFlowGraph::VertexIterator truncateBasicBlock(
const ControlFlowGraph::ConstVertexIterator &basicBlock,
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;
1306 std::vector<rose_addr_t> basicBlockConcreteSuccessors(
const BasicBlockPtr&,
bool *isComplete=NULL)
const;
1326 std::set<rose_addr_t> basicBlockGhostSuccessors(
const BasicBlockPtr&)
const;
1349 bool basicBlockIsFunctionReturn(
const BasicBlockPtr&)
const;
1412 void forgetStackDeltas()
const;
1425 size_t stackDeltaInterproceduralLimit()
const;
1426 void stackDeltaInterproceduralLimit(
size_t);
1489 void basicBlockMayReturnReset()
const;
1493 struct MayReturnVertexInfo {
1494 enum State {INIT, CALCULATING, FINISHED};
1496 bool processedCallees;
1497 boost::logic::tribool anyCalleesReturn;
1498 boost::logic::tribool result;
1499 MayReturnVertexInfo(): state(INIT), processedCallees(false), anyCalleesReturn(false), result(
boost::indeterminate) {}
1503 bool mayReturnIsSignificantEdge(
const ControlFlowGraph::ConstEdgeIterator &edge,
1504 std::vector<MayReturnVertexInfo> &vertexInfo)
const;
1507 boost::logic::tribool mayReturnDoesCalleeReturn(
const ControlFlowGraph::ConstVertexIterator &vertex,
1508 std::vector<MayReturnVertexInfo> &vertexInfo)
const;
1511 boost::logic::tribool mayReturnDoesSuccessorReturn(
const ControlFlowGraph::ConstVertexIterator &vertex,
1512 std::vector<MayReturnVertexInfo> &vertexInfo)
const;
1516 std::vector<MayReturnVertexInfo> &vertexInfo)
const;
1533 size_t nDataBlocks()
const;
1608 std::vector<DataBlockPtr> dataBlocksOverlapping(
const AddressInterval&)
const;
1619 std::vector<DataBlockPtr> dataBlocksSpanning(
const AddressInterval&)
const;
1630 std::vector<DataBlockPtr> dataBlocksContainedIn(
const AddressInterval&)
const;
1645 std::vector<DataBlockPtr> dataBlocks()
const;
1662 size_t nFunctions()
const;
1682 FunctionPtr functionExists(rose_addr_t entryVa)
const;
1692 std::vector<FunctionPtr> functions()
const;
1703 std::vector<FunctionPtr> functionsOverlapping(
const AddressInterval&)
const;
1715 std::vector<FunctionPtr> functionsSpanning(
const AddressInterval&)
const;
1726 std::vector<FunctionPtr> functionsContainedIn(
const AddressInterval&)
const;
1772 size_t attachFunctions(
const Functions&);
1806 size_t attachFunctionBasicBlocks(
const Functions&);
1807 size_t attachFunctionBasicBlocks(
const FunctionPtr&);
1859 std::vector<FunctionPtr>
1860 functionsOwningBasicBlock(
const ControlFlowGraph::Vertex&,
bool doSort =
true)
const;
1862 std::vector<FunctionPtr>
1863 functionsOwningBasicBlock(
const ControlFlowGraph::ConstVertexIterator&,
bool doSort =
true)
const;
1865 std::vector<FunctionPtr>
1866 functionsOwningBasicBlock(rose_addr_t bblockVa,
bool doSort =
true)
const;
1868 std::vector<FunctionPtr>
1869 functionsOwningBasicBlock(
const BasicBlockPtr&,
bool doSort =
true)
const;
1871 template<
class Container>
1872 std::vector<FunctionPtr>
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);
1892 std::vector<FunctionPtr> discoverCalledFunctions()
const;
1905 std::vector<FunctionPtr> discoverFunctionEntryVertices()
const;
1928 void discoverFunctionBasicBlocks(
const FunctionPtr &
function)
const;
1936 std::set<rose_addr_t> functionGhostSuccessors(
const FunctionPtr&)
const;
1971 void allFunctionStackDelta()
const;
1984 void allFunctionMayReturn()
const;
2033 void allFunctionCallingConvention()
const;
2084 void allFunctionCallingConventionDefinition()
const;
2096 void fixInterFunctionEdges();
2097 void fixInterFunctionEdge(
const ControlFlowGraph::ConstEdgeIterator&);
2124 void allFunctionIsNoop()
const;
2133 void forgetFunctionIsNoop()
const;
2134 void forgetFunctionIsNoop(
const FunctionPtr&)
const;
2141 std::set<rose_addr_t> functionDataFlowConstants(
const FunctionPtr&)
const;
2170 CfgAdjustmentCallbacks& cfgAdjustmentCallbacks();
2171 const CfgAdjustmentCallbacks& cfgAdjustmentCallbacks()
const;
2182 BasicBlockCallbacks& basicBlockCallbacks();
2183 const BasicBlockCallbacks& basicBlockCallbacks()
const;
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 );
2232 FunctionPaddingMatchers& functionPaddingMatchers();
2233 const FunctionPaddingMatchers& functionPaddingMatchers()
const;
2266 void dumpCfg(std::ostream&,
const std::string &prefix=
"",
bool showBlocks=
true,
bool computeProperties=
true)
const;
2288 static std::string vertexName(
const ControlFlowGraph::Vertex&);
2289 std::string vertexName(
const ControlFlowGraph::ConstVertexIterator&)
const;
2295 static std::string vertexNameEnd(
const ControlFlowGraph::Vertex&);
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;
2337 static std::string functionName(
const FunctionPtr&);
2343 void expandIndeterminateCalls();
2370 void updateProgress(
const std::string &phase,
double completion)
const;
2373 void showStatistics()
const;
2376 void checkConsistency()
const;
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;
2499 bool checkingCallBranch()
const;
2500 void checkingCallBranch(
bool);
2567 #ifdef ROSE_ENABLE_PYTHON_API
2568 void pythonUnparse()
const;
2583 void updateCfgProgress();
2588 ControlFlowGraph::VertexIterator convertFrom(
const Partitioner &other,
2589 ControlFlowGraph::ConstVertexIterator otherIter);
2593 ControlFlowGraph::EdgeIterator adjustPlaceholderEdges(
const ControlFlowGraph::VertexIterator &placeholder);
2597 ControlFlowGraph::EdgeIterator adjustNonexistingEdges(
const ControlFlowGraph::VertexIterator &vertex);
2600 BasicBlockPtr discoverBasicBlockInternal(rose_addr_t startVa)
const;
2604 void bblockAttached(
const ControlFlowGraph::VertexIterator &newVertex);
2608 void bblockDetached(rose_addr_t startVa,
const BasicBlockPtr &removedBlock);
2611 void rebuildVertexIndices();
Represents information about a thunk.
Contiguous region of a file.
Sawyer::Callbacks< BasicBlockCallbackPtr > BasicBlockCallbacks
See basicBlockCallbacks.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Base class for machine instructions.
std::vector< FunctionPrologueMatcherPtr > FunctionPrologueMatchers
See functionPrologueMatchers.
Bidirectional mapping between addresses and source locations.
Settings that directly control a partitioner.
Function calling convention.
High precision, but slow.
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.
Function call information.
Reference-counting intrusive smart pointer.
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.
BasicBlockPtr bblock
The one and only basic block for the thunk.
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.
This class represents the base class for all IR nodes within Sage III.
std::vector< FunctionPtr > functionsOwningBasicBlocks(const Container &bblocks) const
Finds functions that own the specified basic block.
static Interval whole()
Construct an interval that covers the entire domain.
Creates SharedPointer from this.
Sawyer::SharedPointer< const Partitioner > PartitionerConstPtr
Shared-ownership pointer for Partitioner.
SemanticMemoryParadigm
Organization of semantic memory.
std::vector< BasicBlockSuccessor > BasicBlockSuccessors
All successors in no particular order.
std::vector< FunctionPaddingMatcherPtr > FunctionPaddingMatchers
See functionPaddingMatchers.
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.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
Format
Format of the state file.
API and storage for attributes.
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.
Binary state files are smaller and faster than the other formats, but are not portable across archite...
Represents an interpretation of a binary container.
Sawyer::Callbacks< CfgAdjustmentCallback::Ptr > CfgAdjustmentCallbacks
See cfgAdjustmentCallbacks.
Holds configuration information.