diff --git a/include/inc-cfg/BasicBlock.hpp b/include/inc-cfg/BasicBlock.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c04e48348f90f90a215efa7107b2b931ffae7184 --- /dev/null +++ b/include/inc-cfg/BasicBlock.hpp @@ -0,0 +1,58 @@ +/* + * 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/ + * + */ + +#include <ostream> +#include <set> + +namespace IRDB_SDK +{ + using namespace std; + + class BasicBlock_t; + + using BasicBlockSet_t = set<BasicBlock_t*>; + + class BasicBlock_t + { + protected: + BasicBlock_t() {} + BasicBlock_t(const BasicBlock_t& copy) = delete; + public: + + 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; + + + bool endsInBranch() = 0; + bool endsInIndirectBranch() = 0; + bool endsInConditionalBranch() = 0; + Instruction_t* getBranchInstruction() = 0; + + void dump(ostream &os=std::cout) = 0 ; + + }; + ostream& operator<<(ostream& os, const BasicBlock_t& block); + +} diff --git a/include/inc-cfg/CFG.hpp b/include/inc-cfg/CFG.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8bf1d0b2f752590fb8609b2e79807eb1d3cf6895 --- /dev/null +++ b/include/inc-cfg/CFG.hpp @@ -0,0 +1,56 @@ +/* + * 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 +{ + 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); + + diff --git a/include/inc-cfg/callgraph.hpp b/include/inc-cfg/callgraph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..02dca2c8e88df452777da21cc1ab4c7cac5cc850 --- /dev/null +++ b/include/inc-cfg/callgraph.hpp @@ -0,0 +1,70 @@ + + +namespace IRDB_SDK +{ + using namespace std; + + + class CallGraphNode_t + { + protected: + CallGraphNode_t() { } + CallGraphNode_t(const CallGraphNode_t& copy) = delete; + public: + virtual ~CallGraphNode_t() { } + + bool isHellnode() const =0; + Function_t* getFunction() 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 + { + protected: + Callgraph_t() {} + Callgraph_t(const Callgraph_t& copy) = delete; + public: + virtual ~Callgraph_t() { } + virtual void addFile() = 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, + getAncestors + ( + const Function_t* const fn, + const bool skipHellNode = false + ) 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 bool isReachable + ( + CallGraphNode_t* const from, + CallGraphNode_t* const to, + bool skipHellNode = false + ) const = 0; + + virtual const CallGraphNode_t& + getDefaultHellNode() const = 0; + + virtual CallGraphNode_t* + findNode(Function_t* const fn) const = 0; + }; + +} diff --git a/include/inc-cfg/criticaledge.hpp b/include/inc-cfg/criticaledge.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6126703ea5fa32f25c13ad7aeca0392dcaff6508 --- /dev/null +++ b/include/inc-cfg/criticaledge.hpp @@ -0,0 +1,33 @@ +/* + * 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 +{ + public: + CriticalEdgeAnalyzer_t(const ControlFlowGraph_t &p_cfg, const bool p_conservative=true); + BasicBlockEdgeSet_t GetAllCriticalEdges() const; + + private: + const ControlFlowGraph_t m_cfg; + const bool m_conservative; +}; diff --git a/include/inc-cfg/domgraph.hpp b/include/inc-cfg/domgraph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..087fc4dd604d8458be76de68b188447ffaf68ba9 --- /dev/null +++ b/include/inc-cfg/domgraph.hpp @@ -0,0 +1,54 @@ + + + +typedef std::map<const BasicBlock_t*, BasicBlockSet_t> DominatorMap_t; +typedef std::map<const BasicBlock_t*, BasicBlock_t*> BlockToBlockMap_t; + +class DominatorGraph_t +{ + 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); + +}; + +std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg); + +