Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
H
hostCompiledSimulation
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gaurav Kukreja
hostCompiledSimulation
Commits
bf148626
Commit
bf148626
authored
Aug 28, 2014
by
Gaurav Kukreja
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes to Grammar.py * Removing unneeded files *
Signed-off-by:
Gaurav Kukreja
<
gaurav@gauravk.in
>
parent
74c3f39c
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
24 additions
and
1515 deletions
+24
-1515
cGrammar.py
instrument/cGrammar.py
+24
-7
cGrammar1.py
instrument/cGrammar1.py
+0
-465
display_cfg.py
instrument/display_cfg.py
+0
-367
instrument.py
instrument/instrument.py
+0
-0
irc_instrument.py
instrument/irc_instrument.py
+0
-0
irc_parse.py
instrument/irc_parse.py
+0
-128
map_cfg.py
instrument/map_cfg.py
+0
-548
No files found.
instrument/cGrammar.py
View file @
bf148626
...
...
@@ -35,6 +35,8 @@ LE_OP = Literal("<=")
RIGHT_OP
=
Literal
(
">>"
)
LEFT_OP
=
Literal
(
"<<"
)
PTR_OP
=
Literal
(
"->"
)
POINTER
=
Literal
(
"*"
)
SEMICOLON
=
Literal
(
";"
)
SIZEOF
=
Literal
(
"sizeof"
)
...
...
@@ -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.
del
(
list_annotations
[
-
1
])
# TODO : Check if PTR_OP and Literal(".") must be handled more carefully
# Removing Left Recursion
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
))
|
(
PTR_OP
+
IDENTIFIER
+
postfix_expression_1
)
|
(
Literal
(
"."
)
+
IDENTIFIER
+
postfix_expression_1
)
|
Empty
()
)
postfix_expression
=
(
(
primary_expression
)
+
postfix_expression_1
)
...
...
@@ -301,7 +307,7 @@ shift_expression_1 << ( (LEFT_OP + additive_expression + shift_expression_1)
shift_expression
=
(
(
additive_expression
+
shift_expression_1
)
)
relational_expression_1
=
Forward
()
relational_expression_1
<<
(
(
L
T_OP
+
shift_expression
+
relational_expression_1
)
relational_expression_1
<<
(
(
G
T_OP
+
shift_expression
+
relational_expression_1
)
|
(
LT_OP
+
shift_expression
+
relational_expression_1
)
|
(
GE_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) )
conditional_expression
=
Forward
()
conditional_expression
<<
(
(
logical_or_expression
+
Literal
(
"?"
)
+
expression
+
Literal
(
":"
)
+
conditional_expression
)
|
(
logical_or_expression
)
^
(
logical_or_expression
)
)
def
act_assign_op
(
tokens
):
...
...
@@ -367,7 +373,7 @@ def act_assign_op(tokens):
assignment_expression
=
Forward
()
assignment_expression
<<
(
((
unary_expression
)
+
ASSIGN_OP
.
setParseAction
(
act_assign_op
)
+
(
assignment_expression
))
|
(
conditional_expression
)
^
(
conditional_expression
)
)
expression
<<
(
assignment_expression
)
...
...
@@ -408,8 +414,6 @@ def parse_statement(line):
list_identifiers
=
[]
list_annotations
=
[]
print
assign_operator_seen
r
=
statement
.
parseString
(
line
)
return
list_annotations
...
...
@@ -421,6 +425,9 @@ def test():
,
"diff = (int) *(short int *)((uintptr_t)indata + (uintptr_t)ivtmp_28) - valpred;"
,
"*outp = (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);"
),
...
...
@@ -434,8 +441,6 @@ def test():
],
[(
"diff"
,
"simDCache((diff_addr), 0);"
),
(
"indata"
,
"simDCache((indata_addr+ivtmp_28), 1);"
),
(
"indata"
,
"simDCache((indata_addr), 1);"
),
(
"ivtmp_28"
,
"simDCache((ivtmp_28_addr), 1);"
),
(
"valpred"
,
"simDCache((valpred_addr), 1);"
)
],
[(
"outp"
,
"simDCache((outp_addr), 0);"
),
...
...
@@ -443,6 +448,18 @@ def test():
],
[(
"outp"
,
"simDCache((outp_addr+i), 0);"
),
(
"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);"
)
]
]
...
...
instrument/cGrammar1.py
deleted
100644 → 0
View file @
74c3f39c
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
instrument/display_cfg.py
deleted
100644 → 0
View file @
74c3f39c
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
instrument/instrument.py
deleted
100644 → 0
View file @
74c3f39c
instrument/irc_instrument.py
deleted
100644 → 0
View file @
74c3f39c
instrument/irc_parse.py
deleted
100644 → 0
View file @
74c3f39c
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
instrument/map_cfg.py
deleted
100644 → 0
View file @
74c3f39c
#-----------------------------------------------------------------
# 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
(
"
\n
FileName :
%
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
(
"
\n
FileName :
%
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment