Skip to content

Commit

Permalink
Add dyninstAPI/src/BPatch_flowGraph.C
Browse files Browse the repository at this point in the history
  • Loading branch information
hainest committed Apr 3, 2024
1 parent fefcdfa commit 6bbd00e
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 103 deletions.
115 changes: 108 additions & 7 deletions docs/dyninstAPI/developer/BPatch_flowGraph.h.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,132 @@ BPatch_flowGraph.h

.. cpp:class:: BPatch_flowGraph : public Dyninst::AnnotatableSparse

.. cpp:member:: std::set<BPatch_basicBlockLoop*> *loops
.. cpp:member:: private BPatch_function *func_
.. cpp:member:: private BPatch_addressSpace *addSpace
.. cpp:member:: private BPatch_module *mod

.. cpp:member:: private std::set<BPatch_basicBlockLoop*> *loops

set of loops contained in control flow graph

.. cpp:member:: std::set<BPatch_basicBlock*> allBlocks
.. cpp:member:: private std::set<BPatch_basicBlock*> allBlocks

set of all basic blocks that control flow graph has

.. cpp:member:: BPatch_loopTreeNode *loopRoot
.. cpp:member:: private BPatch_loopTreeNode *loopRoot

root of the tree of loops

.. cpp:member:: std::set<BPatch_edge*> backEdges
.. cpp:member:: private std::set<BPatch_edge*> backEdges

set of back edges

.. cpp:member:: bool isDominatorInfoReady
.. cpp:member:: private bool isDominatorInfoReady

flag that keeps whether dominator info is initialized

.. cpp:member:: bool isPostDominatorInfoReady
.. cpp:member:: private bool isPostDominatorInfoReady

flag that keeps whether postdominator info is initialized

.. cpp:member:: bool isSourceBlockInfoReady
.. cpp:member:: private bool isSourceBlockInfoReady

flag that keeps whether source block info is initialized


.. cpp:member:: private std::map<Dyninst::PatchAPI::PatchLoop*, BPatch_basicBlockLoop*> _loop_map

.. cpp:function:: private bool createBasicBlocks()

This is the main method to create the basic blocks and the the edges between basic blocks. After
finding the leaders, for each leader a basic block is created and then the predecessors and
successors of the basic blocks are inserted to the basic blocks by passing from the function address
space again, one instruction at a time, and using maps from basic blocks to leaders, and leaders to
basic blocks. The basic block of which the leader is the start address of the function is assumed to
be the entry block to control flow graph. This makes only one basic block to be in the entryBlocks
field of the controlflow grpah. If it is possible to enter a function from many points some
modification is needed to insert all entry basic blocks to the esrelevant field of the class.

.. cpp:function:: bool createSourceBlocks()

Creates the source line blocks of all blocks in CFG.

This function must be called only after basic blocks have been created by calling createBasicBlocks.
It computes the source block for each basic block. For now, a source block is represented by the
starting and ending line numbers in the source block for the basic block. Without calling this method,
line info is not available

.. cpp:function:: void fillDominatorInfo()

Fills the dominator information of each basic block looking at the control flow edges. It uses a
fixed point calculation to find the immediate dominator of the basic blocks and the set of basic
blocks that are immediately dominated by this one. Before calling this method all the dominator
information is going to give incorrect results. So first this function must be called to process
dominator related fields and methods.

.. cpp:function:: void fillPostDominatorInfo()

same as :cpp:func:`fillDominatorInfo`, but for postdominatorimmediate-postdom info

.. cpp:function:: private void dfsVisitWithTargets(BPatch_basicBlock*,int*)
.. cpp:function:: private void dfsVisitWithSources(BPatch_basicBlock*,int*)
.. cpp:function:: private void findAndDeleteUnreachable()
.. cpp:function:: private static void findBBForBackEdge(BPatch_edge*, std::set<BPatch_basicBlock*>&)
.. cpp:function:: private void getLoopsByNestingLevel(BPatch_Vector<BPatch_basicBlockLoop*>&, bool outerMostOnly)

Returns the loop objects that exist in the control flow grap.

.. cpp:function:: private void dfsPrintLoops(BPatch_loopTreeNode *n)
.. cpp:function:: private void createLoops()
.. cpp:function:: private void dump()
.. cpp:function:: private void findLoopExitInstPoints(BPatch_basicBlockLoop *loop, BPatch_Vector<BPatch_point*> *points)

.. cpp:function:: BPatch_Vector<BPatch_point*>* findLoopInstPoints(const BPatch_procedureLocation loc, \
Patch_basicBlockLoop *loop)

.. code:: console
We need to detect and handle following cases:
(1) If a loop has no entry edge, e.g. the loop head is also
first basic block of the function, we need to create a loop
preheader. we probably want to relocate the function at this
point.
___
v |
f: [_]--/
|
[ ]
(2) If a loop header is shared between two loops then add a new
nop node N, redirect the back edge of each loop to N and make N
jump to the header. this transforms the two loops into a single
loop.
_ _
--->[_]<--- [_]<---
| _/ \_ | _/ \_ |
\-[_] [_]-/ [_] [_] |
\_/ |
[N]---/
Also, loop instrumentation works on the control flow as it was
_originally_ parsed. Function entry/exit instrumentation may
have modified the this control flow, but this new
instrumentation is not cognizant of these modifications. This
instrumentation therefore may clobber any instrumentation that
was added because it has an inaccurate view of the binary.
2014-10-14 Xiaozhu:
Case (2) becomes irrelevant because under the new loop detection
algorithm, there is going to be only one loop identified.
Case (1) is still a problem.
.. cpp:function:: bool getEntryBasicBlock(BPatch_Vector<BPatch_basicBlock*> &blocks)

Actually, there must be only one entry point to each control flow graph but the definition given API
specifications say there might be more.
18 changes: 4 additions & 14 deletions docs/dyninstAPI/public/BPatch_flowGraph.h.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ BPatch_flowGraph.h

.. cpp:function:: bool getEntryBasicBlock(BPatch_Vector<BPatch_basicBlock*> &blocks)

returns the vector of entry basic blocks to CFG
Returns the basic blocks that are entry points in the control flow graph.

.. cpp:function:: bool getExitBasicBlock(BPatch_Vector<BPatch_basicBlock*> &blocks)

returns the vector of exit basic blocks to CFG
Returns the basic blocks that are the exit basic blocks from the control flow graph.
That is, those are the basic blocks that contains the instruction for returning from
the function.

.. cpp:function:: BPatch_basicBlock *findBlockByAddr(Dyninst::Address addr)

Expand All @@ -68,18 +70,6 @@ BPatch_flowGraph.h

Returns in ``loops`` the natural (single entry) outer loops in the control flow graph.

.. cpp:function:: bool createSourceBlocks()

creates the source line blocks of all blocks in CFG. without calling this method line info is not available

.. cpp:function:: void fillDominatorInfo()

fills the dominator and immediate-dom information of basic blocks. without calling this method dominator info is not available

.. cpp:function:: void fillPostDominatorInfo()

same as :cpp:func:`fillDominatorInfo`, but for postdominatorimmediate-postdom info

.. cpp:function:: BPatch_loopTreeNode * getLoopTree()

Return the root node of the tree of loops in this flow graph.
Expand Down
82 changes: 0 additions & 82 deletions dyninstAPI/src/BPatch_flowGraph.C
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@

using namespace Dyninst::PatchAPI;

// constructor of the class. It creates the CFG and
// deletes the unreachable code.
BPatch_flowGraph::BPatch_flowGraph(BPatch_function *func,
bool &valid)
: func_(func), addSpace(func->getAddSpace()), mod(func->getModule()),
Expand Down Expand Up @@ -116,48 +114,6 @@ BPatch_Vector<BPatch_point*> *
BPatch_flowGraph::findLoopInstPoints(const BPatch_procedureLocation loc,
BPatch_loop *loop)
{
/*
* We need to detect and handle following cases:
*
* (1) If a loop has no entry edge, e.g. the loop head is also
* first basic block of the function, we need to create a loop
* preheader. we probably want to relocate the function at this
* point.
*
* ___
* v |
* f: [_]--/
* |
* [ ]
*
*
* (2) If a loop header is shared between two loops then add a new
* nop node N, redirect the back edge of each loop to N and make N
* jump to the header. this transforms the two loops into a single
* loop.
*
* _ _
* --->[_]<--- [_]<---
* | _/ \_ | _/ \_ |
* \-[_] [_]-/ [_] [_] |
* \_/ |
* [N]---/
*
*
* Also, loop instrumentation works on the control flow as it was
* _originally_ parsed. Function entry/exit instrumentation may
* have modified the this control flow, but this new
* instrumentation is not cognizant of these modifications. This
* instrumentation therefore may clobber any instrumentation that
* was added because it has an inaccurate view of the binary.
*
*
* 2014-10-14 Xiaozhu:
* Case (2) becomes irrelevant because under the new loop detection
* algorithm, there is going to be only one loop identified.
* Case (1) is still a problem.
*/

if (DEBUG_LOOP)
fprintf(stderr,"%s findLoopInstPoints 0x%p\n",
ll_func()->prettyName().c_str(), (void*)loop);
Expand Down Expand Up @@ -301,10 +257,6 @@ BPatch_flowGraph::getAllBasicBlocks(BPatch_Set<BPatch_basicBlock*>& abb) {
return true;
}

// this is the method that returns the set of entry points
// basic blocks, to the control flow graph. Actually, there must be
// only one entry point to each control flow graph but the definition
// given API specifications say there might be more.
bool
BPatch_flowGraph::getEntryBasicBlock(BPatch_Vector<BPatch_basicBlock*>& ebb)
{
Expand All @@ -313,10 +265,6 @@ BPatch_flowGraph::getEntryBasicBlock(BPatch_Vector<BPatch_basicBlock*>& ebb)
return true;
}

// this method returns the set of basic blocks that are the
// exit basic blocks from the control flow graph. That is those
// are the basic blocks that contains the instruction for
// returning from the function
bool
BPatch_flowGraph::getExitBasicBlock(BPatch_Vector<BPatch_basicBlock*>& nbb)
{
Expand Down Expand Up @@ -359,9 +307,6 @@ BPatch_flowGraph::createLoops()

}

// this methods returns the loop objects that exist in the control flow
// grap. It returns a set. And if there are no loops, then it returns the empty
// set. not NULL.
void BPatch_flowGraph::getLoopsByNestingLevel(BPatch_Vector<BPatch_loop*>& lbb,
bool outerMostOnly)
{
Expand All @@ -381,15 +326,13 @@ void BPatch_flowGraph::getLoopsByNestingLevel(BPatch_Vector<BPatch_loop*>& lbb,
}


// get all the loops in this flow graph
bool
BPatch_flowGraph::getLoops(BPatch_Vector<BPatch_basicBlockLoop*>& lbb)
{
getLoopsByNestingLevel(lbb, false);
return true;
}

// get the outermost loops in this flow graph
bool
BPatch_flowGraph::getOuterLoops(BPatch_Vector<BPatch_basicBlockLoop*>& lbb)
{
Expand All @@ -398,19 +341,6 @@ BPatch_flowGraph::getOuterLoops(BPatch_Vector<BPatch_basicBlockLoop*>& lbb)
}


//this is the main method to create the basic blocks and the
//the edges between basic blocks.
//after finding the leaders, for each leader a basic block is created and
//then the predecessors and successors of the basic blocks are inserted
//to the basic blocks by passing from the function address space again, one
//instruction at a time, and using maps from basic blocks to leaders, and
//leaders to basic blocks.
//The basic block of which the
//leader is the start address of the function is assumed to be the entry block
//to control flow graph. This makes only one basic block to be in the
//entryBlocks field of the controlflow grpah. If it is possible
//to enter a function from many points some modification is needed
//to insert all entry basic blocks to the esrelevant field of the class.
bool BPatch_flowGraph::createBasicBlocks()
{
assert(ll_func());
Expand Down Expand Up @@ -456,11 +386,6 @@ bool BPatch_flowGraph::createBasicBlocks()
}


// This function must be called only after basic blocks have been created
// by calling createBasicBlocks. It computes the source block for each
// basic block. For now, a source block is represented by the starting
// and ending line numbers in the source block for the basic block.

bool BPatch_flowGraph::createSourceBlocks() {
if( isSourceBlockInfoReady ) { return true; }

Expand Down Expand Up @@ -524,13 +449,6 @@ bool BPatch_flowGraph::createSourceBlocks() {
return true;
} /* end createSourceBlocks() */

//this method fill the dominator information of each basic block
//looking at the control flow edges. It uses a fixed point calculation
//to find the immediate dominator of the basic blocks and the set of
//basic blocks that are immediately dominated by this one.
//Before calling this method all the dominator information
//is going to give incorrect results. So first this function must
//be called to process dominator related fields and methods.
void BPatch_flowGraph::fillDominatorInfo()
{
if(isDominatorInfoReady)
Expand Down

0 comments on commit 6bbd00e

Please sign in to comment.