Skip to content

Commit 298b951

Browse files
committed
ARM:AST: update ast_prov methods
1 parent 3d643ca commit 298b951

File tree

8 files changed

+118
-117
lines changed

8 files changed

+118
-117
lines changed

chb/app/CHVersion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
chbversion: str = "0.3.0-20241028"
1+
chbversion: str = "0.3.0-20241111"

chb/arm/opcodes/ARMBitwiseExclusiveOr.py

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2023 Aarno Labs LLC
7+
# Copyright (c) 2021-2024 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -118,12 +118,6 @@ def ast_prov(
118118

119119
annotations: List[str] = [iaddr, "EOR"]
120120

121-
lhs = xdata.vars[0]
122-
rhs = xdata.xprs[3]
123-
rdefs = xdata.reachingdefs
124-
defuses = xdata.defuses
125-
defuseshigh = xdata.defuseshigh
126-
127121
(ll_lhs, _, _) = self.operands[0].ast_lvalue(astree)
128122
(ll_op1, _, _) = self.operands[0].ast_rvalue(astree)
129123
(ll_op2, _, _) = self.operands[0].ast_rvalue(astree)
@@ -136,27 +130,20 @@ def ast_prov(
136130
bytestring=bytestring,
137131
annotations=annotations)
138132

139-
lhsasts = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
140-
if len(lhsasts) == 0:
141-
raise UF.CHBError("BitwiseExclusiveOr (EOR): no lval found")
142-
143-
if len(lhsasts) > 1:
144-
raise UF.CHBError(
145-
"BitwiseExclusiveOr (EOR): multiple lvals found: "
146-
+ ", ".join(str(v) for v in lhsasts))
133+
rdefs = xdata.reachingdefs
147134

148-
hl_lhs = lhsasts[0]
135+
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
136+
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
149137

150-
rhsasts = XU.xxpr_to_ast_def_exprs(rhs, xdata, iaddr, astree)
151-
if len(rhsasts) == 0:
152-
raise UF.CHBError("BitwiseExclusiveOr (EOR): no lval found")
138+
# high-level assignment
153139

154-
if len(rhsasts) > 1:
155-
raise UF.CHBError(
156-
"BitwiseExclusiveOr (EOR): multiple rhs values found: "
157-
+ ", ".join(str(v) for v in rhsasts))
140+
lhs = xdata.vars[0]
141+
rhs = xdata.xprs[3]
142+
defuses = xdata.defuses
143+
defuseshigh = xdata.defuseshigh
158144

159-
hl_rhs = rhsasts[0]
145+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
146+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
160147

161148
hl_assign = astree.mk_assign(
162149
hl_lhs,
@@ -165,13 +152,12 @@ def ast_prov(
165152
bytestring=bytestring,
166153
annotations=annotations)
167154

168-
astree.add_reg_definition(iaddr, hl_lhs, hl_rhs)
169155
astree.add_instr_mapping(hl_assign, ll_assign)
170156
astree.add_instr_address(hl_assign, [iaddr])
171157
astree.add_expr_mapping(hl_rhs, ll_rhs)
172158
astree.add_lval_mapping(hl_lhs, ll_lhs)
173-
astree.add_expr_reachingdefs(ll_op1, [rdefs[0]])
174-
astree.add_expr_reachingdefs(ll_op2, [rdefs[1]])
159+
astree.add_expr_reachingdefs(hl_rhs, rdefs[2:])
160+
astree.add_expr_reachingdefs(ll_rhs, rdefs[:2])
175161
astree.add_lval_defuses(hl_lhs, defuses[0])
176162
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
177163

chb/arm/opcodes/ARMCompareBranchZero.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,7 @@ def ast_condition_prov(
131131
else:
132132
condition = ftconds[1]
133133

134-
astconds = XU.xxpr_to_ast_def_exprs(condition, xdata, iaddr, astree)
135-
if len(astconds) == 0:
136-
chklogger.logger.error(
137-
"CompareBranchZero (CBZ) at address %s: no rhs values "
138-
+ "found; returning zero", iaddr)
139-
return (zero, zero)
140-
141-
if len(astconds) > 1:
142-
chklogger.logger.error(
143-
"CompareBranchZero (CBZ) at address %s: multiple rhs "
144-
+ "values found at address %s: %s; returning zero",
145-
iaddr,
146-
", ".join(str(v) for v in astconds))
147-
return (zero, zero)
148-
149-
hl_cond = astconds[0]
134+
hl_cond = XU.xxpr_to_ast_def_expr(condition, xdata, iaddr, astree)
150135

151136
astree.add_expr_mapping(hl_cond, ll_cond)
152137
astree.add_expr_reachingdefs(hl_cond, rdefs)

chb/arm/opcodes/ARMStoreRegisterByte.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,19 @@ def ast_prov(
150150

151151
lhs = xdata.vars[0]
152152
rhs = xdata.xprs[3]
153+
rhs_basic = xdata.xprs[2]
153154
memaddr = xdata.xprs[4]
154155
rdefs = xdata.reachingdefs
155156
defuses = xdata.defuses
156157
defuseshigh = xdata.defuseshigh
157158

158-
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
159+
if rhs.has_variables_with_property(
160+
lambda v: v.is_initial_memory_value
161+
and xdata.function.has_var_disequality(iaddr, v)):
162+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs_basic, xdata, iaddr, astree)
163+
else:
164+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
165+
159166
hl_lhs = XU.xvariable_to_ast_lval(
160167
lhs, xdata, iaddr, astree, memaddr=memaddr)
161168

chb/arm/opcodes/ARMUnsignedBitFieldExtract.py

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -111,44 +111,43 @@ def ast_prov(
111111

112112
annotations: List[str] = [iaddr, "UBFX"]
113113

114+
(ll_rhs, _, _) = self.opargs[1].ast_rvalue(astree)
115+
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
116+
117+
ll_assign = astree.mk_assign(
118+
ll_lhs,
119+
ll_rhs,
120+
iaddr=iaddr,
121+
bytestring=bytestring,
122+
annotations=annotations)
123+
124+
rdefs = xdata.reachingdefs
125+
126+
astree.add_expr_reachingdefs(ll_rhs, [rdefs[0]])
127+
128+
# high-level assignment
129+
114130
lhs = xdata.vars[0]
115131
rhs = xdata.xprs[1]
116-
rdefs = xdata.reachingdefs
117132
defuses = xdata.defuses
118133
defuseshigh = xdata.defuseshigh
119134

120-
(ll_rhs, _, _) = self.opargs[1].ast_rvalue(astree)
121-
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
122-
123-
hl_lhss = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
124-
125-
try:
126-
hl_rhss = XU.xxpr_to_ast_def_exprs(rhs, xdata, iaddr, astree)
127-
except UF.CHBError as e:
128-
chklogger.logger.error(
129-
"Error in UBFX at address %s: %s", iaddr, str(e))
130-
hl_rhss = [ll_rhs]
131-
132-
if len(hl_rhss) == 1 and len(hl_lhss) == 1:
133-
hl_lhs = hl_lhss[0]
134-
hl_rhs = hl_rhss[0]
135-
136-
return self.ast_variable_intro(
137-
astree,
138-
astree.astree.unsigned_char_type,
139-
hl_lhs,
140-
hl_rhs,
141-
ll_lhs,
142-
ll_rhs,
143-
rdefs[1:],
144-
[rdefs[0]],
145-
defuses[0],
146-
defuseshigh[0],
147-
True,
148-
iaddr,
149-
annotations,
150-
bytestring)
151-
152-
else:
153-
raise UF.CHBError(
154-
"ARMUnsignedBitFieldExtract: multiple expressions/lvals in ast")
135+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
136+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
137+
138+
hl_assign = astree.mk_assign(
139+
hl_lhs,
140+
hl_rhs,
141+
iaddr=iaddr,
142+
bytestring=bytestring,
143+
annotations=annotations)
144+
145+
astree.add_instr_mapping(hl_assign, ll_assign)
146+
astree.add_instr_address(hl_assign, [iaddr])
147+
astree.add_expr_mapping(hl_rhs, ll_rhs)
148+
astree.add_lval_mapping(hl_lhs, ll_lhs)
149+
astree.add_expr_reachingdefs(hl_rhs, rdefs[1:])
150+
astree.add_lval_defuses(hl_lhs, defuses[0])
151+
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
152+
153+
return ([hl_assign], [ll_assign])

chb/arm/opcodes/ARMUnsignedExtendHalfword.py

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -120,42 +120,42 @@ def ast_prov(
120120

121121
annotations: List[str] = [iaddr, "UXTH"]
122122

123-
lhs = xdata.vars[0]
124-
rhs = xdata.xprs[2]
125-
rdefs = xdata.reachingdefs
126-
defuses = xdata.defuses
127-
defuseshigh = xdata.defuseshigh
128-
129123
(ll_rhs, _, _) = self.opargs[1].ast_rvalue(astree)
130124
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
131125

132-
hl_lhss = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
133-
hl_rhss = XU.xxpr_to_ast_def_exprs(rhs, xdata, iaddr, astree)
126+
ll_assign = astree.mk_assign(
127+
ll_lhs,
128+
ll_rhs,
129+
iaddr=iaddr,
130+
bytestring=bytestring,
131+
annotations=annotations)
134132

135-
if len(hl_lhss) == 0:
136-
raise UF.CHBError("UXTH: no lvals in ast")
137-
if len(hl_lhss) > 1:
138-
raise UF.CHBError("UXTH: multiple lvals in ast")
139-
if len(hl_rhss) == 0:
140-
raise UF.CHBError("UXTH: no rhs expressions in ast")
141-
if len(hl_rhss) > 1:
142-
raise UF.CHBError("UXTH: multiplve rhs expressions in ast")
133+
rdefs = xdata.reachingdefs
143134

144-
hl_lhs = hl_lhss[0]
145-
hl_rhs = hl_rhss[0]
135+
astree.add_expr_reachingdefs(ll_rhs, [rdefs[0]])
146136

147-
return self.ast_variable_intro(
148-
astree,
149-
astree.astree.unsigned_short_type,
137+
lhs = xdata.vars[0]
138+
rhs = xdata.xprs[2]
139+
defuses = xdata.defuses
140+
defuseshigh = xdata.defuseshigh
141+
142+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
143+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
144+
145+
hl_assign = astree.mk_assign(
150146
hl_lhs,
151147
hl_rhs,
152-
ll_lhs,
153-
ll_rhs,
154-
rdefs[1:],
155-
[rdefs[0]],
156-
defuses[0],
157-
defuseshigh[0],
158-
True,
159-
iaddr,
160-
annotations,
161-
bytestring)
148+
iaddr=iaddr,
149+
bytestring=bytestring,
150+
annotations=annotations)
151+
152+
astree.add_instr_mapping(hl_assign, ll_assign)
153+
astree.add_instr_address(hl_assign, [iaddr])
154+
astree.add_expr_mapping(hl_rhs, ll_rhs)
155+
astree.add_lval_mapping(hl_lhs, ll_lhs)
156+
astree.add_expr_reachingdefs(hl_rhs, rdefs[1:])
157+
astree.add_expr_reachingdefs(ll_rhs, rdefs[:1])
158+
astree.add_lval_defuses(hl_lhs, defuses[0])
159+
astree.add_lval_defuses_high(hl_lhs, defuseshigh[0])
160+
161+
return ([hl_assign], [ll_assign])

chb/invariants/XXpr.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
4040
"""
4141
from typing import (
42-
Any, cast, Dict, List, Mapping, Optional, Sequence, TYPE_CHECKING)
42+
Any, Callable, cast, Dict, List, Mapping, Optional, Sequence, TYPE_CHECKING)
4343

4444
from chb.api.CallTarget import CallTarget
4545

@@ -287,6 +287,10 @@ def has_global_variables(self) -> bool:
287287
def has_global_references(self) -> bool:
288288
return False
289289

290+
def has_variables_with_property(
291+
self, p: Callable[[XVariable], bool]) -> bool:
292+
return False
293+
290294
def negated_value(self) -> int:
291295
raise UF.CHBError("Get_negated_value not supported for " + str(self))
292296

@@ -437,6 +441,10 @@ def has_global_variables(self) -> bool:
437441
def has_global_references(self) -> bool:
438442
return self.has_global_variables()
439443

444+
def has_variables_with_property(
445+
self, p: Callable[[XVariable], bool]) -> bool:
446+
return p(self.variable)
447+
440448
def argument_index(self) -> int:
441449
if self.is_argument_value:
442450
return self.variable.denotation.argument_index()
@@ -737,6 +745,10 @@ def has_global_variables(self) -> bool:
737745
def has_global_references(self) -> bool:
738746
return any([op.has_global_references() for op in self.operands])
739747

748+
def has_variables_with_property(
749+
self, p: Callable[[XVariable], bool]) -> bool:
750+
return any([op.has_variables_with_property(p) for op in self.operands])
751+
740752
@property
741753
def is_stack_address(self) -> bool:
742754
args = self.operands

chb/invariants/XXprUtil.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def memory_variable_to_lval_expression(
390390
return astree.mk_vinfo_lval_expression(
391391
vinfo, astoffset, anonymous=anonymous)
392392

393-
elif offset.is_array_index_offset:
393+
if offset.is_array_index_offset:
394394
offset = cast("VMemoryOffsetArrayIndexOffset", offset)
395395
index = offset.index_expression
396396
astindex = xxpr_to_ast_def_expr(
@@ -411,10 +411,22 @@ def memory_variable_to_lval_expression(
411411
return astree.mk_vinfo_lval_expression(
412412
vinfo,astindexoffset, anonymous=anonymous)
413413

414+
if offset.is_index_offset:
415+
offset = cast("VMemoryOffsetIndexOffset", offset)
416+
indexvar = offset.indexvariable
417+
astindexvar = xvariable_to_ast_def_lval_expression(
418+
indexvar, xdata, iaddr, astree, anonymous=anonymous)
419+
suboffset = offset.offset
420+
421+
if suboffset.is_no_offset:
422+
astindexoffset = astree.mk_expr_index_offset(astindexvar)
423+
return astree.mk_vinfo_lval_expression(
424+
vinfo, astindexoffset, anonymous=anonymous)
425+
414426
chklogger.logger.error(
415-
"AST conversion of memory variable %s with other offset not yet "
427+
"AST conversion of memory variable %s with other offset: %s not yet "
416428
+ "supported at address %s",
417-
name, iaddr)
429+
name, str(offset), iaddr)
418430

419431
return astree.mk_temp_lval_expression()
420432

@@ -1000,7 +1012,7 @@ def default() -> AST.ASTExpr:
10001012
xpr2, xdata, iaddr, astree, anonymous=anonymous)
10011013
if operator in [
10021014
"plus", "minus", "mult", "div",
1003-
"band", "land", "lor", "bor", "asr",
1015+
"band", "land", "lor", "bor", "asr", "bxor",
10041016
"lsl", "lsr", "eq", "ne", "gt", "le", "lt", "ge"]:
10051017
return astree.mk_binary_expression(operator, astxpr1, astxpr2)
10061018
else:

0 commit comments

Comments
 (0)