From 87299dec03db4cad748244fcfbd4b72c3847cff6 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Thu, 31 Jan 2019 10:31:23 -0500 Subject: [PATCH] added irdb-cfg --- include/inc-cfg/BasicBlock.hpp | 30 ++++++------ include/inc-cfg/CFG.hpp | 80 +++++++++++--------------------- include/inc-cfg/callgraph.hpp | 56 +++++++++++----------- include/inc-cfg/criticaledge.hpp | 49 ++++++++----------- include/inc-cfg/domgraph.hpp | 75 +++++++++++------------------- include/irdb-cfg | 2 +- 6 files changed, 116 insertions(+), 176 deletions(-) diff --git a/include/inc-cfg/BasicBlock.hpp b/include/inc-cfg/BasicBlock.hpp index c04e483..8d24374 100644 --- a/include/inc-cfg/BasicBlock.hpp +++ b/include/inc-cfg/BasicBlock.hpp @@ -20,14 +20,14 @@ #include <ostream> #include <set> +#include <vector> namespace IRDB_SDK { using namespace std; - class BasicBlock_t; - using BasicBlockSet_t = set<BasicBlock_t*>; + using InstructionVector_t = vector<Instruction_t*>; class BasicBlock_t { @@ -35,24 +35,20 @@ namespace IRDB_SDK BasicBlock_t() {} BasicBlock_t(const BasicBlock_t& copy) = delete; public: + virtual ~BasicBlock_t() {} - bool getIsExitBlock() const = 0; - const InstructionVector_t& getInstructions() const = 0; - const BasicBlockSet_t& getPredecessors() const = 0; - const BasicBlockSet_t& getSuccessors() const = 0; - const BasicBlockSet_t& getIndirectTargets() const = 0; - const BasicBlock_t* getFallthrough() const = 0; - const BasicBlock_t* getTarget() const = 0; - + virtual bool getIsExitBlock() const = 0; + virtual const InstructionVector_t& getInstructions() const = 0; + virtual const BasicBlockSet_t& getPredecessors() const = 0; + virtual const BasicBlockSet_t& getSuccessors() const = 0; + virtual const BasicBlockSet_t& getIndirectTargets() const = 0; + virtual bool endsInBranch() const = 0; + virtual bool endsInIndirectBranch() const = 0; + virtual bool endsInConditionalBranch() const = 0; + virtual Instruction_t* getBranchInstruction() const = 0; - bool endsInBranch() = 0; - bool endsInIndirectBranch() = 0; - bool endsInConditionalBranch() = 0; - Instruction_t* getBranchInstruction() = 0; - - void dump(ostream &os=std::cout) = 0 ; + virtual void dump(ostream &os=cout) const = 0 ; }; ostream& operator<<(ostream& os, const BasicBlock_t& block); - } diff --git a/include/inc-cfg/CFG.hpp b/include/inc-cfg/CFG.hpp index 8bf1d0b..ad8fcce 100644 --- a/include/inc-cfg/CFG.hpp +++ b/include/inc-cfg/CFG.hpp @@ -1,56 +1,28 @@ -/* - * Copyright (c) 2014 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ -enum CFG_EdgeTypeEnum { CFG_FallthroughEdge, CFG_TargetEdge, CFG_IndirectEdge }; -typedef std::set<CFG_EdgeTypeEnum> CFG_EdgeType; - -class ControlFlowGraph_t +namespace IRDB_SDK { - public: - ControlFlowGraph_t(Function_t* func); - BasicBlock_t* GetEntry() const { return entry; } - Function_t* GetFunction() const { return function; } - BasicBlockSet_t& GetBlocks() { return blocks; } - const BasicBlockSet_t& GetBlocks() const { return blocks; } - void dump(std::ostream &os=std::cout) const { os<<*this; } - bool HasEdge(BasicBlock_t *p_src, BasicBlock_t *p_tgt) const; - CFG_EdgeType GetEdgeType(const BasicBlock_t *p_src, const BasicBlock_t *p_tgt) const; - - private: - // methods - void Build(Function_t *func); - void alloc_blocks(const InstructionSet_t &starts, map<Instruction_t*,BasicBlock_t*>& insn2block_map); - void build_blocks(const map<Instruction_t*,BasicBlock_t*>& insn2block_map); - void find_unblocked_instructions(InstructionSet_t &starts, Function_t* func); - - // data - BasicBlockSet_t blocks; - BasicBlock_t* entry; - Function_t* function; - - /* friends */ - public: - friend std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg); -}; - - -std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg); - - + using namespace std; + enum CFGEdgeTypeEnum { cetFallthroughEdge, cetTargetEdge, cetIndirectEdge }; + using CFGEdgeType_t = set<CFGEdgeTypeEnum>; + + class ControlFlowGraph_t + { + protected: + ControlFlowGraph_t() { } + ControlFlowGraph_t(const ControlFlowGraph_t& copy) = delete; + public: + + virtual BasicBlock_t* getEntry() const = 0 ; + virtual Function_t* getFunction() const = 0 ; + virtual const BasicBlockSet_t& getBlocks() const = 0 ; + virtual bool hasEdge(BasicBlock_t *p_src, BasicBlock_t *p_tgt) const = 0 ; + virtual CFGEdgeType_t getEdgeType(const BasicBlock_t *p_src, const BasicBlock_t *p_tgt) const = 0 ; + virtual void dump(ostream &os=cout) const = 0 ; + + // factories + static unique_ptr<ControlFlowGraph_t> factory(Function_t* func); + + }; + ostream& operator<<(ostream& os, const ControlFlowGraph_t& cfg); + +} diff --git a/include/inc-cfg/callgraph.hpp b/include/inc-cfg/callgraph.hpp index f1c0077..a47a9c0 100644 --- a/include/inc-cfg/callgraph.hpp +++ b/include/inc-cfg/callgraph.hpp @@ -4,6 +4,14 @@ namespace IRDB_SDK { using namespace std; + class CallGraph_t; + class CallGraphNode_t; + + using CallGraphEdge_t = pair<CallGraphNode_t*,CallGraphNode_t*>; + using CallGraphNodeSet_t = set<CallGraphNode_t*>; + using CallSite_t = Instruction_t*; + using CallSiteSet_t = set<CallSite_t>; + class CallGraphNode_t { @@ -13,36 +21,29 @@ namespace IRDB_SDK public: virtual ~CallGraphNode_t() { } - bool isHellnode() const =0; - Function_t* getFunction() const =0; + virtual bool isHellnode() const = 0; + virtual Function_t* getFunction() const = 0; + virtual void dump(ostream& os=cout) const = 0; }; - - - using CallGraphEdge_t = pair<CallGraphNode_t*,CallGraphNode_t*>; - using CallGraphNodeSet_t = set<CallGraphNode_t*>; - using CallSite_t = Instruction_t*; - using CallSiteSet_t = set<CallSite_t>; - - class Callgraph_t + class CallGraph_t { protected: - Callgraph_t() {} - Callgraph_t(const Callgraph_t& copy) = delete; + CallGraph_t() {} + CallGraph_t(const CallGraph_t& copy) = delete; public: - virtual ~Callgraph_t() { } + virtual ~CallGraph_t() { } - virtual void addFile() = 0; - - virtual bool edgeExists(const CallGraphEdge_t& edge) const = 0; + // accessors + virtual void addFile(FileIR_t* const firp) = 0; + virtual bool edgeExists(const CallGraphEdge_t& edge) const = 0; virtual const CallGraphNodeSet_t& getCallersOfNode(CallGraphNode_t* const node) const = 0; - virtual const CallGraphNodeSet_t& getCalleesOfNode(CallGraphNode_t* const node) const = 0; - - virtual const CallGraphNodeSet_t& ancestors, + /* + virtual const CallGraphNodeSet_t& getAncestors ( const Function_t* const fn, @@ -50,22 +51,25 @@ namespace IRDB_SDK ) const = 0; virtual const CallSiteSet_t& getCallSites(CallGraphNode_t* const n1) const = 0; - - virtual void dump(std::ostream& fout) const = 0; - virtual string getNodeName(const CallGraphNode_t* const n1) const = 0; - virtual string getCallsiteDisassembly(const CallSite_t &c) const = 0; + virtual string getNodeName(const CallGraphNode_t* const n1) const = 0; + */ virtual bool isReachable ( CallGraphNode_t* const from, CallGraphNode_t* const to, bool skipHellNode = false - ) const = 0; - + ) const = 0; virtual const CallGraphNode_t& getDefaultHellNode() const = 0; - virtual CallGraphNode_t* findNode(Function_t* const fn) const = 0; + // printer + virtual void dump(ostream& fout) const = 0; + + // factories + static unique_ptr<CallGraph_t> factory(FileIR_t* const firp=nullptr); }; + ostream& operator<<(ostream& os, const CallGraph_t& cg); + ostream& operator<<(ostream& os, const CallGraphNode_t& cgn); } diff --git a/include/inc-cfg/criticaledge.hpp b/include/inc-cfg/criticaledge.hpp index 6126703..9b372be 100644 --- a/include/inc-cfg/criticaledge.hpp +++ b/include/inc-cfg/criticaledge.hpp @@ -1,33 +1,22 @@ -/* - * Copyright (c) 2019 - Zephyr Software LLC - * - * This file may be used and modified for non-commercial purposes as long as - * all copyright, permission, and nonwarranty notices are preserved. - * Redistribution is prohibited without prior written consent from Zephyr - * Software. - * - * Please contact the authors for restrictions applying to commercial use. - * - * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Author: Zephyr Software - * e-mail: jwd@zephyr-software.com - * URL : http://www.zephyr-software.com/ - * - */ -typedef std::tuple<BasicBlock_t*, BasicBlock_t*> BasicBlockEdge_t; -typedef std::set<BasicBlockEdge_t> BasicBlockEdgeSet_t; - -class CriticalEdgeAnalyzer_t +namespace IRDB_SDK { - public: - CriticalEdgeAnalyzer_t(const ControlFlowGraph_t &p_cfg, const bool p_conservative=true); - BasicBlockEdgeSet_t GetAllCriticalEdges() const; + using namespace std; + using BasicBlockEdge_t = tuple<BasicBlock_t*, BasicBlock_t*>; + using BasicBlockEdgeSet_t = set<BasicBlockEdge_t> ; + + class CriticalEdges_t + { + protected: + CriticalEdges_t(){} + CriticalEdges_t(const CriticalEdges_t& copy) = delete; + public: + static unique_ptr<CriticalEdges_t> factory( + const ControlFlowGraph_t &p_cfg, + const bool p_conservative=true + ); + + virtual const BasicBlockEdgeSet_t& getAllCriticalEdges() const = 0; + }; - private: - const ControlFlowGraph_t m_cfg; - const bool m_conservative; -}; +} diff --git a/include/inc-cfg/domgraph.hpp b/include/inc-cfg/domgraph.hpp index 087fc4d..65ccef5 100644 --- a/include/inc-cfg/domgraph.hpp +++ b/include/inc-cfg/domgraph.hpp @@ -1,54 +1,33 @@ - - -typedef std::map<const BasicBlock_t*, BasicBlockSet_t> DominatorMap_t; -typedef std::map<const BasicBlock_t*, BasicBlock_t*> BlockToBlockMap_t; - -class DominatorGraph_t +namespace IRDB_SDK { - public: - DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms=false, bool needs_idoms=false); - - - // get the (post) dominators for a node - BasicBlockSet_t& GetDominators(const BasicBlock_t* node) { return dom_graph[node]; } - BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) { return post_dom_graph[node]; } - - const BasicBlockSet_t& GetDominators(const BasicBlock_t* node) const { return dom_graph.at(node); } - const BasicBlockSet_t& GetPostDominators(const BasicBlock_t* node) const { return post_dom_graph.at(node); } - - bool HasWarnings() const { return warn; } - - - // get the immeidate (post) dominators for a node - const BasicBlock_t* GetImmediateDominator(const BasicBlock_t* node) const - { BlockToBlockMap_t::const_iterator it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; } - const BasicBlock_t* GetImmediatePostDominators(const BasicBlock_t* node) const - { BlockToBlockMap_t::const_iterator it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; } - - private: - - typedef const BasicBlockSet_t& (*pred_func_ptr_t) (const BasicBlock_t* node); - - DominatorMap_t Dom_Comp(const BasicBlockSet_t& N, pred_func_ptr_t pred_func, BasicBlock_t* r); - BlockToBlockMap_t Idom_Comp(const BasicBlockSet_t& N, const DominatorMap_t &Domin, BasicBlock_t* r); - - - DominatorMap_t dom_graph; - BlockToBlockMap_t idom_graph; - - DominatorMap_t post_dom_graph; - BlockToBlockMap_t post_idom_graph; - - const ControlFlowGraph_t& cfg; // a reference to our cfg. - - bool warn; - - friend std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg); + using namespace std; + + using DominatorMap_t = map<const BasicBlock_t*, BasicBlockSet_t>; + using BlockToBlockMap_t = map<const BasicBlock_t*, BasicBlock_t*>; + + class DominatorGraph_t + { + protected: + DominatorGraph_t(){} + DominatorGraph_t(const DominatorGraph_t& copy)=delete; + public: + unique_ptr<DominatorGraph_t*> factory( + const ControlFlowGraph_t* p_cfg, + bool needs_postdoms=false, + bool needs_idoms=false + ); + + virtual const BasicBlockSet_t& getDominators(const BasicBlock_t* node) const = 0 ; + virtual const BasicBlockSet_t& getPostDominators(const BasicBlock_t* node) const = 0 ; + virtual bool hasWarnings() const = 0 ; + virtual const BasicBlock_t* getImmediateDominator(const BasicBlock_t* node) const = 0 ; + virtual const BasicBlock_t* getImmediatePostDominators(const BasicBlock_t* node) const = 0 ; + virtual void dump(ostream &os=cout) const = 0 ; -}; - -std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg); + }; + ostream& operator<<(ostream& os, const DominatorGraph_t& cfg); +} diff --git a/include/irdb-cfg b/include/irdb-cfg index 6251c73..21f4c5d 100644 --- a/include/irdb-cfg +++ b/include/irdb-cfg @@ -23,7 +23,7 @@ /* Building a CFG depends on core functionality */ -#include <IRDB_SDK-core.hpp> +#include <irdb-core> #include <vector> #include <set> -- GitLab