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

working on libIRDB-cfg

parent fc5f9496
No related branches found
No related tags found
No related merge requests found
/*
* 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);
}
/*
* 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);
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;
};
}
/*
* 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;
};
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);
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