1 # ScratchABlock - Program analysis and decompilation framework
3 # Copyright (c) 2015-2018 Paul Sokolovsky
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 """Transformation passes on instructions"""
20 from xform_expr
import *
24 def normalize_cond(inst
):
25 "Normalize conditions so constants are on the right side."
27 inst
.args
[0].normalize()
30 def booleanize_cond(inst
):
31 "Make conditions be of bool type (have bool operation)."
34 if not cond
.is_relation():
36 if is_expr(e
) and e
.op
== "!":
37 new
= EXPR("==", e
.args
[0], VALUE(0, 0))
39 new
= EXPR("!=", e
, VALUE(0, 0))
43 def sub_const_to_add(inst
):
44 "Replace subtractions of constant with adds."
46 inst
.dest
= expr_xform(inst
.dest
, expr_sub_const_to_add
)
47 for i
, a
in enumerate(inst
.args
):
48 inst
.args
[i
] = expr_xform(a
, expr_sub_const_to_add
)
51 def simplify_inst(inst
):
52 if not (inst
.dest
and inst
.op
== "="):
54 assert len(inst
.args
) == 1
55 inst
.args
[0] = simplify_expr(inst
.args
[0])
58 def struct_access_inst(inst
):
59 if not (inst
.dest
and inst
.op
== "="):
61 assert len(inst
.args
) == 1
62 inst
.args
[0] = struct_access_expr(inst
.args
[0])
65 def rewrite_complex_dest(inst
):
66 "Rewrite casts and bitfield() on the left hand side of assignment."
69 if not (inst
.dest
and inst
.op
== "="):
71 if not is_expr(inst
.dest
):
75 size
= dest
.args
[0].bitsize()
76 elif dest
.op
== "SFUNC" and dest
.args
[0].name
== "bitfield":
77 assert is_value(dest
.args
[2]) and is_value(dest
.args
[3])
78 lsb
= dest
.args
[2].val
79 size
= dest
.args
[3].val
83 inst
.dest
= dest
.args
[1]
84 if lsb
== 0 and size
== arch
.BITNESS
:
87 all_ones
= (1 << arch
.BITNESS
) - 1
88 mask
= (1 << size
) - 1
91 new_rhs
= EXPR("&", inst
.args
[0], VALUE(mask
))
94 EXPR("<<", inst
.args
[0], VALUE(lsb
, 10)),
97 inst
.args
[0] = EXPR("|",
98 EXPR("&", inst
.dest
, VALUE(all_ones ^ mask
)),
102 def rewrite_stack_vars(inst
, rewrite_to
=CVAR
):
103 "Rewrite memory references relative to sp0 to local variables."
105 if is_mem(m
) and is_expr(m
.expr
) and set(m
.expr
.regs()) == {REG("sp_0")}:
106 name
= "loc" + str(m
.expr
.args
[1].val
).replace("-", "_") + "_" + str(m
.type)
107 return rewrite_to(name
)
110 inst
.dest
= expr_xform(inst
.dest
, mem2loc
)
112 for arg_no
, arg
in enumerate(inst
.args
):
113 inst
.args
[arg_no
] = expr_xform(arg
, mem2loc
)