Skip to content

Commit

Permalink
correct ssa naming for phi-function
Browse files Browse the repository at this point in the history
  • Loading branch information
Francois Chagnon committed May 22, 2015
1 parent ecd6520 commit 338cb8c
Show file tree
Hide file tree
Showing 16 changed files with 95 additions and 72 deletions.
4 changes: 2 additions & 2 deletions src/callconv.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, flow):
def is_correct_step(self, loc):
return isinstance(loc, assignable_t)

def tag_tethas(self, context, block):
def tag_phis(self, context, block):
return

def tag_uses(self, context, block, expr):
Expand Down Expand Up @@ -114,7 +114,7 @@ def process(self, flow, ssa_tagger, block, stmt, call):
if newloc:
regs.append(newloc.copy())
elif ssa_tagger.has_contextual_definition(stmt, loc):
newloc = self.insert_theta(stmt, loc)
newloc = self.insert_phi(stmt, loc)
regs.append(newloc.copy())
else:
break
Expand Down
6 changes: 3 additions & 3 deletions src/decompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ def rename_with(self, op):

class stack_propagator_t(propagator.propagator_t):
def replace_with(self, defn, value, use):
if isinstance(use.parent, theta_t) or \
isinstance(value, theta_t) or \
if isinstance(use.parent, phi_t) or \
isinstance(value, phi_t) or \
not isinstance(value, replaceable_t):
return
if self.flow.arch.is_stackreg(defn) or \
Expand All @@ -184,7 +184,7 @@ def is_stack_location(self, expr):

class registers_propagator_t(propagator.propagator_t):
def replace_with(self, defn, value, use):
if isinstance(use, regloc_t) and not isinstance(use.parent, theta_t):
if isinstance(use, regloc_t) and not isinstance(use.parent, phi_t):
return value

class call_arguments_propagator_t(propagator.propagator_t):
Expand Down
4 changes: 2 additions & 2 deletions src/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,13 +468,13 @@ def __repr__(self):
def copy(self, **kwargs):
return self.__class__(*[op.copy(**kwargs) for op in self.operands])

class theta_t(expr_t):
class phi_t(expr_t):
def __init__(self, *operands):
expr_t.__init__(self, *operands)
return

def __repr__(self):
return '<theta %s>' % ([repr(op) for op in self.operands])
return '<phi %s>' % ([repr(op) for op in self.operands])

def copy(self, **kwargs):
return self.__class__(*[op.copy(**kwargs) for op in self.operands])
Expand Down
5 changes: 3 additions & 2 deletions src/output/c.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# coding=utf-8

from expressions import *
from statements import *
Expand Down Expand Up @@ -336,8 +337,8 @@ def expression_tokens(self, obj):
yield r
return

if type(obj) == theta_t:
yield token_keyword('THETA')
if type(obj) == phi_t:
yield token_keyword('Φ')
l, r = self.matching('(', ')')
yield l
for op in obj.operands:
Expand Down
54 changes: 27 additions & 27 deletions src/ssa.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ def __init__(self, flow):
self.exit_contexts = {}

# dict of `flowblock_t` : [`expr_t`, ...]
# contains each block and a list of thier theta assignments.
self.block_thetas = {}
# contains each block and a list of thier phi assignments.
self.block_phis = {}

return

Expand Down Expand Up @@ -140,10 +140,10 @@ def tag_uninitialized(self, expr):
self.uninitialized.append(expr)
return

def insert_theta(self, block, lastdef, thisdef):
def insert_phi(self, block, lastdef, thisdef):

newuse = lastdef.copy(with_definition=True)
stmt = statement_t(assign_t(thisdef.copy(), theta_t(newuse)))
stmt = statement_t(assign_t(thisdef.copy(), phi_t(newuse)))

block.container.insert(thisdef.parent_statement.index(), stmt)

Expand All @@ -152,19 +152,19 @@ def insert_theta(self, block, lastdef, thisdef):

return stmt

def need_tetha(self, context, block, expr):
def need_phi(self, context, block, expr):
obj = context.get_definition_object(expr)
return obj and obj.block != block

def tag_use(self, context, block, expr):
if self.need_tetha(context, block, expr):
if self.need_phi(context, block, expr):
# expr is defined in another block.

lastdef = context.get_definition(expr)
if lastdef:
stmt = self.insert_theta(block, lastdef, expr)
stmt = self.insert_phi(block, lastdef, expr)

self.block_thetas[block].append(stmt)
self.block_phis[block].append(stmt)

context.assign(block, stmt.expr.op1)
stmt.expr.op1.index = self.index
Expand Down Expand Up @@ -196,10 +196,10 @@ def clean_du(self, loc):
use.definition = None
return loc

def tag_tethas(self, context, block):
def tag_phis(self, context, block):
""" insert new locations from the current context in all
theta-functions present in the target block. """
for stmt in self.block_thetas[block]:
phi-functions present in the target block. """
for stmt in self.block_phis[block]:
loc = stmt.expr.op1
lastdef = context.get_definition(loc)
if lastdef and lastdef != loc:
Expand Down Expand Up @@ -231,11 +231,11 @@ def statement(self, context, stmt):
def tag_block(self, context, block):

if block in self.done_blocks:
self.tag_tethas(context, block)
self.tag_phis(context, block)
return

self.done_blocks.append(block)
self.block_thetas[block] = []
self.block_phis[block] = []

for stmt in list(block.container.statements):
for expr in stmt.expressions:
Expand Down Expand Up @@ -291,7 +291,7 @@ def is_restored(self, expr):
current = start.pop(0)
checked.append(current)
rvalue = current.parent_statement.expr.op2
if isinstance(rvalue, theta_t):
if isinstance(rvalue, phi_t):
for t in rvalue:
if t.definition:
if t.definition not in checked:
Expand Down Expand Up @@ -358,23 +358,23 @@ def spoiled_locations(self):
return

def simplify(self):
""" propagate theta groups that only have one item in them
""" propagate phi groups that only have one item in them
while keeping the ssa form. """
p = theta_propagator_t(self)
p = phi_propagator_t(self)
p.propagate()
self.verify()
return

def has_theta_expressions(self):
def has_phi_expressions(self):
for op in iterators.operand_iterator_t(self.flow):
if isinstance(op, theta_t):
if isinstance(op, phi_t):
return True
return False

def remove_ssa_form(self):
""" transform the flow out of ssa form. """

if not self.has_theta_expressions():
if not self.has_phi_expressions():
for op in iterators.operand_iterator_t(self.flow):
if isinstance(op, assignable_t):
op.index = None
Expand Down Expand Up @@ -407,27 +407,27 @@ def verify(self):
assert use.parent_statement.container, "%s: has a use (%s) which is unlinked from the tree" % (repr(op), repr(use))
return

class theta_propagator_t(propagator.propagator_t):
class phi_propagator_t(propagator.propagator_t):
def __init__(self, ssa):
propagator.propagator_t.__init__(self, ssa.flow)
self.ssa = ssa

def replace_with(self, defn, value, use):
if isinstance(value, theta_t) and len(value) == 1:
if isinstance(value, phi_t) and len(value) == 1:
return value[0]

def replace(self, defn, value, use):
for block, tethas in self.ssa.block_thetas.iteritems():
for block, phis in self.ssa.block_phis.iteritems():
stmt = defn.parent_statement
if stmt in tethas:
tethas.remove(stmt)
theta = use.parent
if isinstance(theta, theta_t) and value in list(theta.operands):
if stmt in phis:
phis.remove(stmt)
phi = use.parent
if isinstance(phi, phi_t) and value in list(phi.operands):
use.definition = None
if len(defn.uses) == 0:
defn.parent_statement.expr.unlink()
defn.parent_statement.remove()
theta.remove(use)
phi.remove(use)
new = None
else:
new = propagator.propagator_t.replace(self, defn, value, use)
Expand Down
2 changes: 2 additions & 0 deletions tests/run.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest
import sys

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import os
import sys

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_args.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest

import test_helper
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_capstone.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest
import sys

Expand Down
6 changes: 4 additions & 2 deletions tests/unit/test_conditionals.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest
import re
import binascii
Expand Down Expand Up @@ -154,7 +156,7 @@ def test_if6_x86(self):
else {
eax@77 = 0;
}
return THETA(eax@61, eax@77, eax@78, eax@79, eax@80, eax@81, );
return Φ(eax@61, eax@77, eax@78, eax@79, eax@80, eax@81, );
}
""")
return
Expand Down Expand Up @@ -186,7 +188,7 @@ def test_if7_x86(self):
else {
eax@77 = 0;
}
return THETA(eax@61, eax@77, eax@78, eax@79, eax@80, eax@81, );
return Φ(eax@61, eax@77, eax@78, eax@79, eax@80, eax@81, );
}
""")
return
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_flow.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest

import test_helper
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_helper.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import re
import unittest
import sys
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_ir.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest

import test_helper
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/test_prune.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# coding=utf-8

import unittest

import test_helper
Expand Down
Loading

0 comments on commit 338cb8c

Please sign in to comment.