Skip to content

Commit 876edb0

Browse files
committed
ARM:ADD: update for conversion to C expressions
1 parent fba5a45 commit 876edb0

File tree

1 file changed

+93
-144
lines changed

1 file changed

+93
-144
lines changed

chb/arm/opcodes/ARMAdd.py

Lines changed: 93 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,34 @@
5353
class ARMAddXData(ARMOpcodeXData):
5454
"""Add <rd> <rn> <rm> ==> result
5555
56-
xdata format: a:vxxxxxxrrdh
57-
-------------------------
58-
vars[0]: vrd (Rd)
59-
xprs[0]: xrn (Rn)
60-
xprs[1]: xrm (Rm)
61-
xprs[2]: result: xrn + xrm
62-
xprs[3]: rresult: xrn + xrm (rewritten)
63-
xprs[4]: xxrn (xrn rewritten)
64-
xprs[5]: xxrm (xrm rewritten)
65-
xprs[6]: tcond (optional)
66-
xprs[7]: fcond (optional)
56+
Data format (regular)
57+
- variables:
58+
0: vrd
59+
60+
- expressions:
61+
0: xrn
62+
1: xrm
63+
2: result
64+
3: rresult (result, rewritten)
65+
4: xxrn (xrn, rewritten)
66+
5: xxrm (xrm, rewritten)
67+
68+
- c expressions:
69+
0: cresult
70+
6771
rdefs[0]: xrn
6872
rdefs[1]: xrm
6973
rdefs[2:..]: reaching definitions for simplified result expression
7074
uses[0]: vrd
7175
useshigh[0]: vrd
76+
77+
Data format (as part of jump table)
78+
- expressions:
79+
0: xrn
80+
1: xxrn (xrn, rewritten)
81+
82+
rdefs[0]: xrn
83+
rdefs[1:]: reaching definitions for xxrn
7284
"""
7385

7486
def __init__(self, xdata: InstrXData) -> None:
@@ -91,27 +103,58 @@ def jt_xxrn(self) -> "XXpr":
91103
"""Part of jumptable."""
92104
return self.xpr(1, "xxrn")
93105

106+
@property
107+
def is_jt_xxrn_ok(self) -> bool:
108+
return self.is_xpr_ok(1)
109+
94110
@property
95111
def result(self) -> "XXpr":
96112
return self.xpr(2, "result")
97113

114+
@property
115+
def is_result_ok(self) -> bool:
116+
return self.is_xpr_ok(2)
117+
98118
@property
99119
def rresult(self) -> "XXpr":
100120
return self.xpr(3, "rresult")
101121

122+
@property
123+
def is_rresult_ok(self) -> bool:
124+
return self.is_xpr_ok(3)
125+
126+
@property
127+
def cresult(self) -> "XXpr":
128+
return self.cxpr(0, "cresult")
129+
130+
@property
131+
def is_cresult_ok(self) -> bool:
132+
return self.is_cxpr_ok(0)
133+
102134
@property
103135
def result_simplified(self) -> str:
104-
return simplify_result(
105-
self.xdata.args[3], self.xdata.args[4], self.result, self.rresult)
136+
if self.is_result_ok and self.is_rresult_ok:
137+
return simplify_result(
138+
self.xdata.args[3], self.xdata.args[4], self.result, self.rresult)
139+
else:
140+
return str(self.xrn) + " + " + str(self.xrm)
106141

107142
@property
108143
def xxrn(self) -> "XXpr":
109144
return self.xpr(4, "xxrn")
110145

146+
@property
147+
def is_xxrn_ok(self) -> bool:
148+
return self.is_xpr_ok(4)
149+
111150
@property
112151
def xxrm(self) -> "XXpr":
113152
return self.xpr(5, "xxrm")
114153

154+
@property
155+
def is_xxrm_ok(self) -> bool:
156+
return self.is_xpr_ok(5)
157+
115158
@property
116159
def rn_rdef(self) -> Optional["ReachingDefFact"]:
117160
return self._xdata.reachingdefs[0]
@@ -123,7 +166,10 @@ def rm_rdef(self) -> Optional["ReachingDefFact"]:
123166
@property
124167
def annotation(self) -> str:
125168
if self.xdata.is_aggregate_jumptable:
126-
return "jump-table: " + str(self.jt_xxrn)
169+
if self.is_jt_xxrn_ok:
170+
return "jump-table: " + str(self.jt_xxrn)
171+
else:
172+
return "jump-table: " + str(self.xrn)
127173
assignment = str(self.vrd) + " := " + self.result_simplified
128174
return self.add_instruction_condition(assignment)
129175

@@ -175,10 +221,7 @@ def mnemonic_extension(self) -> str:
175221

176222
def annotation(self, xdata: InstrXData) -> str:
177223
xd = ARMAddXData(xdata)
178-
if xd.is_ok:
179-
return xd.annotation
180-
else:
181-
return "Error Value"
224+
return xd.annotation
182225

183226
# --------------------------------------------------------------------------
184227
# AddWithCarry()
@@ -243,169 +286,75 @@ def has_cast() -> bool:
243286
and astree.get_register_variable_intro(iaddr).has_cast())
244287

245288
xd = ARMAddXData(xdata)
246-
if not xdata.is_ok:
247-
chklogger.logger.error("Error value encountered at %s", iaddr)
248-
return ([], [])
289+
290+
if xd.is_cresult_ok and xd.is_rresult_ok:
291+
rhs = xd.cresult
292+
xrhs = xd.rresult
293+
294+
elif xd.is_rresult_ok:
295+
rhs = xd.rresult
296+
xrhs = xd.rresult
297+
298+
elif xd.is_result_ok:
299+
rhs = xd.result
300+
xrhs = xd.result
301+
302+
else:
303+
chklogger.logger.error(
304+
"ADD: Encountered error value for rhs at address %s", iaddr)
305+
return ([], [ll_assign])
249306

250307
lhs = xd.vrd
251308
rhs1 = xd.xrn
252309
rhs2 = xd.xrm
253-
rhs3 = xd.rresult
254-
rrhs1 = xd.xxrn
255-
rrhs2 = xd.xxrm
310+
rrhs1 = xd.xxrn if xd.is_xxrn_ok else xd.xrn
311+
rrhs2 = xd.xxrm if xd.is_xxrm_ok else xd.xrm
256312

257313
defuses = xdata.defuses
258314
defuseshigh = xdata.defuseshigh
259315

260316
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
261317

262-
def hl_rhs_default () -> AST.ASTExpr:
263-
return XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
264-
265318
if str(lhs) == "PC":
266319
chklogger.logger.info(
267320
"Add (ADD) instruction at address %s sets PC", iaddr)
268321

269322
hl_lhs_type = hl_lhs.ctype(astree.ctyper)
270323

271-
def pointer_arithmetic_expr() -> AST.ASTExpr:
272-
hl_rhs1 = XU.xxpr_to_ast_def_expr(rrhs1, xdata, iaddr, astree)
273-
hl_rhs2 = XU.xxpr_to_ast_def_expr(rrhs2, xdata, iaddr, astree)
274-
hl_rhs1_type = hl_rhs1.ctype(astree.ctyper)
275-
hl_rhs2_type = hl_rhs2.ctype(astree.ctyper)
276-
277-
if hl_rhs1_type is None and hl_rhs2_type is None:
278-
chklogger.logger.info(
279-
"Unable to lift pointer arithmetic without type for "
280-
+ "%s at address %s",
281-
str(rhs3), iaddr)
282-
return hl_rhs_default()
283-
284-
if hl_rhs2_type is not None and hl_rhs2_type.is_pointer:
285-
rhs2tgttyp = cast(AST.ASTTypPtr, hl_rhs2_type).tgttyp
286-
tgttypsize = astree.type_size_in_bytes(rhs2tgttyp)
287-
if tgttypsize is None:
288-
chklogger.logger.warning(
289-
"Unable to lift pointer arithmetic without size for "
290-
+ "%s at address %s; set type size to 1",
291-
str(hl_rhs2_type), iaddr)
292-
tgttypsize = 1
293-
294-
if tgttypsize == 1:
295-
return XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
296-
297-
if hl_rhs1.is_integer_constant:
298-
addend = cast(AST.ASTIntegerConstant, hl_rhs1).cvalue
299-
addend = addend // tgttypsize
300-
astaddend: AST.ASTExpr = astree.mk_integer_constant(addend)
301-
annotations.append("scaled by " + str(tgttypsize))
302-
return astree.mk_binary_op("plus", hl_rhs2, astaddend)
303-
304-
scale = astree.mk_integer_constant(tgttypsize)
305-
scaled = astree.mk_binary_op("div", hl_rhs1, scale)
306-
return astree.mk_binary_op("plus", hl_rhs2, scaled)
307-
308-
if hl_rhs1_type is not None and hl_rhs1_type.is_pointer:
309-
rhs1tgttyp = cast(AST.ASTTypPtr, hl_rhs1_type).tgttyp
310-
tgttypsize = astree.type_size_in_bytes(rhs1tgttyp)
311-
if tgttypsize is None:
312-
chklogger.logger.info(
313-
"Unable to lift pointer arithmetic without size for "
314-
+ "%s at address %s",
315-
str(hl_rhs1_type), iaddr)
316-
return hl_rhs_default()
317-
318-
if hl_rhs1.is_ast_startof:
319-
arraylval = cast(AST.ASTStartOf, hl_rhs1).lval
320-
arrayvinfo = cast(AST.ASTVariable, arraylval.lhost).varinfo
321-
if tgttypsize == 1:
322-
scaled = hl_rhs2
323-
else:
324-
scale = astree.mk_integer_constant(tgttypsize)
325-
scaled = astree.mk_binary_op("div", hl_rhs2, scale)
326-
327-
offset = astree.mk_expr_index_offset(scaled)
328-
offsetlval = astree.mk_vinfo_lval(arrayvinfo, offset)
329-
return astree.mk_address_of(offsetlval)
330-
331-
if tgttypsize == 1:
332-
return XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
333-
334-
if hl_rhs2.is_integer_constant:
335-
addend = cast(AST.ASTIntegerConstant, hl_rhs2).cvalue
336-
addend = addend // tgttypsize
337-
astaddend = astree.mk_integer_constant(addend)
338-
annotations.append("scaled by " + str(tgttypsize))
339-
return astree.mk_binary_op("plus", hl_rhs1, astaddend)
340-
341-
scale = astree.mk_integer_constant(tgttypsize)
342-
scaled = astree.mk_binary_op("div", hl_rhs2, scale)
343-
return astree.mk_binary_op("plus", hl_rhs1, scaled)
344-
345-
if hl_rhs2_type is None:
346-
chklogger.logger.info(
347-
"Unable to lift pointer arithmetic without type for "
348-
+ "%s at address %s",
349-
str(rhs2), iaddr)
350-
return hl_rhs_default()
351-
352-
chklogger.logger.info(
353-
"Second operand pointer variable not yet supported for %s at "
354-
+ "address %s; rrhs1: %s; hl_rhs1: %s; hl_rhs2: %s; hl_rhs1_type: %s;"
355-
+ " hl_rhs2_type: %s",
356-
str(rhs3),
357-
iaddr,
358-
str(rrhs1),
359-
str(hl_rhs1),
360-
str(hl_rhs2),
361-
str(hl_rhs1_type),
362-
str(hl_rhs2_type))
363-
return hl_rhs_default()
364-
365324
# resulting expression is a stack address
366325
if (
367326
(str(rrhs1) == "SP" or rrhs1.is_stack_address)
368-
and rhs3.is_stack_address):
327+
and xrhs.is_stack_address):
369328
annotations.append("stack address")
370-
rhs3 = cast("XprCompound", rhs3)
371-
stackoffset = rhs3.stack_address_offset()
329+
xrhs = cast("XprCompound", xrhs)
330+
stackoffset = xrhs.stack_address_offset()
372331
rhslval = astree.mk_stack_variable_lval(stackoffset)
373332
hl_rhs: AST.ASTExpr = astree.mk_address_of(rhslval)
374333

375334
# resulting expression is a pc-relative address
376335
elif str(rrhs1) == "PC" or str(rhs2) == "PC":
377336
annotations.append("PC-relative")
378-
if rhs3.is_int_constant:
379-
rhsexpr = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
380-
rhsval = cast("XprConstant", rhs3).intvalue
381-
if rhs3.is_string_reference:
337+
if xrhs.is_int_constant:
338+
rhsexpr = XU.xxpr_to_ast_def_expr(xrhs, xdata, iaddr, astree)
339+
rhsval = cast("XprConstant", xrhs).intvalue
340+
if xrhs.is_string_reference:
382341
saddr = hex(rhsval)
383-
cstr = rhs3.constant.string_reference()
342+
cstr = xrhs.constant.string_reference()
384343
hl_rhs = astree.mk_string_constant(
385344
rhsexpr, cstr, saddr)
386345
else:
387346
hl_rhs = astree.mk_global_address_constant(
388347
rhsval, rhsexpr)
389348
else:
390-
hl_rhs = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
349+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
391350

392-
elif rhs3.is_addressof_var:
393-
hl_rhs = XU.xxpr_to_ast_def_expr(rhs3, xdata, iaddr, astree)
394-
if rhs3.is_constant_expression:
351+
elif rhs.is_addressof_var:
352+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
353+
if rhs.is_constant_expression:
395354
astree.set_ssa_value(str(hl_lhs), hl_rhs)
396355

397-
elif (hl_lhs_type is not None and hl_lhs_type.is_pointer and not has_cast()):
398-
hl_rhs = pointer_arithmetic_expr()
399-
if str(hl_rhs).startswith("astmem_tmp"):
400-
chklogger.logger.error(
401-
"Unable to compute pointer arithmetic expression for %s "
402-
"at address %s",
403-
str(rhs3), iaddr)
404-
else:
405-
if rhs3.is_constant_expression:
406-
astree.set_ssa_value(str(hl_lhs), hl_rhs)
407356
else:
408-
hl_rhs = hl_rhs_default ()
357+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
409358

410359
hl_assign = astree.mk_assign(
411360
hl_lhs,

0 commit comments

Comments
 (0)