Commit bf148626 authored by Gaurav Kukreja's avatar Gaurav Kukreja

Fixes to Grammar.py * Removing unneeded files *

Signed-off-by: Gaurav Kukreja's avatarGaurav Kukreja <gaurav@gauravk.in>
parent 74c3f39c
...@@ -35,6 +35,8 @@ LE_OP = Literal("<=") ...@@ -35,6 +35,8 @@ LE_OP = Literal("<=")
RIGHT_OP = Literal(">>") RIGHT_OP = Literal(">>")
LEFT_OP = Literal("<<") LEFT_OP = Literal("<<")
PTR_OP = Literal("->")
POINTER = Literal("*") POINTER = Literal("*")
SEMICOLON = Literal(";") SEMICOLON = Literal(";")
SIZEOF = Literal("sizeof") SIZEOF = Literal("sizeof")
...@@ -237,9 +239,13 @@ def act_array_index_lbrace(tokens): ...@@ -237,9 +239,13 @@ def act_array_index_lbrace(tokens):
# TODO : Previous variable name was already annotated, assuming its a variable access. Delete the last entry in the list of annotations. # TODO : Previous variable name was already annotated, assuming its a variable access. Delete the last entry in the list of annotations.
del(list_annotations[-1]) del(list_annotations[-1])
# TODO : Check if PTR_OP and Literal(".") must be handled more carefully
# Removing Left Recursion # Removing Left Recursion
postfix_expression_1 = Forward() postfix_expression_1 = Forward()
postfix_expression_1 << ( (Literal("[").setParseAction(act_array_index_lbrace) + Combine(expression).setParseAction(act_array_index_expression) + Literal("]").setParseAction(act_array_index_rbrace)) postfix_expression_1 << ( (Literal("[").setParseAction(act_array_index_lbrace) + Combine(expression).setParseAction(act_array_index_expression) + Literal("]").setParseAction(act_array_index_rbrace))
| (PTR_OP + IDENTIFIER + postfix_expression_1)
| (Literal(".") + IDENTIFIER + postfix_expression_1)
| Empty() | Empty()
) )
postfix_expression = ( (primary_expression) + postfix_expression_1) postfix_expression = ( (primary_expression) + postfix_expression_1)
...@@ -301,7 +307,7 @@ shift_expression_1 << ( (LEFT_OP + additive_expression + shift_expression_1) ...@@ -301,7 +307,7 @@ shift_expression_1 << ( (LEFT_OP + additive_expression + shift_expression_1)
shift_expression = ( (additive_expression + shift_expression_1) ) shift_expression = ( (additive_expression + shift_expression_1) )
relational_expression_1 = Forward() relational_expression_1 = Forward()
relational_expression_1 << ( (LT_OP + shift_expression + relational_expression_1) relational_expression_1 << ( (GT_OP + shift_expression + relational_expression_1)
| (LT_OP + shift_expression + relational_expression_1) | (LT_OP + shift_expression + relational_expression_1)
| (GE_OP + shift_expression + relational_expression_1) | (GE_OP + shift_expression + relational_expression_1)
| (LE_OP + shift_expression + relational_expression_1) | (LE_OP + shift_expression + relational_expression_1)
...@@ -354,7 +360,7 @@ logical_or_expression = ( (logical_and_expression + logical_or_expression_1) ) ...@@ -354,7 +360,7 @@ logical_or_expression = ( (logical_and_expression + logical_or_expression_1) )
conditional_expression = Forward() conditional_expression = Forward()
conditional_expression << ( (logical_or_expression + Literal("?") + expression + Literal(":") + conditional_expression) conditional_expression << ( (logical_or_expression + Literal("?") + expression + Literal(":") + conditional_expression)
| (logical_or_expression) ^ (logical_or_expression)
) )
def act_assign_op(tokens): def act_assign_op(tokens):
...@@ -367,7 +373,7 @@ def act_assign_op(tokens): ...@@ -367,7 +373,7 @@ def act_assign_op(tokens):
assignment_expression = Forward() assignment_expression = Forward()
assignment_expression << ( ((unary_expression) + ASSIGN_OP.setParseAction(act_assign_op) + (assignment_expression)) assignment_expression << ( ((unary_expression) + ASSIGN_OP.setParseAction(act_assign_op) + (assignment_expression))
| (conditional_expression) ^ (conditional_expression)
) )
expression << ( assignment_expression ) expression << ( assignment_expression )
...@@ -408,8 +414,6 @@ def parse_statement(line): ...@@ -408,8 +414,6 @@ def parse_statement(line):
list_identifiers = [] list_identifiers = []
list_annotations = [] list_annotations = []
print assign_operator_seen
r = statement.parseString(line) r = statement.parseString(line)
return list_annotations return list_annotations
...@@ -421,6 +425,9 @@ def test(): ...@@ -421,6 +425,9 @@ def test():
, "diff = (int) *(short int *)((uintptr_t)indata + (uintptr_t)ivtmp_28) - valpred;" , "diff = (int) *(short int *)((uintptr_t)indata + (uintptr_t)ivtmp_28) - valpred;"
, "*outp = (signed char) (signed char) outputbuffer;" , "*outp = (signed char) (signed char) outputbuffer;"
, "*(outp + i) = (signed char) (signed char) outputbuffer;" , "*(outp + i) = (signed char) (signed char) outputbuffer;"
, "valpred = state->valprev;"
, "valpred = state.valprev;"
, "valpred_41 = (valpred_34 > -32768) ? valpred_35 : -32768;"
] ]
expected_annotations = [[("start", "simDCache((start_addr), 0);" ), expected_annotations = [[("start", "simDCache((start_addr), 0);" ),
...@@ -434,8 +441,6 @@ def test(): ...@@ -434,8 +441,6 @@ def test():
], ],
[("diff", "simDCache((diff_addr), 0);"), [("diff", "simDCache((diff_addr), 0);"),
("indata", "simDCache((indata_addr+ivtmp_28), 1);"), ("indata", "simDCache((indata_addr+ivtmp_28), 1);"),
("indata", "simDCache((indata_addr), 1);"),
("ivtmp_28", "simDCache((ivtmp_28_addr), 1);"),
("valpred", "simDCache((valpred_addr), 1);") ("valpred", "simDCache((valpred_addr), 1);")
], ],
[("outp", "simDCache((outp_addr), 0);"), [("outp", "simDCache((outp_addr), 0);"),
...@@ -443,6 +448,18 @@ def test(): ...@@ -443,6 +448,18 @@ def test():
], ],
[("outp", "simDCache((outp_addr+i), 0);"), [("outp", "simDCache((outp_addr+i), 0);"),
("outputbuffer", "simDCache((outputbuffer_addr), 1);") ("outputbuffer", "simDCache((outputbuffer_addr), 1);")
],
[("valpred", "simDCache((valpred_addr), 0);"),
("state", "simDCache((state_addr), 1);"),
("valprev", "simDCache((valprev_addr), 1);")
],
[("valpred", "simDCache((valpred_addr), 0);"),
("state", "simDCache((state_addr), 1);"),
("valprev", "simDCache((valprev_addr), 1);")
],
[("valpred_41", "simDCache((valpred_41_addr), 0);"),
("valpred_34", "simDCache((valpred_34_addr), 1);"),
("valpred_35", "simDCache((valpred_35_addr), 1);")
] ]
] ]
......
from pyparsing import *
from _ast import For
IDENTIFIER = Word(alphas, alphanums+'_')
CONSTANT = Word(nums+'.')
STRING = quotedString
SIZEOF = "sizeof"
PTR_OP = Literal("->")
INC_OP = Literal("++")
DEC_OP = Literal("--")
LEFT_OP = Literal("<<")
RIGHT_OP = Literal(">>")
LE_OP = Literal("<=")
GE_OP = Literal(">=")
EQ_OP = Literal("==")
NE_OP = Literal("!=")
AND_OP = Literal("&&")
OR_OP = Literal("||")
MUL_ASSIGN = Literal("*=")
DIV_ASSIGN = Literal("/=")
MOD_ASSIGN = Literal("%=")
ADD_ASSIGN = Literal("+=")
SUB_ASSIGN = Literal("-=")
LEFT_ASSIGN = Literal("<<=")
RIGHT_ASSIGN = Literal(">>=")
AND_ASSIGN = Literal("&=")
XOR_ASSIGN = Literal("^=")
OR_ASSIGN = Literal("|=")
# TODO: TYPE_NAME
TYPEDEF = Literal("typedef")
EXTERN = Literal("extern")
STATIC = Literal("static")
AUTO = Literal("auto")
REGISTER = Literal("register")
CHAR = Literal("char")
SHORT = Literal("short")
INT = Literal("int")
LONG = Literal("long")
SIGNED = Literal("signed")
UNSIGNED = Literal("unsigned")
FLOAT = Literal("float")
DOUBLE= "double"
CONST = Literal("const")
VOLATILE = Literal("volatile")
VOID = Literal("void")
STRUCT = Literal("struct")
UNION = Literal("union")
ENUM = Literal("enum")
ELLIPSIS = Literal("...")
CASE = Literal("case")
DEFAULT = Literal("default")
IF = Literal("if")
ELSE = Literal("else")
SWITCH = Literal("switch")
WHILE = Literal("while")
DO = Literal("do")
FOR = Literal("for")
GOTO = Literal("goto")
CONTINUE = Literal("continue")
BREAK = Literal("break")
RETURN = Literal("return")
# TODO: Start Translation Unit
postfix_expression = Forward()
unary_expression = Forward()
cast_expression = Forward()
multiplicative_expression = Forward()
additive_expression = Forward()
shift_expression = Forward()
relational_expression = Forward()
equality_expression = Forward()
and_expression = Forward()
exclusive_or_expression = Forward()
logical_and_expression = Forward()
logical_or_expression = Forward()
conditional_expression = Forward()
assignment_expression = Forward()
expression = Forward()
declaration_specifiers = Forward()
init_declarator_list = Forward()
struct_declaration_list = Forward()
specifier_qualifier_list = Forward()
struct_declarator_list = Forward()
enumerator_list = Forward()
direct_declarator = Forward()
pointer = Forward()
type_qualifier_list = Forward()
parameter_type_list = Forward()
parameter_list = Forward()
identifier_list = Forward()
direct_abstract_declarator = Forward()
initializer_list = Forward()
declaration_list = Forward()
statement_list = Forward()
translation_unit = Forward()
primary_expression = Forward()
argument_expression_list = Forward()
unary_operator = Forward()
assignment_operator = Forward()
constant_expression = Forward()
declaration = Forward()
init_declarator = Forward()
storage_class_specifier = Forward()
type_specifier = Forward()
struct_or_union_specifier = Forward()
struct_or_union = Forward()
struct_declaration = Forward()
struct_declarator = Forward()
enum_specifier = Forward()
enumerator = Forward()
type_qualifier = Forward()
declarator = Forward()
parameter_declaration = Forward()
type_name = Forward()
abstract_declarator = Forward()
initializer = Forward()
statement = Forward()
labeled_statement = Forward()
compound_statement = Forward()
expression_statement = Forward()
selection_statement = Forward()
iteration_statement = Forward()
jump_statement = Forward()
external_declaration = Forward()
function_definition = Forward()
inclusive_or_expression = Forward()
primary_expression << ( IDENTIFIER
| CONSTANT
| STRING
| ('(' + expression + ')')
)
postfix_expression<< ( primary_expression
| (postfix_expression + '[' + expression + ']')
| (postfix_expression + '(' + ')')
| (postfix_expression + '(' + argument_expression_list + ')')
| (postfix_expression + '.' + IDENTIFIER)
| (postfix_expression + PTR_OP + IDENTIFIER)
| (postfix_expression + INC_OP)
| (postfix_expression + DEC_OP)
)
argument_expression_list << ( assignment_expression
| (argument_expression_list + ',' + assignment_expression)
)
unary_expression << ( postfix_expression
| (INC_OP + unary_expression)
| (DEC_OP + unary_expression)
| (unary_operator + cast_expression)
| (SIZEOF + unary_expression)
| (SIZEOF + '(' + type_name + ')')
)
unary_operator << oneOf("& * + - ~ !")
cast_expression << ( unary_expression
| ('(' + type_name + ')' + cast_expression)
)
multiplicative_expression << ( cast_expression
| (multiplicative_expression + '*' + cast_expression)
| (multiplicative_expression + '/' + cast_expression)
| (multiplicative_expression + '%' + cast_expression)
)
additive_expression << ( multiplicative_expression
| (additive_expression + '+' + multiplicative_expression)
| (additive_expression + '-' + multiplicative_expression)
)
shift_expression << ( additive_expression
| (shift_expression + LEFT_OP + additive_expression)
| (shift_expression + RIGHT_OP + additive_expression)
)
relational_expression << ( shift_expression
| (relational_expression + '<' + shift_expression)
| (relational_expression + '>' + shift_expression)
| (relational_expression + LE_OP + shift_expression)
| (relational_expression + GE_OP + shift_expression)
)
equality_expression << ( relational_expression
| (equality_expression + EQ_OP + relational_expression)
| (equality_expression + NE_OP + relational_expression)
)
and_expression << ( equality_expression
| (and_expression + '&' + equality_expression)
)
exclusive_or_expression <<( and_expression
| (exclusive_or_expression + '^' + and_expression)
)
logical_and_expression << ( inclusive_or_expression
| (logical_and_expression + AND_OP + inclusive_or_expression)
)
logical_or_expression << ( logical_and_expression
| (logical_or_expression + OR_OP + logical_and_expression)
)
conditional_expression << ( logical_or_expression
| (logical_or_expression + '?' + expression + ':' + conditional_expression)
)
assignment_expression << ( conditional_expression
| (unary_expression + assignment_operator + assignment_expression)
)
assignment_operator << ( '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
)
expression << ( assignment_expression
| (expression + ',' + assignment_expression)
)
constant_expression << conditional_expression
# declaration << ( (declaration_specifiers + ';')
# | (declaration_specifiers + init_declarator_list + ';')
# )
#
# declaration_specifiers << ( storage_class_specifier
# | (storage_class_specifier + declaration_specifiers)
# | type_specifier
# | (type_specifier + declaration_specifiers)
# | type_qualifier
# | (type_qualifier + declaration_specifiers)
# )
#
# init_declarator_list << ( init_declarator
# | (init_declarator_list + ',' + init_declarator)
# )
#
# init_declarator << ( declarator
# | (declarator + '=' + initializer)
# )
storage_class_specifier << ( TYPEDEF
| EXTERN
| STATIC
| AUTO
| REGISTER
)
type_specifier << ( VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
| struct_or_union_specifier
| enum_specifier
| type_name
)
struct_or_union_specifier << ( (struct_or_union + IDENTIFIER + '{' + struct_declaration_list + '}')
| (struct_or_union + '{' + struct_declaration_list + '}')
| (struct_or_union + IDENTIFIER)
)
struct_or_union << ( STRUCT
| UNION
)
# struct_declaration_list << ( struct_declaration
# | (struct_declaration_list + struct_declaration)
# )
#
# struct_declaration << specifier_qualifier_list + struct_declarator_list + ';'
specifier_qualifier_list << ( (type_specifier + specifier_qualifier_list)
| type_specifier
| (type_qualifier + specifier_qualifier_list)
| (type_qualifier)
)
# struct_declarator_list << ( struct_declarator
# | (struct_declarator_list + ',' + struct_declarator)
# )
#
# struct_declarator << ( declarator
# | (':' + constant_expression)
# | (declarator + ':' + constant_expression)
# )
#
# enum_specifier << ( (ENUM + '{' + enumerator_list + '}')
# | (ENUM + IDENTIFIER + '{' + enumerator_list + '}')
# | (ENUM + IDENTIFIER)
# )
#
# enumerator_list << ( enumerator
# | (enumerator_list + ',' + enumerator)
# )
#
# enumerator << ( IDENTIFIER
# | (IDENTIFIER + '=' + constant_expression)
# )
type_qualifier << ( CONST
| VOLATILE
)
# declarator << ( pointer + direct_declarator
# | direct_declarator
# )
#
# direct_declarator << ( IDENTIFIER
# | ('(' + declarator + ')')
# | (direct_declarator + '[' + constant_expression + ']')
# | (direct_declarator + '[' + ']')
# | (direct_declarator + '(' + parameter_type_list + ')')
# | (direct_declarator + '(' + identifier_list + ')')
# | (direct_declarator + '(' + ')')
# )
pointer << ( '*'
| ('*' + type_qualifier_list)
| ('*' + pointer)
| ('*' + type_qualifier_list + pointer)
)
type_qualifier_list << ( type_qualifier
| (type_qualifier_list + type_qualifier)
)
# parameter_type_list << ( parameter_list
# | (parameter_list + ',' + ELLIPSIS)
# )
#
# parameter_list << ( parameter_declaration
# | (parameter_list + ',' + parameter_declaration)
# )
#
# parameter_declaration << ( (declaration_specifiers + declarator)
# | (declaration_specifiers + abstract_declarator)
# | (declaration_specifiers)
# )
# identifier_list << ( IDENTIFIER
# | (identifier_list + ',' + IDENTIFIER)
# )
type_name << ( specifier_qualifier_list
# | (specifier_qualifier_list + abstract_declarator)
)
# abstract_declarator << ( pointer
# | direct_abstract_declarator
# | (pointer + direct_abstract_declarator)
# )
#
# direct_abstract_declarator << ( ('(' + abstract_declarator + ')')
# | ('[' + ']')
# | ('[' + constant_expression + ']')
# | (direct_abstract_declarator + '[' + ']')
# | (direct_abstract_declarator + '[' + constant_expression + ']')
# | ('(' + ')')
# | ('(' + parameter_type_list + ')')
# | (direct_abstract_declarator + '(' + ')')
# | (direct_abstract_declarator + '(' + parameter_type_list + ')')
# )
# initializer << ( assignment_expression
# | ('{' + initializer_list + '}')
# | ('{' + initializer_list + ',' + '}')
# )
#
# initializer_list << ( initializer
# | (initializer_list + ',' + initializer)
# )
#
# statement << ( labeled_statement
# | compound_statement
# | expression_statement
# | selection_statement
# | iteration_statement
# | jump_statement
# )
#
# labeled_statement << ( (IDENTIFIER + ':' + statement)
# | (CASE + constant_expression + ':' + statement)
# | (DEFAULT + ':' + statement)
# )
#
# compound_statement << ( ('{' + '}')
# | ('{' + statement_list + '}')
# | ('{' + declaration_list + '}')
# | ('{' + declaration_list + statement_list + '}')
# )
#
# declaration_list << ( declaration
# | (declaration_list + declaration)
# )
#
# statement_list << ( statement
# | (statement_list + statement)
# )
expression_statement << ( ';'
| (expression + ';')
)
# selection_statement << ( (IF + '(' + expression + ')' + statement)
# | (IF + '(' + expression + ')' + statement + ELSE + statement)
# | (SWITCH + '(' + expression + ')' + statement)
# )
#
# iteration_statement << ( (WHILE + '(' + expression + ')' + statement)
# | (DO + statement + WHILE + '(' + expression + ')' + ';')
# | (FOR + '(' + expression_statement + expression_statement + ')' + statement)
# | (FOR + '(' + expression_statement + expression_statement + expression + ')' + statement)
# )
#
# jump_statement << ( (GOTO + IDENTIFIER + ';')
# | (CONTINUE + ';')
# | (BREAK + ';')
# | (RETURN + ';')
# | (RETURN + expression + ';')
# )
#
# translation_unit << ( external_declaration
# | (translation_unit + external_declaration)
# )
#
# external_declaration << ( function_definition
# | declaration
# )
#
# function_definition << ( (declaration_specifiers + declarator + declaration_list + compound_statement)
# | (declaration_specifiers + declarator + compound_statement)
# | (declarator + declaration_list + compound_statement)
# | (declarator + compound_statement)
# )
if __name__ == "__main__":
str = "a = b"
# print expression
r = assignment_expression.parseString(str)
print r
\ No newline at end of file
import sys
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
from collections import deque
import math
from cfg import *
unmappedColor = "000000"
mappedColors = ["CC4733",
"BF6600",
"4C5943",
"B6EEF2",
"0000B3",
"8273E6",
"592D44",
"E6B4AC",
"FFAA00",
"1D331A",
"00C2F2",
"000099",
"9900E6",
"FF0044",
"401D10",
"593C00",
"00731F",
"0D2B33",
"00008C",
"75468C",
"4C0014",
"FFA280",
"B2A700",
"40FF73",
"004D73",
"000080",
"FF40F2",
"994D57",
"4D3E39",
"6D731D",
"30BF7C",
"368DD9",
"000066",
"CC99C2",
"FF6600",
"BCBF8F",
"008C83",
"003380",
"101040",
"FF80D5",
"FFD9BF",
"B6F23D",
"3DF2E6",
"737899",
"BFBFFF",
"E5007A"]
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 clicked(self, pts):
print("clicked: %s" % pts)
verticalGap = 6
horizontalGap = 16
def display_cfgs(app, cfgISC, cfgObj, 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, brushes) = draw_cfg(cfg=cfgISC, isISC=1, v=v1)
g1.setData(pos=pos, adj=adj, size=1, pxMode=False, text=texts,
symbol=symbols, brush=brushes)
v2 = w.addViewBox()
v2.setAspectLocked()
g2 = Graph()
v2.addItem(g2)
(pos, adj, texts, symbols, brushes) = draw_cfg(cfg=cfgObj, isISC=0, v=v2)
g2.setData(pos=pos, adj=adj, size=1, pxMode=False, text=texts,
symbol=symbols, brush=brushes)
app.exec_();
def mk_arrow(pos, adj):
i = len(adj) - 1
x1 = pos[adj[i][0]][0]
y1 = pos[adj[i][0]][1]
x2 = pos[adj[i][1]][0]
y2 = pos[adj[i][1]][1]
if (x2-x1) != 0:
angle = math.degrees(math.atan(float((y1-y2))/float((x2-x1))))
else:
if y1 > y2:
angle = 270
else:
angle = 90
if x1 < x2:
angle = angle + 180
arrow = pg.ArrowItem(angle=angle, headLen=17)
arrow.setPos((x1+x2)/2, (y1+y2)/2)
return arrow
def mk_edge(adj, startBlockInd, endBlockInd, posOfBlock):
if adj == None:
adj = np.array([[posOfBlock[startBlockInd], posOfBlock[endBlockInd]]])
else:
adj = np.insert(adj, len(adj),
[posOfBlock[startBlockInd], posOfBlock[endBlockInd]],
axis = 0)
return adj
def mk_brush(brushes, cfg, blockInd, isISC):
if cfg.listBlocks[blockInd].mapsTo:
if isISC == 1:
brushes.append(pg.mkBrush(mappedColors[cfg.listBlocks[blockInd].mapsTo[0]]))
else:
brushes.append(pg.mkBrush(mappedColors[blockInd]))
else:
brushes.append(pg.mkBrush(unmappedColor))
def mk_symbol(symbols, cfg, blockInd):
if cfg.listBlocks[blockInd].isReturning == 1:
symbols.append('x')
else:
symbols.append('o')
ellipseRadius = 1
def mk_selfEdge(pos, blockInd, posOfBlock, v):
posBlock = pos[posOfBlock[blockInd]]
cx = posBlock[0]
cy = posBlock[1]
selfEdge = pg.CircleROI([cx, cy-ellipseRadius],
[2*ellipseRadius, 2*ellipseRadius],
movable=False)
listHandles = selfEdge.getHandles()
v.addItem(selfEdge)
pg.CircleROI.removeHandle(selfEdge, listHandles[0])
def draw_cfg(cfg, isISC, v):
logging.debug ("Inside Function draw_cfg()")
'''
Breadth first search for all blocks in the Control Flow Graph to print them
on screen.
'''
posOfBlock = {}
brushes = []
texts=[]
posOfBlock[0] = 0
pos = np.array([[0, 0]])
mk_brush(brushes, cfg, 0, isISC)
symbols = ['+']
texts.append(cfg.listBlocks[0].name)
adj = None
# Queue for BFS
q = deque([0])
while q:
'''
Breadth First Traversal of the graph, to generate visualization.
Algorithm:
0. For each node, we add an entry to the 'pos' array for its position.
We add an entry in the 'adj' array for each edge. 'texts' array
contains the text associated with each node ie. the name of the
node. Symbols array is the symbol for each node. The root node has
'+' symbol, and the return node has 'x'. All other nodes have 'o'.
'brushes' array contains the color for each node, which indicates
mapping between the ISC and Objdump graphs.
0.a Global variables 'verticalGap' and 'horizontalGap' are distances
between nodes.
0.b 'posOfBlock' is a dictionary mapping between block index and index
of the block in the 'pos' array.
1. Outside the loop, the starting node (index 0) is already plotted at
(0, 0). The block is then added to the queue of pending blocks 'q'
2. Pop a block index from 'q' in 'blockInd'.
3. If current node has more than one successor, for each successor
a. If it has an edge to itself ie. successor is same as blockInd
TODO
b. If successor is in 'posOfBlock' ie. block has already been plot,
1. create an edge from 'blockInd' to 'succBlock'.
2. create an arrow for the edge.
3. continue to next succBlock
c. else, (if 'succBlock' is not in 'posOfBlock')
1. Find a parent of the block.
2. Compute position of successor block from position of its
parent. Add an entry to the 'pos' array.
3. Add an entry to 'brushes' array for color of the edge.
4. Add an entry to 'texts' array for name of the edge.
5. Add an entry to 'symbols' array for symbol of the edge.
6. Create an edge from 'blockInd' to 'succBlock'.
7. Create an arrow for the edge.
8. Add 'succBlock' to 'q', if not already present.
9. continue to next successor block.
4. else if, current node has only one successor.
-> Only one successor should not generally be a self edge, so
so ignoring check.
a. If 'succBlock' is in 'posOfBlock'
1. Create an edge from 'blockInd' to 'succBlock'.
2. Create an arrow for the edge.
3. continue to next entry in the queue of pending nodes.
b. else, if 'succBlock' not in 'posOfBlock'
1. Find position for succBlock,
a. if succBlock has more than one predessors (parents), the
position of the block will be between the parents.
b. If it has only one parent, the position will be directly
below the parent.
2. Add entry to 'pos' array for position of successor block.
3. Add entry to 'brushes' array for color of the block.
4. Add entry to 'texts' array for name of the block.
5. Add entry to 'symbols' array for symbol of the block.
6. Create an edge from 'blockInd' to 'succBlock'
7. Create an arrow for the edge.
8. Add 'succBlock' to 'q' if not already present.
9. continue to next entry in the queue of pending blocks
'''
# Algo 2. Pop next block from the queue
blockInd = q.popleft()
logging.debug ("Block %d" % blockInd)
# Find all children of the blockInd
succBlocks = cfg.successorBlocks(blockInd)
spaceForChildren = (len(succBlocks) - 1) * horizontalGap
logging.debug ("\t has %d children, space = %d" % (len(succBlocks), spaceForChildren))
# Algo 3.
if len(succBlocks) > 1:
# Algo 3. number of successors is more than 1
i = 0 # index for each successor block
for succBlock in succBlocks:
if succBlock == blockInd:
# 3.a. Self Edge
mk_selfEdge(pos, blockInd, posOfBlock, v)
continue
logging.debug ("\t Successor Block %d" % succBlock)
if succBlock in posOfBlock:
# 3.b. Successor has already been plot
logging.debug ("\t\t Already drawn at %d, %d" % (pos[posOfBlock[succBlock]][0], pos[posOfBlock[succBlock]][1]))
adj = mk_edge(adj, blockInd, succBlock, posOfBlock)
arrow = mk_arrow(pos, adj)
v.addItem(arrow)
continue
else:
# 3.c. Successor has not yet been plotted
parent = None
for predBlock in cfg.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)
mk_brush(brushes, cfg, succBlock, isISC)
texts.append("%s" % cfg.listBlocks[succBlock].name)
mk_symbol(symbols, cfg, succBlock)
adj = mk_edge(adj, blockInd, succBlock, posOfBlock)
arrow = mk_arrow(pos, adj)
v.addItem(arrow)
logging.debug ("\t\t Drawn at %d, %d" % (posSuccBlock[0], posSuccBlock[1]))
if succBlock not in q:
q.append(succBlock)
i = i + 1
continue
# 4. Only one successor
elif len(succBlocks) == 1:
succBlock = succBlocks[0]
logging.debug ("\t Successor Block %d" % succBlock)
if succBlock in posOfBlock:
# 4.a. Successor has already been plotted
logging.debug ("\t\t Already drawn at %d, %d" % (pos[posOfBlock[succBlock]][0], pos[posOfBlock[succBlock]][1]))
adj = mk_edge(adj, blockInd, succBlock, posOfBlock)
arrow = mk_arrow(pos, adj)
v.addItem(arrow)
continue
else:
# 4.c. Successor has not yet been plotted
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
posSuccBlockX = posSuccBlockX / len(predBlocks)
posSuccBlock = [posSuccBlockX, posSuccBlockY]
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)
mk_brush(brushes, cfg, succBlock, isISC)
adj = mk_edge(adj, blockInd, succBlock, posOfBlock)
arrow = mk_arrow(pos, adj)
v.addItem(arrow)
logging.debug ("\t\t Drawn at %d, %d" % (posSuccBlock[0], posSuccBlock[1]))
texts.append("%s" % cfg.listBlocks[succBlock].name)
mk_symbol(symbols, cfg, succBlock)
if succBlock not in q:
q.append(succBlock)
else:
continue
if adj==None:
adj = np.array([[0, 0]])
return pos, adj, texts, symbols, brushes
\ No newline at end of file
from pyparsing import *
Ident = Word(alphas, alphanums+'_')
Num = Word(nums+'.')
String = quotedString
MUL_ASSIGN = "*"
DIV_ASSIGN = "/"
MOD_ASSIGN = "%"
ADD_ASSIGN = "+"
SUB_ASSIGN = "-"
LEFT_ASSIGN = "<<="
RIGHT_ASSIGN = ">>="
AND_ASSIGN = "&="
XOR_ASSIGN ="^="
OR_ASSIGN = "|="
IncOp = "++"
DecOp = "--"
LPAREN = Suppress("(")
RPAREN = Suppress(")")
UnaryOp = ( "&" |
"*" |
"+" |
"-" |
"~" |
"!"
)
Sizeof = "sizeof"
StructUnion = ( "struct" |
"union" )
StructDeclList = Forward()
StructDeclList << ( (StructDecl) |
(StructDeclList + StructDecl)
)
StructDecl = ( SpecifierQualifierList + StructDeclaratorList + ';' )
StructDeclaratorList = Forward()
StructUnionSpecifier = ( (StructUnion + Ident + '{' + StructDeclList + '}') |
(StructUnion + '{' + StructDeclList + '}') |
(StructUnion + Ident)
)
TypeSpecifier = ( "void" |
"char" |
"short" |
"int" |
"long" |
"float" |
"double" |
"signed" |
"unsigned" |
StructUnionSpecifier |
EnumSpecifier |
TypeName
)
SpecifierQualifierList = Forward()
SpecifierQualifierList << ( TypeSpecifier + SpecifierQualifierList |
TypeSpecifier |
TypeQualifier + SpecifierQualifierList |
TypeQualifier
)
TypeName = ( SpecifierQualifierList |
(SpecifierQualifierList + AbstractDeclarator)
)
CastExpression = ( UnaryExpression |
(LPAREN + TypeName + RPAREN + CastExpression)
)
UnaryExpression = Forward()
UnaryExpression << (PostExpression |
(IncOp + UnaryExpression) |
(DecOp + UnaryExpression) |
(UnaryOp + CastExpresssion) |
(Sizeof + UnaryExpression) |
(Sizeof + LPAREN + TypeName + RParen)
)
AssignOperator = ( '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
)
AssignExpression = Forward()
AssignExpression << ( CondExpression |
(UnaryExpression + AssignOperator + AssignExpression)
)
Expression = Forward()
Expression << ( AssignExpression |
(Expression + ',' + AssignExpression)
)
PrimExpression = ( Ident |
Num |
String |
(LPAREN + Expression + RPAREN )
)
PostExpression = Forward()
PostExpression << ( PrimExpression |
)
if __name__ == "__main__":
str_varDecl = "unsigned short int a;"
\ No newline at end of file
#-----------------------------------------------------------------
# map_cfg.py: Map Control Flow Graphs from Binary and ISC
#-----------------------------------------------------------------
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
######################################################
## Global Variables
######################################################
COND_EXEC_BLOCKLEN_THRESH = 4
app = None
# listISCFileNames = []
# listObjdumpFileNames = []
# listBinaryFileNames = []
class GDBMapTarget:
def __init__(self, fileName, lineNum):
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))
print "\t Stack Size = %d" % func.stackSize
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
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:
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 = {}
re_gdbInfoLineOutput = re.compile('Line (\d*) of "(.*)" starts at address 0x([0-9a-f]*).*')
# File Name for GDB Command file
gdbXFileName = binFileName+".gdbx"
gdbXFile = open(gdbXFileName, 'w')
for address in objdumpLineNumForAddress:
line = "info line *0x%x\n" % (int(address, 16))
gdbXFile.write(line)
gdbXFile.write("quit\n")
gdbXFile.close()
gdbOutputFileName = binFileName+".gdbo"
gdbOutputFile = open(gdbOutputFileName, 'w')
call(args=["gdb", "--quiet", "--command="+gdbXFileName, binFileName],
stdout=gdbOutputFile)
gdbOutputFile.close()
gdbOutputFile = open(gdbOutputFileName, 'r')
for line in gdbOutputFile:
m = re_gdbInfoLineOutput.match(line)
if m is not None:
targetLineNum = int(m.group(1), 10)
targetFileName = m.group(2)
objdumpAddress = m.group(3)
objdumpLineNum = objdumpLineNumForAddress[objdumpAddress]
gdbMapping[objdumpLineNum] = GDBMapTarget(targetFileName, targetLineNum)
gdbOutputFile.close()
# gdbMappingDebug(gdbMapping)
return gdbMapping
mappingStackISC = []
mappingStackObj = []
def mapping(cfgISC, blockIndISC, cfgObj, blockIndObj, mergedLevelsISC, gdbMapping):
# raw_input("Press any key to continue ...")
'''
Recursinve Function to trace the Control Flow Graphs in Depth First Fashion
in order to match the corresponding blocks
Algorithm:
1. The recursive function is first called for the root block of ISC and
Objdump. The current node index is stored in blockIndISC and blockIndObj.
2. mappingStackISC and mappingStackObj are stacks to maintain the control
flow for each branch in ISC and Objdump. The current node index is added
to the stack.
3. Here after each situation is carefully handled.
a. Both blocks return.
1. If both blocks are returning, we assume the blocks match as there
should be only one returning block in each.
2. We add the index of ISC block to mapsTo array in the Objdump
block, and vice-a-versa.
3. We pop one entry from the mappingStackISC and mappingStackObjdump
for the matched node.
b. Check if flow, nesting level and isReturning are not same.
1. Either of these being not same means, the blocks don't match.
c. listSuccObj is list of successors of blockIndObj, and similarly
listSuccISC is list of successors of blockIndISC.
d. if length of list of successors without back edges for both
blocks is not same and current obj block has conditional
execution (predication).
1. Calculate the length of the shortest block in the list of
successors. This length should be smaller than the
threshold, for it to be optimal for conditional execution.
If true:
a. case 1: The current ISC block has 2 branches, and one of
the branch merges with the other.
In this case, the the Obj block is matched to the common
child, and all three ISC blocks are matched to the
current Obj block.
b. case 2: the current ISC block has 2 branches, and both
merge with a fourth node.
In this case, the the Obj block is matched to the fourth
node, and all four ISC blocks are matched to the current
Obj block.
-> In each of the case, we call mapping function recursively
on the current obj block and the common child in the
conditional execution construct. The mapping function
checks if corresponding decision is supported by
following nodes in ISC and Objdump CFGs, and returns 0,
only when mapping function returns 0, saying this is
the best match.
-> If neither matches, it means it is either not Conditional
Execution, or it is a corner case.
If false:
a. Issue warning, for corner case that may occur for last
ISC node in the conditional execution construct. In this
case we will proceed to check for the method to match.
e. Coming here means, conditional execution was not found. If length of
list of successors is same, run mapping function for match of the
successor blocks. If mapping succeeds, pop one entry from each stack
for blockIndISC and blockIndObj and return 0.
f. Coming here means no conditional execution, and length of successors
lists is not equal. Refer the the GDB Mapping to match the blocks
now, since nothing else works!
'''
a = raw_input("Press Enter to continue...")
mappingStackISC.append((blockIndISC, [blockIndObj]))
mappingStackObj.append((blockIndObj, [blockIndISC]))
blockISC = cfgISC.listBlocks[blockIndISC]
blockObj = cfgObj.listBlocks[blockIndObj]
logging.debug("")
logging.debug(" Mapping blocks ISC:%s and OBJ:%d" % (blockISC.name, blockIndObj))
logging.debug("\t mergedLevelsISC = %d" % (mergedLevelsISC))
if (blockISC.isReturning == 1 and
blockObj.isReturning == 1):
logging.debug("\t\t Both Blocks return!!!")
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
mappingStackISC.pop()
mappingStackObj.pop()
return 0
listSuccISC = cfgISC.successorBlocks(blockIndISC)
listSuccObj = cfgObj.successorBlocks(blockIndObj)
listSuccWOBackEdgeISC = cfgISC.successorBlocksWOBackEdges(blockIndISC)
listSuccWOBackEdgeObj = cfgObj.successorBlocksWOBackEdges(blockIndObj)
logging.debug("\t Checking if blockISC returns, and successor of blockObj returns!")
if (blockISC.isReturning == 1 and
len(listSuccObj) == 1 and
cfgObj.listBlocks[listSuccObj[0]].isReturning == 1):
logging.debug("\t\t It does!")
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
cfgObj.listBlocks[listSuccObj[0]].mapsTo.append(blockIndISC)
mappingStackISC.pop()
mappingStackObj.pop()
return 0
if (blockISC.flow != blockObj.flow or
blockISC.isReturning != blockObj.isReturning):
logging.debug("\t\t Flow did not match or only one of them returns!")
# logging.debug( "\t\tblockISC.nestingLevel - mergedLevelsISC = %d; blockObj.nestingLevel = %d" % ((blockISC.nestingLevel-mergedLevelsISC), blockObj.nestingLevel))
mappingStackISC.pop()
mappingStackObj.pop()
return -1
# if (blockIndISC, blockIndObj) in mappingDict:
# return mappingDict[(blockIndISC, blockIndObj)]
mincost = -1
logging.debug("\t Checking for Conditional Execution")
if(len(listSuccWOBackEdgeISC) != len(listSuccWOBackEdgeObj)) and blockObj.hasConditionalExec == 1:
minSuccBlockLength = -1
for succBlockISC in listSuccISC:
blockLength = cfgISC.listBlocks[succBlockISC].endLine - cfgISC.listBlocks[succBlockISC].startLine
if blockLength < minSuccBlockLength:
minSuccBlockLength = blockLength
if minSuccBlockLength < COND_EXEC_BLOCKLEN_THRESH:
logging.debug("\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
for succ2BlockISC in list(set(listSuccISC) - {succ1BlockISC}):
if succ2BlockISC in mappingStackISC:
continue
if succSucc1BlockISC == succ2BlockISC:
# case 1
logging.debug("\t\t case 1")
mappingStackISC.append((succ1BlockISC, [blockIndObj]))
blockObjStackEntry = mappingStackObj.pop() # popping blockIndObj, because mapping it again
if mapping(cfgISC, succ2BlockISC, cfgObj, blockIndObj, mergedLevelsISC + 1, gdbMapping) == 0:
cfgISC.listBlocks[blockIndISC].mapsTo.append(blockIndObj)
cfgISC.listBlocks[succ1BlockISC].mapsTo.append(blockIndObj)
cfgISC.listBlocks[succ2BlockISC].mapsTo.append(blockIndObj)
cfgObj.listBlocks[blockIndObj].mapsTo.append(succ2BlockISC)
mappingStackISC.pop()
mappingStackISC.pop()
return 0
else:
mappingStackObj.append(blockObjStackEntry) # Adding what was removed above
# mappingStackISC.append((succ2BlockISC, [blockIndObj])) # was already done above, no need to do again
mappingStackISC.append((succ2BlockISC, [blockIndObj]))
listSuccSucc2BlockISC = cfgISC.successorBlocks(succ2BlockISC)
for succSucc2BlockISC in listSuccSucc2BlockISC:
if succSucc2BlockISC in mappingStackISC:
continue;
for succBlockObj in listSuccObj:
if succBlockObj in mappingStackISC:
continue;
if mapping(cfgISC, succSucc2BlockISC, cfgObj, succBlockObj, mergedLevelsISC+2, gdbMapping) == 0:
cfgISC.listBlocks[blockIndISC].mapsTo.append(blockIndObj)
cfgISC.listBlocks[succ1BlockISC].mapsTo.append(blockIndObj)
cfgISC.listBlocks[succ2BlockISC].mapsTo.append(blockIndObj)
cfgObj.listBlocks[blockIndObj].mapsTo.append(succ2BlockISC)
mappingStackISC.pop() # succ1BlockISC
mappingStackISC.pop() # succ2BlockISC
mappingStackISC.pop() # blockIndISC
mappingStackObj.pop() # blockIndObj
return 0
# Coming here means case 1 could not be successfully mapped
mappingStackISC.pop() # succ1BlockISC
mappingStackISC.pop() # succ2BlockISC
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
logging.debug( "\t\t case 2")
mappingStackISC.append((succ1BlockISC, [blockIndObj]))
mappingStackISC.append((succ2BlockISC, [blockIndObj]))
blockObjStackEntry = mappingStackObj.pop() # popping blockIndObj, because mapping it again
if mapping(cfgISC, succSucc1BlockISC, cfgObj, blockIndObj, mergedLevelsISC+2, gdbMapping) == 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()
return 0
else:
# mappingStackISC.append(succ1BlockISC) # Was already done above, no need twice
# mappingStackISC.append(succ2BlockISC) # Was already done above, no need twice
mappingStackISC.append((succSucc1BlockISC, [blockIndObj]))
mappingStackObj.append(blockObjStackEntry) # was popped above, restoring it
listSuccSuccSucc1BlockISC = cfgISC.successorBlocks(succSucc1BlockISC)
for succSuccSucc1BlockISC in listSuccSuccSucc1BlockISC:
if succSuccSucc1BlockISC in mappingStackISC:
continue
for succBlockObj in listSuccObj:
if succBlockObj in mappingStackISC:
continue;
if mapping(cfgISC, succSuccSucc1BlockISC,
cfgOBJ, succBlockObj,
mergedLevelsISC+3, gdbMapping) == 0:
mappingStackISC.pop() # succ1BlockISC
mappingStackISC.pop() # succ2BlockISC
mappingStackISC.pop() # succSucc1BlockISC
mappingStackISC.pop() # blockIndISC
mappingStackObj.pop() # blockIndObj
return 0
# Coming here means case 2 could not be successfully mapped
mappingStackISC.pop() # succ1BlockISC
mappingStackISC.pop() # succ1BlockISC
mappingStackISC.pop() # succSucc1BlockISC
# Should not come here!
logging.warning ("\t\t Expected Conditional Execution, but not of the matches were valid!")
#TODO: Add more information about warning
else:
logging.warning("\t\t Conditional Execution found, but suspecting it to be last node, since length of successor block is more than threshold")
#TODO: Add more information about warning
# Trying to map using Depth First Search traversal of each successor edge,
# if the number of successors is same.
numSuccBlocksMapped = 0
if len(listSuccISC) == len(listSuccObj):
logging.debug("\t Matching ISC:%s and OBJ:%s using DFT (number of successors is same)" % (blockISC.name, blockObj.name))
for succBlockISC in listSuccISC:
if succBlockISC in mappingStackISC:
numSuccBlocksMapped = numSuccBlocksMapped + 1
continue
succBlockISCMapped = 0
for succBlockObj in listSuccObj:
if succBlockObj in mappingStackObj:
# numSuccBlocksMapped = numSuccBlocksMapped + 1
continue
if mapping(cfgISC, succBlockISC, cfgObj, succBlockObj, mergedLevelsISC, gdbMapping) == 0:
# numSuccBlocksMapped = numSuccBlocksMapped + 1
succBlockISCMapped = 1
break
else:
continue
if succBlockISCMapped == 1:
numSuccBlocksMapped = numSuccBlocksMapped + 1
print "len(listSuccISC) = %d; len(listSuccObj) = %d" % (len(listSuccISC), len(listSuccObj))
print "len(listSuccWOBEISC) = %d; len(listSuccWOBEObj) = %d" % (len(listSuccWOBackEdgeISC), len(listSuccWOBackEdgeObj))
print "numSuccBlocksMapped = %d" % numSuccBlocksMapped
numBackEdgesISC = (len(listSuccISC) - len(listSuccWOBackEdgeISC))
numBackEdgesObj = (len(listSuccObj) - len(listSuccWOBackEdgeObj))
if len(listSuccISC) == numSuccBlocksMapped:
# All successor blocks were mapped!
blockISC.mapsTo.append(blockIndObj)
blockObj.mapsTo.append(blockIndISC)
mappingStackISC.pop()
mappingStackObj.pop()
return 0
# Trying to map using gdbMapping
deepestISCBlock = -1
deepestISCBlockNestingLevel = -1
logging.debug ("\t Matching ISC:%s and OBJ:%s using gdbMapping" % (blockISC.name, blockObj.name))
blockObj.mapsTo = []
for lineNum in range(blockObj.startLine, blockObj.endLine):
if lineNum in gdbMapping:
ISCLineNum = gdbMapping[lineNum].lineNum
for i in range(len(cfgISC.listBlocks)):
if (cfgISC.listBlocks[i].startLine <= ISCLineNum and
cfgISC.listBlocks[i].endLine >= ISCLineNum):
if i not in blockObj.mapsTo:
blockObj.mapsTo.append(i)
if blockIndObj not in cfgISC.listBlocks[i].mapsTo:
cfgISC.listBlocks[i].mapsTo.append(blockIndObj)
if deepestISCBlockNestingLevel < cfgISC.listBlocks[i].nestingLevel and i != blockIndISC:
# The deepest ISC Block is not inserted in mappingStackISC
# because mapping will be called on this block, and
# it will be inserted by the next iteration of the
# mapping function. Insert the block in stack, which
# was previously thought of being deepest.
if deepestISCBlock != -1:
mappingStackISC.append(deepestISCBlock)
deepestISCBlock = i
deepestISCBlockNestingLevel < cfgISC.listBlocks[i].nestingLevel
break
else:
mappingStackISC.append(i)
continue
if deepestISCBlock != -1:
mappingStackObj.pop() # popping blockIndObj from stack, as mapping is called on it again.
mergedLevelsISC = mergedLevelsISC + cfgISC.listBlocks[deepestISCBlock].nestingLevel - blockISC.nestingLevel
if mapping(cfgISC, deepestISCBlock, cfgObj, blockIndObj, mergedLevelsISC, gdbMapping) == 0:
for i in range(len(blockObj.mapsTo)-1):
# pop each entry from ISC to which the blockIndObj maps to
mappingStackISC.pop()
return 0 # successful mapping
logging.error("No mapping algorithm has worked!")
#TODO : Add more information about error
exit(1)
def map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames):
global mappingStackISC
global mappingStackObj
listISCFunctions = []
listFunctionNames = []
listObjdumpFunctions = []
gdbMapping = []
# Parse the ISC files
for ISCFileName in listISCFileNames:
listISCFunctions = listISCFunctions + parse_isc(ISCFileName)
for function in listISCFunctions:
listFunctionNames.append(function.functionName)
logging.debug("parsed "+ISCFileName)
# Parse the objdump files
for ObjdumpFileName in listObjdumpFileNames:
(tempListObjdumpFunctions, objdumpLineNumForAddress) = parse_binary(ObjdumpFileName,
listFunctionNames)
listObjdumpFunctions = listObjdumpFunctions + tempListObjdumpFunctions
# Check that we found all functions in ISC in Objdump
if len(listISCFunctions) != len(listObjdumpFunctions):
raise ParseError("all functions in ISC file not found in Objdump file!")
for function in listISCFunctions:
logging.debug("Computing flow for function %s from file %s" % (function.functionName, function.fileName))
function.cfg.computeFlow()
for function in listObjdumpFunctions:
logging.debug("Computing flow for function %s from file %s" % (function.functionName, function.fileName))
function.cfg.computeFlow()
for funcISC in listISCFunctions:
funcObj = find(lambda fn: fn.functionName == funcISC.functionName, listObjdumpFunctions)
display_cfgs(app, funcISC.cfg, funcObj.cfg, "%s" % funcISC.functionName)
for binaryFileName in listBinaryFileNames:
gdbMapping = getGDBMapping(binaryFileName, objdumpLineNumForAddress)
for fnISC in listISCFunctions:
mappingStackISC = []
mappingStackObj = []
cfgISC = fnISC.cfg
fnObj = find(lambda fn: fn.functionName == fnISC.functionName, listObjdumpFunctions)
cfgObj = fnObj.cfg
logging.debug( "Mapping Function %s" % (fnISC.functionName))
if mapping(cfgISC=cfgISC, blockIndISC=0, cfgObj=cfgObj, blockIndObj=0, mergedLevelsISC=0, gdbMapping=gdbMapping) == 0:
logging.debug( "Mapping Found!!!!")
print mappingStackISC
print mappingStackObj
else:
logging.debug( "Fuck my life!!!")
printDebugMapCFG(listISCFunctions, listObjdumpFunctions, gdbMapping)
#
for funcISC in listISCFunctions:
funcObj = find(lambda fn: fn.functionName == funcISC.functionName, listObjdumpFunctions)
display_cfgs(app, funcISC.cfg, funcObj.cfg, "%s" % funcISC.functionName)
return listISCFunctions, listObjdumpFunctions
if __name__ == "__main__":
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 "Addtional arguments are being ignored"
listISCFileNames = options.listISCFileNames
listObjdumpFileNames = options.listObjdumpFileNames
listBinaryFileNames = options.listBinaryFileNames
map_cfg(listISCFileNames, listObjdumpFileNames, listBinaryFileNames)
\ No newline at end of file
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