Skip to content
Snippets Groups Projects
Commit 87299dec authored by Jason Hiser's avatar Jason Hiser :tractor:
Browse files

added irdb-cfg

parent 914f72be
No related branches found
No related tags found
No related merge requests found
...@@ -20,14 +20,14 @@ ...@@ -20,14 +20,14 @@
#include <ostream> #include <ostream>
#include <set> #include <set>
#include <vector>
namespace IRDB_SDK namespace IRDB_SDK
{ {
using namespace std; using namespace std;
class BasicBlock_t; class BasicBlock_t;
using BasicBlockSet_t = set<BasicBlock_t*>; using BasicBlockSet_t = set<BasicBlock_t*>;
using InstructionVector_t = vector<Instruction_t*>;
class BasicBlock_t class BasicBlock_t
{ {
...@@ -35,24 +35,20 @@ namespace IRDB_SDK ...@@ -35,24 +35,20 @@ namespace IRDB_SDK
BasicBlock_t() {} BasicBlock_t() {}
BasicBlock_t(const BasicBlock_t& copy) = delete; BasicBlock_t(const BasicBlock_t& copy) = delete;
public: public:
virtual ~BasicBlock_t() {}
bool getIsExitBlock() const = 0; virtual bool getIsExitBlock() const = 0;
const InstructionVector_t& getInstructions() const = 0; virtual const InstructionVector_t& getInstructions() const = 0;
const BasicBlockSet_t& getPredecessors() const = 0; virtual const BasicBlockSet_t& getPredecessors() const = 0;
const BasicBlockSet_t& getSuccessors() const = 0; virtual const BasicBlockSet_t& getSuccessors() const = 0;
const BasicBlockSet_t& getIndirectTargets() const = 0; virtual const BasicBlockSet_t& getIndirectTargets() const = 0;
const BasicBlock_t* getFallthrough() const = 0; virtual bool endsInBranch() const = 0;
const BasicBlock_t* getTarget() const = 0; virtual bool endsInIndirectBranch() const = 0;
virtual bool endsInConditionalBranch() const = 0;
virtual Instruction_t* getBranchInstruction() const = 0;
bool endsInBranch() = 0; virtual void dump(ostream &os=cout) const = 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); ostream& operator<<(ostream& os, const BasicBlock_t& block);
} }
/*
* 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 }; namespace IRDB_SDK
typedef std::set<CFG_EdgeTypeEnum> CFG_EdgeType;
class ControlFlowGraph_t
{ {
public: using namespace std;
ControlFlowGraph_t(Function_t* func); enum CFGEdgeTypeEnum { cetFallthroughEdge, cetTargetEdge, cetIndirectEdge };
BasicBlock_t* GetEntry() const { return entry; } using CFGEdgeType_t = set<CFGEdgeTypeEnum>;
Function_t* GetFunction() const { return function; }
BasicBlockSet_t& GetBlocks() { return blocks; } class ControlFlowGraph_t
const BasicBlockSet_t& GetBlocks() const { return blocks; } {
void dump(std::ostream &os=std::cout) const { os<<*this; } protected:
bool HasEdge(BasicBlock_t *p_src, BasicBlock_t *p_tgt) const; ControlFlowGraph_t() { }
CFG_EdgeType GetEdgeType(const BasicBlock_t *p_src, const BasicBlock_t *p_tgt) const; ControlFlowGraph_t(const ControlFlowGraph_t& copy) = delete;
public:
private:
// methods virtual BasicBlock_t* getEntry() const = 0 ;
void Build(Function_t *func); virtual Function_t* getFunction() const = 0 ;
void alloc_blocks(const InstructionSet_t &starts, map<Instruction_t*,BasicBlock_t*>& insn2block_map); virtual const BasicBlockSet_t& getBlocks() const = 0 ;
void build_blocks(const map<Instruction_t*,BasicBlock_t*>& insn2block_map); virtual bool hasEdge(BasicBlock_t *p_src, BasicBlock_t *p_tgt) const = 0 ;
void find_unblocked_instructions(InstructionSet_t &starts, Function_t* func); virtual CFGEdgeType_t getEdgeType(const BasicBlock_t *p_src, const BasicBlock_t *p_tgt) const = 0 ;
virtual void dump(ostream &os=cout) const = 0 ;
// data
BasicBlockSet_t blocks; // factories
BasicBlock_t* entry; static unique_ptr<ControlFlowGraph_t> factory(Function_t* func);
Function_t* function;
};
/* friends */ ostream& operator<<(ostream& os, const ControlFlowGraph_t& cfg);
public:
friend std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg); }
};
std::ostream& operator<<(std::ostream& os, const ControlFlowGraph_t& cfg);
...@@ -4,6 +4,14 @@ namespace IRDB_SDK ...@@ -4,6 +4,14 @@ namespace IRDB_SDK
{ {
using namespace std; 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 class CallGraphNode_t
{ {
...@@ -13,36 +21,29 @@ namespace IRDB_SDK ...@@ -13,36 +21,29 @@ namespace IRDB_SDK
public: public:
virtual ~CallGraphNode_t() { } virtual ~CallGraphNode_t() { }
bool isHellnode() const =0; virtual bool isHellnode() const = 0;
Function_t* getFunction() const =0; virtual Function_t* getFunction() const = 0;
virtual void dump(ostream& os=cout) const = 0;
}; };
class CallGraph_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 Callgraph_t
{ {
protected: protected:
Callgraph_t() {} CallGraph_t() {}
Callgraph_t(const Callgraph_t& copy) = delete; CallGraph_t(const CallGraph_t& copy) = delete;
public: public:
virtual ~Callgraph_t() { } virtual ~CallGraph_t() { }
virtual void addFile() = 0; // accessors
virtual bool edgeExists(const CallGraphEdge_t& edge) const = 0;
virtual void addFile(FileIR_t* const firp) = 0;
virtual bool edgeExists(const CallGraphEdge_t& edge) const = 0;
virtual const CallGraphNodeSet_t& virtual const CallGraphNodeSet_t&
getCallersOfNode(CallGraphNode_t* const node) const = 0; getCallersOfNode(CallGraphNode_t* const node) const = 0;
virtual const CallGraphNodeSet_t& virtual const CallGraphNodeSet_t&
getCalleesOfNode(CallGraphNode_t* const node) const = 0; getCalleesOfNode(CallGraphNode_t* const node) const = 0;
/*
virtual const CallGraphNodeSet_t& ancestors, virtual const CallGraphNodeSet_t&
getAncestors getAncestors
( (
const Function_t* const fn, const Function_t* const fn,
...@@ -50,22 +51,25 @@ namespace IRDB_SDK ...@@ -50,22 +51,25 @@ namespace IRDB_SDK
) const = 0; ) const = 0;
virtual const CallSiteSet_t& virtual const CallSiteSet_t&
getCallSites(CallGraphNode_t* const n1) const = 0; getCallSites(CallGraphNode_t* const n1) const = 0;
virtual string getNodeName(const 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 virtual bool isReachable
( (
CallGraphNode_t* const from, CallGraphNode_t* const from,
CallGraphNode_t* const to, CallGraphNode_t* const to,
bool skipHellNode = false bool skipHellNode = false
) const = 0; ) const = 0;
virtual const CallGraphNode_t& virtual const CallGraphNode_t&
getDefaultHellNode() const = 0; getDefaultHellNode() const = 0;
virtual CallGraphNode_t* virtual CallGraphNode_t*
findNode(Function_t* const fn) const = 0; 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);
} }
/*
* 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; namespace IRDB_SDK
typedef std::set<BasicBlockEdge_t> BasicBlockEdgeSet_t;
class CriticalEdgeAnalyzer_t
{ {
public: using namespace std;
CriticalEdgeAnalyzer_t(const ControlFlowGraph_t &p_cfg, const bool p_conservative=true); using BasicBlockEdge_t = tuple<BasicBlock_t*, BasicBlock_t*>;
BasicBlockEdgeSet_t GetAllCriticalEdges() const; 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;
};
namespace IRDB_SDK
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: using namespace std;
typedef const BasicBlockSet_t& (*pred_func_ptr_t) (const BasicBlock_t* node); using DominatorMap_t = map<const BasicBlock_t*, BasicBlockSet_t>;
using BlockToBlockMap_t = map<const BasicBlock_t*, BasicBlock_t*>;
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); class DominatorGraph_t
{
protected:
DominatorMap_t dom_graph; DominatorGraph_t(){}
BlockToBlockMap_t idom_graph; DominatorGraph_t(const DominatorGraph_t& copy)=delete;
public:
DominatorMap_t post_dom_graph; unique_ptr<DominatorGraph_t*> factory(
BlockToBlockMap_t post_idom_graph; const ControlFlowGraph_t* p_cfg,
bool needs_postdoms=false,
const ControlFlowGraph_t& cfg; // a reference to our cfg. bool needs_idoms=false
);
bool warn;
virtual const BasicBlockSet_t& getDominators(const BasicBlock_t* node) const = 0 ;
friend std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg); 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 ;
}; };
ostream& operator<<(ostream& os, const DominatorGraph_t& cfg);
std::ostream& operator<<(std::ostream& os, const DominatorGraph_t& cfg);
}
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* Building a CFG depends on core functionality */ /* Building a CFG depends on core functionality */
#include <IRDB_SDK-core.hpp> #include <irdb-core>
#include <vector> #include <vector>
#include <set> #include <set>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment