Commit 81ee224e authored by Gaurav Kukreja's avatar Gaurav Kukreja

Map CFG working for ADPCM

Signed-off-by: Gaurav Kukreja's avatarGaurav Kukreja <gaurav@gauravk.in>
parent 0faeaaca
......@@ -27,6 +27,9 @@ class BasicBlock:
else:
self.listFunctionCalls = listFuncCalls
self.flow = 0.0
self.mapsTo = []
self.nestingLevel = -1
self.hasConditionalExec = 0
class ControlFlowGraph:
......@@ -35,6 +38,19 @@ class ControlFlowGraph:
self.listEdges = listEdges
self.listBackEdges = []
def find(self, blockName=None, lineNum = None):
if blockName:
for block in self.listBlocks:
if block.name == blockName:
return block
return None
if lineNum:
for block in self.listBlocks:
if block.startLine <= lineNum and block.endLine >= lineNum:
return block
return None
def successorBlocks(self, blockIndex):
listSuccBlockIndices = []
for edge in self.listEdges:
......@@ -86,6 +102,8 @@ class ControlFlowGraph:
def dft(self, blockIndex):
self.dft_stack.append(blockIndex)
for succBlock in self.successorBlocksWOBackEdges(blockIndex):
if self.listBlocks[succBlock].nestingLevel > self.listBlocks[blockIndex].nestingLevel or self.listBlocks[succBlock].nestingLevel == -1:
self.listBlocks[succBlock].nestingLevel = self.listBlocks[blockIndex].nestingLevel + 1
if succBlock not in self.dft_stack:
self.dft(succBlock)
else:
......@@ -119,6 +137,7 @@ class ControlFlowGraph:
Depth First Fashion
'''
self.dft_stack = []
self.listBlocks[0].nestingLevel = 0
self.dft(0)
self.listBackEdges = list(set(self.listBackEdges))
return self.listBackEdges
......
......@@ -8,7 +8,7 @@ from cfg import *
re_sectionStart = re.compile('Disassembly of section .(.*):')
re_funcDef = re.compile('\s*([0-9a-f]*)\s*<(.*)>:')
re_instruction = re.compile('\s*([0-9a-f]*):\s*[0-9a-f]*\s*(.*)')
re_instruction = re.compile('\s*([0-9a-f]*):\s*([0-9a-f]*)\s*(.*)')
re_branchInst = re.compile('\s*(b(?!ic)(?:l|x|lx|xj)?(?:eq|ne|mi|pl|hi|ls|ge|lt|gt|le)?)\s*([0-9a-f]*)\s*<(.*)>')
re_unconditionalBranchInst = re.compile('\s*(b(?:l|x|lx|xj)?)\s*([0-9a-f]*)\s*<(.*)>')
re_conditionalBranchInst = re.compile('\s*(b(?:l|x|lx|xj)?(?:eq|ne|mi|pl|hi|ls|ge|lt|gt|le))\s*([0-9a-f]*)\s*<(.*)>')
......@@ -53,6 +53,8 @@ def parse_binary(fileName, listFunctionNames = []):
listCurrFuncBlockEndLineNum = []
listCurrFuncBlockStartAddress = []
listCurrFuncBlockEndAddress = []
listCurrFuncConditionalExecInstAtLine = []
lineNumForAddress = {}
branchInstAtLine = {}
returnInstAtLine = {}
......@@ -111,7 +113,8 @@ def parse_binary(fileName, listFunctionNames = []):
if m is not None:
address = m.group(1)
lineNumForAddress[address] = lineNum;
inst = m.group(2)
opcode = m.group(2)
inst = m.group(3)
m = re_branchInst.match(inst)
if m is not None and m.group(3).startswith(currFuncName):
......@@ -139,6 +142,12 @@ def parse_binary(fileName, listFunctionNames = []):
listCurrFuncBlockEndAddress.append(address)
continue
# Not a branch or return instruction,
# Check if a conditional execution instruction
if re.match('[0-9a-d]./*', opcode):
listCurrFuncConditionalExecInstAtLine.append(lineNum)
continue
continue
else:
# inside Function, instruction did not match i.e. end of
......@@ -229,6 +238,12 @@ def parse_binary(fileName, listFunctionNames = []):
if block.startLine <= lNum and block.endLine >= lNum:
block.listFunctionCalls.append(calledFuncName)
# Indicate which blocks have conditional execution instructions
for lNum in listCurrFuncConditionalExecInstAtLine:
for block in listBlocks:
if block.startLine <= lNum and block.endLine >= lNum:
block.hasConditionalExec = 1
# Add the current function and the CFG to the list of functions
listFunctions.append(FunctionDesc(currFuncName,
currFuncFileName,
......@@ -246,6 +261,7 @@ def parse_binary(fileName, listFunctionNames = []):
listCurrFuncBlockEndLineNum = []
listCurrFuncBlockStartAddress = []
listCurrFuncBlockEndAddress = []
listCurrFuncConditionalExecInstAtLine = []
#lineNumForAddress = {}
branchInstAtLine = {}
returnInstAtLine = {}
......@@ -255,7 +271,23 @@ def parse_binary(fileName, listFunctionNames = []):
return listFunctions, lineNumForAddress
def print_debug_binary(listFunctions):
def print_debug_binary(listFunctions, gdbMapping=None):
if gdbMapping == None:
for func in listFunctions:
print("\nFileName : %s" % (func.fileName))
print("Function : %s" % (func.functionName))
i = 0
for block in func.cfg.listBlocks:
print("\t Block %d: line %d - %d, flow = %f" % (i, block.startLine, block.endLine, block.flow))
for funcCall in block.listFunctionCalls:
print("\t\t calls %s()" % (funcCall))
if block.isReturning == 1:
print("\t\t returns")
for edge in func.cfg.listEdges:
if edge.fromBlockIndex == i:
print("\t\t Edge to block %d" % (edge.toBlockIndex))
i = i + 1
else:
for func in listFunctions:
print("\nFileName : %s" % (func.fileName))
print("Function : %s" % (func.functionName))
......@@ -269,6 +301,11 @@ def print_debug_binary(listFunctions):
for edge in func.cfg.listEdges:
if edge.fromBlockIndex == i:
print("\t\t Edge to block %d" % (edge.toBlockIndex))
for lineNum in range(block.startLine, block.endLine):
if lineNum in gdbMapping:
print("\t\t Line %d from %s:%d" % (lineNum,
gdbMapping[lineNum].fileName,
gdbMapping[lineNum].lineNum))
i = i + 1
......
......@@ -19,6 +19,8 @@ re_gotoLine = re.compile('\s*goto\s*(\w*bb_[0-9]*);')
re_funcCallLine = re.compile('\s*(\w*)\s*\([,\s\w&\[\]\*]*\);')
re_returnLine = re.compile('\s*return\s*.*;')
re_funcDefEnd = re.compile('\s*\}')
re_commentStart = re.compile('\s*/\*.*')
re_commentEnd = re.compile('\s*.*\*/')
class BasicBlockTargets:
def __init__(self, name, listTargets = None):
......@@ -49,6 +51,8 @@ def parse_isc(fileName):
listCurrBlockFuncCalls = []
listCurrBasicBlockTargets = []
inMultiLineComment = 0
lineNum = 0
file = open(fileName, 'r')
for line in file:
......@@ -75,6 +79,23 @@ def parse_isc(fileName):
1. Keep note if current Basic Block Returns.
'''
# Comment Handling
m = re_commentStart.match(line)
if m is not None:
if re_commentEnd.match(line) == None:
inMultiLineComment = 1
continue
else:
continue
if inMultiLineComment == 1:
m = re_commentEnd.match(line)
if m is not None:
inMultiLineComment = 0
continue
else:
continue
# 1. Look for function definition
m = re_funcDef.match(line)
if m is not None:
......
......@@ -22,11 +22,54 @@ class GDBMapTarget:
self.fileName = fileName
self.lineNum = lineNum
def printDebugMapCFG(listISCFunctions, listObjdumpFunctions, gdbMapping):
for func in listObjdumpFunctions:
print("\nFileName : %s" % (func.fileName))
print("Function : %s" % (func.functionName))
ISCFuncCfg = find(lambda fn: fn.functionName == func.functionName, listISCFunctions).cfg
i = 0
for block in func.cfg.listBlocks:
print("\t Block %d: line %d - %d, flow = %f, nestingLevel = %d" %
(i, block.startLine, block.endLine,
block.flow, block.nestingLevel))
print "\t Maps to ",
block.mapsTo = list(set(block.mapsTo))
for blockIndISC in block.mapsTo:
print ISCFuncCfg.listBlocks[blockIndISC].name+", ",
print ""
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 %d" % (edge.toBlockIndex))
for lineNum in range(block.startLine, block.endLine):
if lineNum in gdbMapping:
ISCFileName = gdbMapping[lineNum].fileName
ISCLineNum = gdbMapping[lineNum].lineNum
ISCBlock = ISCFuncCfg.find(lineNum = ISCLineNum)
if ISCBlock is not None:
ISCBlockName = ISCFuncCfg.find(lineNum = ISCLineNum).name
else:
ISCBlockName = "%d" % (ISCLineNum)
print("\t\t Line %d from %s:%s" % (lineNum,
gdbMapping[lineNum].fileName,
ISCBlockName))
i = i + 1
def gdbMappingDebug(gdbMapping):
for lineNum in gdbMapping:
print ("line %d maps to %s:%d" % (lineNum, gdbMapping[lineNum].fileName, gdbMapping[lineNum].lineNum))
def find(f, seq):
"""Return first item in sequence where f(item) == True."""
for item in seq:
if f(item):
return item
def getGDBMapping(binFileName, objdumpLineNumForAddress):
gdbMapping = {}
......@@ -60,14 +103,145 @@ def getGDBMapping(binFileName, objdumpLineNumForAddress):
gdbMapping[objdumpLineNum] = GDBMapTarget(targetFileName, targetLineNum)
gdbOutputFile.close()
# gdbMappingDebug(gdbMapping)
# gdbMappingDebug(gdbMapping)
return gdbMapping
mappingStackISC = []
mappingStackObj = []
def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC):
# a = input("Press Enter to continue...")
mappingStackISC.append(blockIndISC)
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)
if (blockISC.isReturning == 1 and
blockObj.isReturning == 1):
print "\t\tBoth Blocks return!!!"
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
mappingStackISC.pop()
mappingStackObj.pop()
return 0
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!"
mappingStackISC.pop()
mappingStackObj.pop()
return -1
# if (blockIndISC, blockIndObj) in mappingDict:
# return mappingDict[(blockIndISC, blockIndObj)]
mincost = -1
listSuccISC = cfgISC.successorBlocks(blockIndISC)
listSuccObj = cfgObj.successorBlocks(blockIndObj)
listSuccWOBackEdgeISC = cfgISC.successorBlocksWOBackEdges(blockIndISC)
listSuccWOBackEdgeObj = cfgObj.successorBlocksWOBackEdges(blockIndObj)
if(len(listSuccWOBackEdgeISC) != len(listSuccWOBackEdgeObj)):
if(blockObj.hasConditionalExec == 1 and
len(listSuccWOBackEdgeObj) == len(listSuccWOBackEdgeISC) - 1):
print "\t\t Conditional Execution Found!"
# Conditional Execution!
for succ1BlockISC in listSuccISC:
if succ1BlockISC in mappingStackISC:
continue
for succSucc1BlockISC in cfgISC.successorBlocks(succ1BlockISC):
if succSucc1BlockISC in mappingStackISC:
continue
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
for succSucc2BlockISC in cfgISC.successorBlocks(succ2BlockISC):
if succSucc2BlockISC in mappingStackISC:
continue
if succSucc1BlockISC == succSucc2BlockISC:
# case 2
print "\t\tcase 2"
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)
exit(1)
for succBlockISC in listSuccISC:
if succBlockISC in mappingStackISC:
continue
for succBlockObj in listSuccObj:
if succBlockObj in mappingStackObj:
continue
if mapping(cfgISC, succBlockISC, cfgObj, succBlockObj, mergedLevelsISC) == 0:
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
else:
continue
mappingStackISC.pop()
mappingStackObj.pop()
print "Here"
return 0
def map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames):
listISCFunctions = []
listFunctionNames = []
listObjdumpFunctions = []
gdbMapping = []
# Parse the ISC files
for ISCFileName in listISCFileNames:
......@@ -96,10 +270,25 @@ def map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames):
function.cfg.computeFlow()
for binaryFileName in listBinaryFileNames:
getGDBMapping(binaryFileName, objdumpLineNumForAddress)
gdbMapping = getGDBMapping(binaryFileName, objdumpLineNumForAddress)
print_debug_isc (listISCFunctions)
print_debug_binary (listObjdumpFunctions)
print_debug_binary (listObjdumpFunctions, gdbMapping)
mappingStackISC = []
mappingStackObj = []
for fnISC in listISCFunctions:
cfgISC = fnISC.cfg
fnObj = find(lambda fn: fn.functionName == fnISC.functionName, listObjdumpFunctions)
cfgObj = fnObj.cfg
print "Mapping Function %s" % (fnISC.functionName)
if mapping(cfgISC, 0, cfgObj, 0, 0) == 0:
print "Mapping Found!!!!"
else:
print "Fuck my life!!!"
printDebugMapCFG(listISCFunctions, listObjdumpFunctions, gdbMapping)
if __name__ == "__main__":
......
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