diff --git a/libIRDB-cfg/include/domgraph.hpp b/libIRDB-cfg/include/domgraph.hpp index 932a34475e59e7044cffb485dcca828bc87a6f43..db37459ae80730a03cc2a15e599ba5b8003d5a72 100644 --- a/libIRDB-cfg/include/domgraph.hpp +++ b/libIRDB-cfg/include/domgraph.hpp @@ -3,8 +3,8 @@ namespace libIRDB { using namespace std; - using DominatorMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>; - using BlockToBlockMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>; + using DominatorMap_t = map<IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>; + using BlockToBlockMap_t = map<IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>; @@ -18,27 +18,38 @@ namespace libIRDB // get the (post) dominators for a node - IRDB_SDK::BasicBlockSet_t& GetDominators(const IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; } - IRDB_SDK::BasicBlockSet_t& GetPostDominators(const IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; } + IRDB_SDK::BasicBlockSet_t& GetDominators(IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; } + IRDB_SDK::BasicBlockSet_t& GetPostDominators(IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; } - const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(node); } - const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { return post_dom_graph.at(node); } + const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(const_cast<IRDB_SDK::BasicBlock_t*>(node)); } + const IRDB_SDK::BasicBlockSet_t& getDominated (const IRDB_SDK::BasicBlock_t* node) const { return dominated_graph.at(const_cast<IRDB_SDK::BasicBlock_t*>(node)); } +// const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { assert(0); } +// const IRDB_SDK::BasicBlockSet_t& getPostDominated (const IRDB_SDK::BasicBlock_t* node) const { assert(0); } bool hasWarnings() const { return warn; } // get the immeidate (post) dominators for a node - const IRDB_SDK::BasicBlock_t* getImmediateDominator(const IRDB_SDK::BasicBlock_t* node) const - { auto it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; } - const IRDB_SDK::BasicBlock_t* getImmediatePostDominators(const IRDB_SDK::BasicBlock_t* node) const - { auto it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; } + const IRDB_SDK::BasicBlock_t* getImmediateDominator (const IRDB_SDK::BasicBlock_t* node) const + { + auto it=idom_graph.find(const_cast<IRDB_SDK::BasicBlock_t*>(node)); + return (it!=idom_graph.end()) ? it->second : nullptr; + } + const IRDB_SDK::BasicBlockSet_t& getImmediateDominated (const IRDB_SDK::BasicBlock_t* node) const + { + const static IRDB_SDK::BasicBlockSet_t empty; + auto it=idominated_graph.find(const_cast<IRDB_SDK::BasicBlock_t*>(node)); + return (it!=idominated_graph.end()) ? it->second : empty; } +// const IRDB_SDK::BasicBlock_t* getImmediatePostDominator(const IRDB_SDK::BasicBlock_t* node) const { assert(0); } +// const IRDB_SDK::BasicBlockSet_t& getImmediatePostDominated(const IRDB_SDK::BasicBlock_t* node) const { assert(0); } void dump(ostream& os=cout) const; private: + void Dominated_Compute(); - typedef const IRDB_SDK::BasicBlockSet_t& (*pred_func_ptr_t) (const IRDB_SDK::BasicBlock_t* node); + using pred_func_ptr_t = const IRDB_SDK::BasicBlockSet_t& (*) (const IRDB_SDK::BasicBlock_t* node); DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r); BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r); @@ -47,6 +58,9 @@ namespace libIRDB DominatorMap_t dom_graph; BlockToBlockMap_t idom_graph; + DominatorMap_t dominated_graph; + DominatorMap_t idominated_graph; + DominatorMap_t post_dom_graph; BlockToBlockMap_t post_idom_graph; diff --git a/libIRDB-cfg/src/BasicBlock.cpp b/libIRDB-cfg/src/BasicBlock.cpp index ffd9baf5fa1696f48b17d91f4114b29f9c088468..e89e6664e805291a2ffc4674957353cdae319fb9 100644 --- a/libIRDB-cfg/src/BasicBlock.cpp +++ b/libIRDB-cfg/src/BasicBlock.cpp @@ -167,7 +167,7 @@ void BasicBlock_t::BuildBlock assert(insn); const auto icfs = insn->getIBTargets(); const auto d = DecodedInstruction_t::factory(insn); - const auto include_icfs = (d->isReturn() || d->isCall() ) ; + const auto include_icfs = !(d->isReturn() || d->isCall() ) ; if(icfs != nullptr && include_icfs) diff --git a/libIRDB-cfg/src/domgraph.cpp b/libIRDB-cfg/src/domgraph.cpp index c7f9895b382b3006c2160651cf6e8a134d79e8dd..36a10b4ced1dca25f7a867d268b8032bdaf44584 100644 --- a/libIRDB-cfg/src/domgraph.cpp +++ b/libIRDB-cfg/src/domgraph.cpp @@ -44,20 +44,22 @@ inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms, bool needs_idoms) : cfg(*p_cfg), warn(false) { + auto &blocks=p_cfg->getBlocks(); assert(needs_postdoms==false); assert(needs_idoms==false); -// typedef const BasicBlockSet_t& (*) (const BasicBlock_t* node) pred_func_ptr_t; pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t& { return node->getPredecessors(); }; - dom_graph=Dom_Comp(p_cfg->getBlocks(), func_get_predecessors, p_cfg->getEntry()); - idom_graph=Idom_Comp(p_cfg->getBlocks(), dom_graph, p_cfg->getEntry()); + dom_graph=Dom_Comp(blocks, func_get_predecessors, p_cfg->getEntry()); + idom_graph=Idom_Comp(blocks, dom_graph, p_cfg->getEntry()); + + Dominated_Compute(); // a func may have multiple exit nodes. how do we deal with that? // psuedo-block? invoke this for each exit block? @@ -300,6 +302,7 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N }; }; + //for each n \in N-{r} do for (auto n : NminusR) { @@ -312,6 +315,26 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N } // IDom_Comp +void DominatorGraph_t::Dominated_Compute() +{ + for(auto p : dom_graph) + { + auto dominates = p.first; + auto dominated_set = p.second; + + for(auto dominated : dominated_set) + dominated_graph[dominated].insert(dominates); + } + for(auto p : idom_graph) + { + auto dominates = p.first; + auto dominated = p.second; + idominated_graph[dominated].insert(dominates); + } + +} + + ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg) @@ -322,28 +345,43 @@ ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg) void DominatorGraph_t::dump(ostream& os) const { - // for_each(dg.cfg.GetBlocks().begin(), dg.cfg.GetBlocks().end(), [&](const BasicBlock_t* blk) for(auto blk : cfg.getBlocks()) { assert(blk); - const auto& blk_dominates=getDominators(blk); + const auto& blk_dominators=getDominators(blk); auto first_insn=*(blk->getInstructions().begin()); assert(first_insn); - os<<"\tBlock entry id:" <<blk->getInstructions()[0]->getBaseID()<<endl; - os<<"\t\tDominated by: "; - for(auto dom : blk_dominates) + os<<"\tBlock entry id:" <<dec<<blk->getInstructions()[0]->getBaseID()<<endl; + os<<"\t\tBlocks that (eventually) dominate me: "; + for(auto blk : blk_dominators) { - os<<dom->getInstructions()[0]->getBaseID()<<", "; + os<<blk->getInstructions()[0]->getBaseID()<<", "; }; os<<endl; const IRDB_SDK::BasicBlock_t* idom=getImmediateDominator(blk); if(idom) - os<<"\t\tImmediate Dominator: "<<hex<<idom->getInstructions()[0]->getBaseID()<<endl; + os<<"\t\tMy Immediate Dominator: "<<dec<<idom->getInstructions()[0]->getBaseID()<<endl; else os<<"\t\tNo Immed Dominator."<<endl; + + os<<"\t\tBlocks I (eventually) Dominate: "; + const auto& dominated_blocks=getDominated(blk); + for(auto blk : dominated_blocks) + { + os<<blk->getInstructions()[0]->getBaseID()<<", "; + }; + os<<endl; + + os<<"\t\tBlocks I Immediately Dominate: "; + const auto& imm_dominated_blocks=getImmediateDominated(blk); + for(auto blk : imm_dominated_blocks) + { + os<<blk->getInstructions()[0]->getBaseID()<<", "; + }; + os<<endl; }; } @@ -356,3 +394,7 @@ IRDB_SDK::DominatorGraph_t::factory(const ControlFlowGraph_t* p_cfg, const bool return unique_ptr<IRDB_SDK::DominatorGraph_t>(new libIRDB::DominatorGraph_t(real_cfg, needs_postdoms, needs_idoms)); } + + + +