Commit 1201ec2e authored by Gaurav Kukreja's avatar Gaurav Kukreja

rewrote map_cfg.py in match_cfg.py, working for all o1 cases with gdbMapping

Signed-off-by: Gaurav Kukreja's avatarGaurav Kukreja <gaurav@gauravk.in>
parent 74d89116
import re
import logging
from optparse import OptionParser
from subprocess import call
from instrument import *
from map_cfg import map_cfg
def find(f, seq):
"""Return first item in sequence where f(item) == True."""
for item in seq:
if f(item):
return item
def debugListGlobalVariables(listGlobalVariables):
print ""
for globVar in listGlobalVariables:
print ("%s\t\t0x%x\t\t(type=%s; length=%d) - %s:%d" %
(globVar.name, globVar.address, globVar.type, globVar.length,
globVar.file, globVar.lineNum))
print ""
def getGlobalVariablesInfoFromGDB(listBinaryFileNames):
re_AllDefinedVariables = re.compile("All Defined Variables:")
re_File = re.compile("File\s(.*):")
re_Variable = re.compile("((?:[\w_]*\s)*)([\w_]*)(?:\[([0-9]*)\])*;")
re_VarAdd = re.compile("Symbol \"([\w_]*)\" is static storage at address ([0-9a-fA-Fx]*).")
listGlobalVariables = []
for fileName in listBinaryFileNames:
# Fetch Global Variable Names from this file
gdbXFileName = fileName + ".globalVarNames.gdbx"
gdbXFile = open(gdbXFileName, 'w')
command = "info variables\n"
gdbXFile.write(command)
gdbXFile.write("quit\n")
gdbXFile.close()
gdbGlobalVarNamesOutputFileName = fileName + ".globalVarNames.gdbo"
gdbGlobalVarNamesOutputFile = open(gdbGlobalVarNamesOutputFileName, 'w')
call(args=["gdb", "--quiet", "--command="+gdbXFileName, fileName],
stdout=gdbGlobalVarNamesOutputFile)
gdbGlobalVarNamesOutputFile.close()
gdbGlobalVarNamesOutputFile = open(gdbGlobalVarNamesOutputFileName, 'r')
currFileName = ""
currListGlobalVariables = []
for line in gdbGlobalVarNamesOutputFile:
m = re_File.match(line)
if m is not None:
currFileName = m.group(1)
m = re_Variable.match(line)
if m is not None:
dataType = m.group(1)
varName = m.group(2)
if m.group(3) is not None:
varLen = int(m.group(3))
else:
varLen = 0
currListGlobalVariables.append(GlobalVariable(name=varName,
type=dataType,
length=varLen,
file=currFileName))
gdbGlobalVarNamesOutputFile.close()
# Fetch addresses for Global Variables in this file
gdbXGlobalVarAddFileName = fileName + ".globalVarAdd.gdbx"
gdbXGlobalVarAddFile = open(gdbXGlobalVarAddFileName, 'w')
for var in currListGlobalVariables:
gdbXGlobalVarAddFile.write("info address %s\n" % (var.name))
gdbXGlobalVarAddFile.write("quit\n")
gdbXGlobalVarAddFile.close()
gdbGlobalVarAddOutputFileName = fileName + ".globalVarAdd.gdbo"
gdbGlobalVarAddOutputFile = open(gdbGlobalVarAddOutputFileName, 'w')
call(args=["gdb", "--quiet", "--command="+gdbXGlobalVarAddFileName, fileName],
stdout=gdbGlobalVarAddOutputFile)
gdbGlobalVarAddOutputFile.close()
gdbGlobalVarAddOutputFile = open(gdbGlobalVarAddOutputFileName, 'r')
for line in gdbGlobalVarAddOutputFile:
m = re_VarAdd.match(line)
if m is not None:
var = find(lambda v: v.name == m.group(1), currListGlobalVariables)
var.setAddress(int(m.group(2), 16))
listGlobalVariables = listGlobalVariables + currListGlobalVariables
debugListGlobalVariables(listGlobalVariables)
return listGlobalVariables
re_loadPCRelative = re.compile("\s*ldr\s*[\w]\2,\s*\[pc,\s#[\d]*\]\s*;\s*[a-fA-F0-9]*\s*<\w*+0x[a-fA-F0-9]*>")
def instrument_cache(listISCFileNames, listISCFunctions,
listObjdumpFileNames, listObjdumpFunctions,
listBinaryFileNames):
'''
Algorithm
'''
getGlobalVariablesInfoFromGDB(listBinaryFileNames)
if __name__ == "__main__":
# listISCFileNames = []
# listObjdumpFileNames = []
# app = QtGui.QApplication(sys.argv)
logging.basicConfig(level=logging.DEBUG)
optparser = OptionParser()
optparser.add_option("-i", "--isc", action="append", dest="listISCFileNames",
type="string", help="ISC Filename. For multiple files, use -i <filename> multiple times.",
metavar="FILE")
optparser.add_option("-o", "--objdump", action="append",
type="string", dest="listObjdumpFileNames",
help="Objdump Filename. For multiple files, use -o <filename> multiple times.",
metavar="FILE")
optparser.add_option("-b", "--binary", action="append",
type="string", dest="listBinaryFileNames",
help="Binary Filename. For multiple files, use -b <filename> multiple times.",
metavar="FILE")
(options, args) = optparser.parse_args()
if (len(args) > 0):
print "Additional arguments are being ignored"
listISCFileNames = options.listISCFileNames
listObjdumpFileNames = options.listObjdumpFileNames
listBinaryFileNames = options.listBinaryFileNames
# (listISCFunctions, listObjdumpFunctions) = map_cfg(listISCFileNames,
# listObjdumpFileNames,
# listBinaryFileNames)
getGlobalVariablesInfoFromGDB(listBinaryFileNames)
# instrument_cache(listISCFileNames, listISCFunctions,
# listObjdumpFileNames, listObjdumpFunctions,
# listBinaryFileNames)
#
\ No newline at end of file
......@@ -189,10 +189,14 @@ class ControlFlowGraph:
self.listBlocks[currBlockIndex].flow = currBlockFlow
class FunctionDesc:
def __init__(self, functionName, fileName, startLine, endLine, cfg):
def __init__(self, functionName, fileName, startLine, endLine, cfg, stackSize = -1):
self.functionName = functionName
self.fileName = fileName
self.startLine = startLine
self.endLine = endLine
self.cfg = cfg
self.stackSize = stackSize
def setStackSize(self, stackSize):
self.stackSize = stackSize
\ No newline at end of file
......@@ -6,6 +6,8 @@ import sys
import re
from cfg import *
sizeOfRegisters = 4
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*(.*)')
......@@ -13,6 +15,8 @@ re_branchInst = re.compile('\s*(b(?!ic)(?:l|x|lx|xj)?(?:eq|ne|cs|hs|lo|cc|mi|pl|
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|cs|hs|lo|cc|mi|pl|hi|ls|ge|lt|gt|le))\s*([0-9a-f]*)\s*<(.*)>')
re_returnInst = re.compile('\s*(bx)\s*(lr)')
re_stackPointerSubInst = re.compile("\s*sub\s*sp, sp, #([0-9]*)\s*.*")
re_pushInst = re.compile("\s*push\s*\{((?:\w*,\s)*\w*)\}")
listFunctionsIgnore = ['__cs3_interrupt_vector',
'__cs3_reset',
......@@ -48,6 +52,7 @@ def parse_binary(fileName, listFunctionNames = []):
inFuncBody = 0 # is 1, when inside Function Body
currFuncName = ""
currFuncFileName = ""
currFuncStackSize = 0
currFuncStartLine = 0
listCurrFuncBlockStartLineNum = []
listCurrFuncBlockEndLineNum = []
......@@ -103,6 +108,7 @@ def parse_binary(fileName, listFunctionNames = []):
m.group(2) not in listFunctionsIgnore)):
inFuncBody = 1
currFuncName = m.group(2)
currFuncStackSize = 0
currFuncFileName = fileName
currFuncStartLine = lineNum + 1
listCurrFuncBlockStartLineNum.append(currFuncStartLine)
......@@ -116,6 +122,24 @@ def parse_binary(fileName, listFunctionNames = []):
opcode = m.group(2)
inst = m.group(3)
# Look for sub instruction on sp (stack pointer) to find the
# stack size for the current function.
# Sometimes, the sub instruction on sp occurs multiple
# times. To incorporate such corner cases, increment the
# currFuncStackSize variable each time.
m = re_stackPointerSubInst.match(inst)
if m is not None:
stackSize = int(m.group(1))
currFuncStackSize = currFuncStackSize + stackSize
# Look for push instruction inside function, to add to the
# stack size of the function.
m = re_pushInst.match(inst)
if m is not None:
pushInstOperand = m.group(1)
numRegistersPushed = pushInstOperand.count(',') + 1
currFuncStackSize = currFuncStackSize + numRegistersPushed * sizeOfRegisters
m = re_branchInst.match(inst)
if m is not None and m.group(3).startswith(currFuncName):
# Branch Instruction
......@@ -251,11 +275,13 @@ def parse_binary(fileName, listFunctionNames = []):
currFuncStartLine,
currFuncEndLine,
ControlFlowGraph(listBlocks,
listEdges)))
listEdges),
currFuncStackSize))
# reset the state management variables
currFuncName = ""
currFuncFileName = ""
currFuncStackSize = 0
currFuncStartLine = 0
currFuncEndLine = 0
listCurrFuncBlockStartLineNum = []
......
......@@ -329,12 +329,13 @@ def draw_cfg(cfg, isISC, v):
continue
else:
# 4.c. Successor has not yet been plotted
predBlocks = cfg.predecessorBlocksWOBackEdges(succBlock)
predBlocks = cfg.predecessorBlocks(succBlock)
if len(predBlocks) > 1:
posSuccBlockX = 0
posSuccBlockY = 0
for predBlock in predBlocks:
if predBlock in posOfBlock:
posSuccBlockX = pos[posOfBlock[predBlock]][0] + posSuccBlockX
if posSuccBlockY > pos[posOfBlock[predBlock]][1] - verticalGap:
posSuccBlockY = pos[posOfBlock[predBlock]][1] - verticalGap
......
import sys
class GlobalVariable:
def __init__(self):
self.name = ""
self.address = 0
self.type = ""
self.length = -1
self.file = ""
self.lineNum = -1
def __init__(self, name, type, length, file):
self.name = name
self.address = -1
self.type = type
self.length = length
self.file = file
self.lineNum = -1
def setAddress(self, address):
self.address = address
\ No newline at end of file
This diff is collapsed.
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