Commit d6939e5b authored by Gaurav Kukreja's avatar Gaurav Kukreja

Added display_cfg functionality

Signed-off-by: Gaurav Kukreja's avatarGaurav Kukreja <gaurav@gauravk.in>
parent d7c836b6
......@@ -68,11 +68,11 @@ class ControlFlowGraph:
edgeIndex = edgeIndex + 1
return listSuccBlockIndices
def successorBlocks(self, blockIndex):
def predecessorBlocks(self, blockIndex):
listSuccBlockIndices = []
for edge in self.listEdges:
if edge.fromBlockIndex == blockIndex:
listSuccBlockIndices.append(edge.toBlockIndex)
if edge.toBlockIndex == blockIndex:
listSuccBlockIndices.append(edge.fromBlockIndex)
return listSuccBlockIndices
def predecessorBlocksWOBackEdges(self, blockIndex):
......
......@@ -183,7 +183,8 @@ def parse_binary(fileName, listFunctionNames = []):
listBlocks = []
for i in range(len(listCurrFuncBlockStartLineNum)):
listBlocks.append(BasicBlock(listCurrFuncBlockStartLineNum[i],
listCurrFuncBlockEndLineNum[i]))
listCurrFuncBlockEndLineNum[i],
name = "%d" % i))
......
import sys
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
from collections import deque
from cfg import *
class Graph(pg.GraphItem):
def __init__(self):
self.dragPoint = None
self.dragOffset = None
self.textItems = []
pg.GraphItem.__init__(self)
self.scatter.sigClicked.connect(self.clicked)
def setData(self, **kwds):
self.text = kwds.pop('text', [])
self.data = kwds
if 'pos' in self.data:
npts = self.data['pos'].shape[0]
self.data['data'] = np.empty(npts, dtype=[('index', int)])
self.data['data']['index'] = np.arange(npts)
self.setTexts(self.text)
self.updateGraph()
def setTexts(self, text):
for i in self.textItems:
i.scene().removeItem(i)
self.textItems = []
for t in text:
item = pg.TextItem(t)
self.textItems.append(item)
item.setParentItem(self)
def updateGraph(self):
pg.GraphItem.setData(self, **self.data)
for i,item in enumerate(self.textItems):
item.setPos(*self.data['pos'][i])
def mouseDragEvent(self, ev):
if ev.button() != QtCore.Qt.LeftButton:
ev.ignore()
return
if ev.isStart():
# We are already one step into the drag.
# Find the point(s) at the mouse cursor when the button was first
# pressed:
pos = ev.buttonDownPos()
pts = self.scatter.pointsAt(pos)
if len(pts) == 0:
ev.ignore()
return
self.dragPoint = pts[0]
ind = pts[0].data()[0]
self.dragOffset = self.data['pos'][ind] - pos
elif ev.isFinish():
self.dragPoint = None
return
else:
if self.dragPoint is None:
ev.ignore()
return
ind = self.dragPoint.data()[0]
self.data['pos'][ind] = ev.pos() + self.dragOffset
self.updateGraph()
ev.accept()
def clicked(self, pts):
print("clicked: %s" % pts)
verticalGap = 5
horizontalGap = 15
def display_cfgs(app, cfg1, cfg2, windowTitle):
# Initialization of Qt
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
w = pg.GraphicsWindow()
w.setWindowTitle(windowTitle)
v1 = w.addViewBox()
v1.setAspectLocked()
g1 = Graph()
v1.addItem(g1)
(pos, adj, texts, symbols) = draw_cfg(cfg1)
g1.setData(pos=pos, adj=adj, size=1, pxMode=False, text=texts, symbol=symbols)
v2 = w.addViewBox()
v2.setAspectLocked()
g2 = Graph()
v2.addItem(g2)
(pos, adj, texts, symbols) = draw_cfg(cfg2)
print adj
g2.setData(pos=pos, adj=adj, size=1, pxMode=False, text=texts, symbol=symbols)
app.exec_();
def draw_cfg(cfg1):
logging.debug ("Inside Function draw_cfg()")
'''
Breadth first search for all blocks in the Control Flow Graph to print them
on screen.
'''
posOfBlock = {}
posOfBlock[0] = 0
symbols = ['+']
pos = np.array([[0, 0]])
adj = None
texts = ["%s" % cfg1.listBlocks[0].name]
# Queue for BFS
q = deque([0])
while q:
# Extract entry from queue, will be 0 for the first iteration.
blockInd = q.popleft()
logging.debug ("Block %d" % blockInd)
# Find all children of the
succBlocks = cfg1.successorBlocks(blockInd)
print "\t successors = ",
print succBlocks
spaceForChildren = (len(succBlocks) - 1) * horizontalGap
logging.debug ("\t has %d children, space = %d" % (len(succBlocks), spaceForChildren))
if len(succBlocks) > 1:
i = 0
for succBlock in succBlocks:
if succBlock == blockInd:
# Self Edge!!
continue
logging.debug ("\t Successor Block %d" % succBlock)
if succBlock in posOfBlock:
logging.debug ("\t\t Already drawn at %d, %d" % (pos[posOfBlock[succBlock]][0], pos[posOfBlock[succBlock]][1]))
if adj == None:
adj = np.array([[posOfBlock[blockInd], posOfBlock[succBlock]]])
else:
adj = np.insert(adj, len(adj), [posOfBlock[blockInd], posOfBlock[succBlock]], axis = 0)
else:
parent = None
for predBlock in cfg1.predecessorBlocks(succBlock):
if predBlock in posOfBlock:
parent = predBlock
break;
if parent == None:
# should never occur
logging.error ("Parent of a child does not exist, which should never happen!")
exit(1)
parentPos = pos[posOfBlock[parent]]
posSuccBlock = [parentPos[0] - (spaceForChildren/2) + (i*horizontalGap), parentPos[1] - verticalGap]
posOfBlock[succBlock] = len(pos)
pos = np.insert(pos, len(pos), posSuccBlock, axis = 0)
if adj == None:
adj = np.array([[posOfBlock[blockInd], posOfBlock[succBlock]]])
else:
adj = np.insert(adj, len(adj), [posOfBlock[blockInd], posOfBlock[succBlock]], axis = 0)
logging.debug ("\t\t Drawn at %d, %d" % (posSuccBlock[0], posSuccBlock[1]))
texts.append("%s" % cfg1.listBlocks[succBlock].name)
if cfg1.listBlocks[succBlock].isReturning == 1:
symbols.append('x')
else:
symbols.append('o')
if succBlock not in q:
q.append(succBlock)
i = i + 1
elif len(succBlocks) == 1:
succBlock = succBlocks[0]
logging.debug ("\t Successor Block %d" % succBlock)
if succBlock in posOfBlock:
logging.debug ("\t\t Already drawn at %d, %d" % (pos[posOfBlock[succBlock]][0], pos[posOfBlock[succBlock]][1]))
if adj == None:
adj = np.array([[posOfBlock[blockInd], posOfBlock[succBlock]]])
else:
adj = np.insert(adj, len(adj), [posOfBlock[blockInd], posOfBlock[succBlock]], axis = 0)
else:
predBlocks = cfg1.predecessorBlocksWOBackEdges(succBlock)
if len(predBlocks) > 1:
posSuccBlockX = 0
posSuccBlockY = 0
for predBlock in predBlocks:
posSuccBlockX = pos[posOfBlock[predBlock]][0] + posSuccBlockX
if posSuccBlockY > pos[posOfBlock[predBlock]][1] - verticalGap:
posSuccBlockY = pos[posOfBlock[predBlock]][1] - verticalGap
posSuccBlockX = posSuccBlockX / len(predBlocks)
posSuccBlock = [posSuccBlockX, posSuccBlockY]
posOfBlock[succBlock] = len(pos)
pos = np.insert(pos, len(pos), posSuccBlock, axis = 0)
if adj == None:
adj = np.array([[posOfBlock[blockInd], posOfBlock[succBlock]]])
else:
adj = np.insert(adj, len(adj), [posOfBlock[blockInd], posOfBlock[succBlock]], axis = 0)
logging.debug ("\t\t Drawn at %d, %d" % (posSuccBlock[0], posSuccBlock[1]))
texts.append("%s" % cfg1.listBlocks[succBlock].name)
if cfg1.listBlocks[succBlock].isReturning == 1:
symbols.append('x')
else:
symbols.append('o')
if succBlock not in q:
q.append(succBlock)
else:
parent = predBlocks[0]
parentPos = pos[posOfBlock[parent]]
posSuccBlock = [parentPos[0], parentPos[1] - verticalGap]
posOfBlock[succBlock] = len(pos)
pos = np.insert(pos, len(pos), posSuccBlock, axis = 0)
if adj == None:
adj = np.array([[posOfBlock[blockInd], posOfBlock[succBlock]]])
else:
adj = np.insert(adj, len(adj), [posOfBlock[blockInd], posOfBlock[succBlock]], axis = 0)
logging.debug ("\t\t Drawn at %d, %d" % (posSuccBlock[0], posSuccBlock[1]))
texts.append("%s" % cfg1.listBlocks[succBlock].name)
if cfg1.listBlocks[succBlock].isReturning == 1:
symbols.append('x')
else:
symbols.append('o')
if succBlock not in q:
q.append(succBlock)
else:
continue
return pos, adj, texts, symbols
\ No newline at end of file
......@@ -6,12 +6,15 @@ from optparse import OptionParser
from subprocess import call
import logging
import re
from collections import deque
import sys
from PyQt4 import QtGui, QtCore
from cfg_binary import parse_binary, print_debug_binary
from cfg_isc import parse_isc, print_debug_isc
from display_cfg import display_cfgs
from collections import deque
app = None
listISCFileNames = []
listObjdumpFileNames = []
......@@ -59,6 +62,28 @@ def printDebugMapCFG(listISCFunctions, listObjdumpFunctions, gdbMapping):
gdbMapping[lineNum].fileName,
ISCBlockName))
i = i + 1
for func in listISCFunctions:
print("\nFileName : %s" % (func.fileName))
print("Function : %s" % (func.functionName))
ObjFuncCfg = find(lambda fn: fn.functionName == func.functionName, listObjdumpFunctions).cfg
i = 0
for block in func.cfg.listBlocks:
print("\t Block %s: line %d - %d, flow = %f, nestingLevel = %d" %
(func.cfg.listBlocks[i].name, block.startLine, block.endLine,
block.flow, block.nestingLevel))
print "\t Maps to ",
print list(set(block.mapsTo))
for funcCall in block.listFunctionCalls:
print("\t\t calls %s()" % (funcCall))
if block.hasConditionalExec == 1:
print("\t\t Conditional Execution Instruction!")
if block.isReturning == 1:
print("\t\t returns")
for edge in func.cfg.listEdges:
if edge.fromBlockIndex == i:
print("\t\t Edge to block %s" % (func.cfg.listBlocks[edge.toBlockIndex].name))
i = i + 1
def gdbMappingDebug(gdbMapping):
for lineNum in gdbMapping:
......@@ -116,12 +141,12 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
mappingStackObj.append(blockIndObj)
blockISC = cfgISC.listBlocks[blockIndISC]
blockObj = cfgObj.listBlocks[blockIndObj]
print "\tMapping blocks ISC:%s and OBJ:%d" % (blockISC.name, blockIndObj)
print "\tmergedLevelsISC = %d" % (mergedLevelsISC)
logging.debug("\tMapping blocks ISC:%s and OBJ:%d" % (blockISC.name, blockIndObj))
logging.debug( "\tmergedLevelsISC = %d" % (mergedLevelsISC))
if (blockISC.isReturning == 1 and
blockObj.isReturning == 1):
print "\t\tBoth Blocks return!!!"
logging.debug( "\t\tBoth Blocks return!!!")
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
mappingStackISC.pop()
......@@ -131,7 +156,7 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
if (blockISC.flow != blockObj.flow or
(blockISC.nestingLevel - mergedLevelsISC) != blockObj.nestingLevel or
blockISC.isReturning != blockObj.isReturning):
print "\t\tFlow, or nesting level did not match or only one of them returns!"
logging.debug( "\t\tFlow, or nesting level did not match or only one of them returns!")
mappingStackISC.pop()
mappingStackObj.pop()
return -1
......@@ -148,7 +173,7 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
if(len(listSuccWOBackEdgeISC) != len(listSuccWOBackEdgeObj)):
if(blockObj.hasConditionalExec == 1 and
len(listSuccWOBackEdgeObj) == len(listSuccWOBackEdgeISC) - 1):
print "\t\t Conditional Execution Found!"
logging.debug( "\t\t Conditional Execution Found!")
# Conditional Execution!
for succ1BlockISC in listSuccISC:
if succ1BlockISC in mappingStackISC:
......@@ -156,12 +181,13 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
for succSucc1BlockISC in cfgISC.successorBlocks(succ1BlockISC):
if succSucc1BlockISC in mappingStackISC:
continue
for succ2BlockISC in list(set(listSuccISC) - {succ1BlockISC}):
if succ2BlockISC in mappingStackISC:
continue
if succSucc1BlockISC == succ2BlockISC:
# case 1
print "\t\t case 1"
logging.debug( "\t\t case 1")
mappingStackISC.append(succ1BlockISC)
mappingStackObj.pop() # popping blockIndObj, because mapping it again
if mapping(cfgISC, succ2BlockISC, cfgObj, blockIndObj, mergedLevelsISC + 1) == 0:
......@@ -175,33 +201,7 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
else:
mappingStackISC.pop()
mappingStackObj.append(blockIndObj)
# if succSucc1BlockISC in (set(listSuccISC) - {succ1BlockISC}):
# # case 1
# print "\t\tcase 1"
# for succSuccSucc1BlockISC in cfgISC.successorBlocks(succSucc1BlockISC):
# if succSuccSucc1BlockISC in mappingStackISC:
# continue
# for succBlockObj in listSuccObj:
# if succBlockObj in mappingStackObj:
# continue
# mappingStackISC.append(succ1BlockISC)
# mappingStackISC.append(succSucc1BlockISC)
# if mapping(cfgISC, succSuccSucc1BlockISC, cfgObj, succBlockObj, mergedLevelsISC+1) == 0:
# cfgISC.listBlocks[blockIndISC].mapsTo.append(blockIndObj)
# cfgISC.listBlocks[succ1BlockISC].mapsTo.append(blockIndObj)
# cfgISC.listBlocks[succSucc1BlockISC].mapsTo.append(blockIndObj)
# cfgObj.listBlocks[blockIndObj].mapsTo.append(succSucc1BlockISC)
# mappingStackISC.pop()
# mappingStackISC.pop()
# mappingStackISC.pop()
# mappingStackObj.pop()
# return 0
# else:
# mappingStackISC.pop()
# mappingStackISC.pop()
for succ2BlockISC in list(set(listSuccISC) - {succ1BlockISC}):
if succ2BlockISC in mappingStackISC:
continue
......@@ -210,7 +210,7 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
continue
if succSucc1BlockISC == succSucc2BlockISC:
# case 2
print "\t\t case 2"
logging.debug( "\t\t case 2")
mappingStackISC.append(succ1BlockISC)
mappingStackISC.append(succ2BlockISC)
mappingStackObj.pop() # popping blockIndObj, because mapping it again
......@@ -228,46 +228,18 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
mappingStackISC.pop()
mappingStackISC.pop()
mappingStackObj.append(blockIndObj)
# for succSuccSucc1BlockISC in cfgISC.successorBlocks(succSucc1BlockISC):
# if succSuccSucc1BlockISC in mappingStackISC:
# continue
# for succBlockObj in listSuccObj:
# if succBlockObj in mappingStackObj:
# continue
# mappingStackISC.append(succ1BlockISC)
# mappingStackISC.append(succ2BlockISC)
# mappingStackISC.append(succSucc1BlockISC)
# if mapping(cfgISC, succSuccSucc1BlockISC, cfgObj, succBlockObj, mergedLevelsISC+2) == 0:
# cfgISC.listBlocks[blockIndISC].mapsTo.append(blockIndObj)
# cfgISC.listBlocks[succ1BlockISC].mapsTo.append(blockIndObj)
# cfgISC.listBlocks[succ2BlockISC].mapsTo.append(blockIndObj)
# cfgISC.listBlocks[succSucc1BlockISC].mapsTo.append(blockIndObj)
# cfgObj.listBlocks[blockIndObj].mapsTo.append(succSucc1BlockISC)
# mappingStackISC.pop()
# mappingStackISC.pop()
# mappingStackISC.pop()
# mappingStackISC.pop()
# mappingStackObj.pop()
# return 0
# else:
# mappingStackISC.pop()
# mappingStackISC.pop()
# mappingStackISC.pop()
else:
print "no. of successors not same, and difference more than one."
print "ISC Block %d; Obj Block %d" % (blockIndISC, blockIndObj)
logging.debug( "no. of successors not same, and difference more than one.")
logging.debug( "ISC Block %d; Obj Block %d" % (blockIndISC, blockIndObj))
exit(1)
print "Successors of ISC:%d" % (blockIndISC),
print cfgISC.successorBlocks(blockIndISC)
for succBlockISC in cfgISC.successorBlocks(blockIndISC):
if succBlockISC in mappingStackISC:
continue
for succBlockObj in listSuccObj:
if succBlockObj in mappingStackObj:
continue
print "recursing on mapping"
if mapping(cfgISC, succBlockISC, cfgObj, succBlockObj, mergedLevelsISC) == 0:
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
......@@ -276,7 +248,6 @@ def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
mappingStackISC.pop()
mappingStackObj.pop()
print "Here"
return 0
def map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames):
......@@ -314,8 +285,7 @@ def map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames):
for binaryFileName in listBinaryFileNames:
gdbMapping = getGDBMapping(binaryFileName, objdumpLineNumForAddress)
print_debug_isc (listISCFunctions)
print_debug_binary (listObjdumpFunctions, gdbMapping)
mappingStackISC = []
mappingStackObj = []
......@@ -324,18 +294,27 @@ def map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames):
fnObj = find(lambda fn: fn.functionName == fnISC.functionName, listObjdumpFunctions)
cfgObj = fnObj.cfg
print "Mapping Function %s" % (fnISC.functionName)
logging.debug( "Mapping Function %s" % (fnISC.functionName))
if mapping(cfgISC, 0, cfgObj, 0, 0) == 0:
print "Mapping Found!!!!"
logging.debug( "Mapping Found!!!!s")
else:
print "Fuck my life!!!"
logging.debug( "Fuck my life!!!")
# print_debug_isc (listISCFunctions)
# print_debug_binary (listObjdumpFunctions, gdbMapping)
printDebugMapCFG(listISCFunctions, listObjdumpFunctions, gdbMapping)
display_cfgs(app, listISCFunctions[0].cfg, listObjdumpFunctions[0].cfg, "%s" % listISCFunctions[0].functionName)
# display_cfg(app, listISCFunctions[1].cfg, "%s" % listISCFunctions[0].functionName)
# app.exec_()
if __name__ == "__main__":
# listISCFileNames = []
# listObjdumpFileNames = []
app = QtGui.QApplication(sys.argv)
logging.basicConfig(level=logging.WARNING)
optparser = OptionParser()
optparser.add_option("-i", "--isc", action="append", dest="listISCFileNames",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment