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: ...@@ -27,6 +27,9 @@ class BasicBlock:
else: else:
self.listFunctionCalls = listFuncCalls self.listFunctionCalls = listFuncCalls
self.flow = 0.0 self.flow = 0.0
self.mapsTo = []
self.nestingLevel = -1
self.hasConditionalExec = 0
class ControlFlowGraph: class ControlFlowGraph:
...@@ -35,6 +38,19 @@ class ControlFlowGraph: ...@@ -35,6 +38,19 @@ class ControlFlowGraph:
self.listEdges = listEdges self.listEdges = listEdges
self.listBackEdges = [] 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): def successorBlocks(self, blockIndex):
listSuccBlockIndices = [] listSuccBlockIndices = []
for edge in self.listEdges: for edge in self.listEdges:
...@@ -86,6 +102,8 @@ class ControlFlowGraph: ...@@ -86,6 +102,8 @@ class ControlFlowGraph:
def dft(self, blockIndex): def dft(self, blockIndex):
self.dft_stack.append(blockIndex) self.dft_stack.append(blockIndex)
for succBlock in self.successorBlocksWOBackEdges(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: if succBlock not in self.dft_stack:
self.dft(succBlock) self.dft(succBlock)
else: else:
...@@ -119,6 +137,7 @@ class ControlFlowGraph: ...@@ -119,6 +137,7 @@ class ControlFlowGraph:
Depth First Fashion Depth First Fashion
''' '''
self.dft_stack = [] self.dft_stack = []
self.listBlocks[0].nestingLevel = 0
self.dft(0) self.dft(0)
self.listBackEdges = list(set(self.listBackEdges)) self.listBackEdges = list(set(self.listBackEdges))
return self.listBackEdges return self.listBackEdges
......
...@@ -8,7 +8,7 @@ from cfg import * ...@@ -8,7 +8,7 @@ from cfg import *
re_sectionStart = re.compile('Disassembly of section .(.*):') re_sectionStart = re.compile('Disassembly of section .(.*):')
re_funcDef = re.compile('\s*([0-9a-f]*)\s*<(.*)>:') 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_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_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*<(.*)>') 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 = []): ...@@ -53,6 +53,8 @@ def parse_binary(fileName, listFunctionNames = []):
listCurrFuncBlockEndLineNum = [] listCurrFuncBlockEndLineNum = []
listCurrFuncBlockStartAddress = [] listCurrFuncBlockStartAddress = []
listCurrFuncBlockEndAddress = [] listCurrFuncBlockEndAddress = []
listCurrFuncConditionalExecInstAtLine = []
lineNumForAddress = {} lineNumForAddress = {}
branchInstAtLine = {} branchInstAtLine = {}
returnInstAtLine = {} returnInstAtLine = {}
...@@ -111,7 +113,8 @@ def parse_binary(fileName, listFunctionNames = []): ...@@ -111,7 +113,8 @@ def parse_binary(fileName, listFunctionNames = []):
if m is not None: if m is not None:
address = m.group(1) address = m.group(1)
lineNumForAddress[address] = lineNum; lineNumForAddress[address] = lineNum;
inst = m.group(2) opcode = m.group(2)
inst = m.group(3)
m = re_branchInst.match(inst) m = re_branchInst.match(inst)
if m is not None and m.group(3).startswith(currFuncName): if m is not None and m.group(3).startswith(currFuncName):
...@@ -139,6 +142,12 @@ def parse_binary(fileName, listFunctionNames = []): ...@@ -139,6 +142,12 @@ def parse_binary(fileName, listFunctionNames = []):
listCurrFuncBlockEndAddress.append(address) listCurrFuncBlockEndAddress.append(address)
continue 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 continue
else: else:
# inside Function, instruction did not match i.e. end of # inside Function, instruction did not match i.e. end of
...@@ -229,6 +238,12 @@ def parse_binary(fileName, listFunctionNames = []): ...@@ -229,6 +238,12 @@ def parse_binary(fileName, listFunctionNames = []):
if block.startLine <= lNum and block.endLine >= lNum: if block.startLine <= lNum and block.endLine >= lNum:
block.listFunctionCalls.append(calledFuncName) 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 # Add the current function and the CFG to the list of functions
listFunctions.append(FunctionDesc(currFuncName, listFunctions.append(FunctionDesc(currFuncName,
currFuncFileName, currFuncFileName,
...@@ -246,6 +261,7 @@ def parse_binary(fileName, listFunctionNames = []): ...@@ -246,6 +261,7 @@ def parse_binary(fileName, listFunctionNames = []):
listCurrFuncBlockEndLineNum = [] listCurrFuncBlockEndLineNum = []
listCurrFuncBlockStartAddress = [] listCurrFuncBlockStartAddress = []
listCurrFuncBlockEndAddress = [] listCurrFuncBlockEndAddress = []
listCurrFuncConditionalExecInstAtLine = []
#lineNumForAddress = {} #lineNumForAddress = {}
branchInstAtLine = {} branchInstAtLine = {}
returnInstAtLine = {} returnInstAtLine = {}
...@@ -255,7 +271,23 @@ def parse_binary(fileName, listFunctionNames = []): ...@@ -255,7 +271,23 @@ def parse_binary(fileName, listFunctionNames = []):
return listFunctions, lineNumForAddress 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: for func in listFunctions:
print("\nFileName : %s" % (func.fileName)) print("\nFileName : %s" % (func.fileName))
print("Function : %s" % (func.functionName)) print("Function : %s" % (func.functionName))
...@@ -269,6 +301,11 @@ def print_debug_binary(listFunctions): ...@@ -269,6 +301,11 @@ def print_debug_binary(listFunctions):
for edge in func.cfg.listEdges: for edge in func.cfg.listEdges:
if edge.fromBlockIndex == i: if edge.fromBlockIndex == i:
print("\t\t Edge to block %d" % (edge.toBlockIndex)) 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 i = i + 1
......
...@@ -19,6 +19,8 @@ re_gotoLine = re.compile('\s*goto\s*(\w*bb_[0-9]*);') ...@@ -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_funcCallLine = re.compile('\s*(\w*)\s*\([,\s\w&\[\]\*]*\);')
re_returnLine = re.compile('\s*return\s*.*;') re_returnLine = re.compile('\s*return\s*.*;')
re_funcDefEnd = re.compile('\s*\}') re_funcDefEnd = re.compile('\s*\}')
re_commentStart = re.compile('\s*/\*.*')
re_commentEnd = re.compile('\s*.*\*/')
class BasicBlockTargets: class BasicBlockTargets:
def __init__(self, name, listTargets = None): def __init__(self, name, listTargets = None):
...@@ -49,6 +51,8 @@ def parse_isc(fileName): ...@@ -49,6 +51,8 @@ def parse_isc(fileName):
listCurrBlockFuncCalls = [] listCurrBlockFuncCalls = []
listCurrBasicBlockTargets = [] listCurrBasicBlockTargets = []
inMultiLineComment = 0
lineNum = 0 lineNum = 0
file = open(fileName, 'r') file = open(fileName, 'r')
for line in file: for line in file:
...@@ -75,6 +79,23 @@ def parse_isc(fileName): ...@@ -75,6 +79,23 @@ def parse_isc(fileName):
1. Keep note if current Basic Block Returns. 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 # 1. Look for function definition
m = re_funcDef.match(line) m = re_funcDef.match(line)
if m is not None: if m is not None:
......
This diff is collapsed.
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