Skip to content

Commit 266ea8c

Browse files
committed
ARM: convert astprov to handle result types
1 parent ec0c132 commit 266ea8c

12 files changed

+477
-204
lines changed

chb/arm/ARMInstruction.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -309,17 +309,22 @@ def ast_switch_condition_prov(self, astree: ASTInterface) -> Tuple[
309309
jumptable = cast(
310310
"ARMJumpTable", self.armfunction.get_jumptable(self.iaddr))
311311
indexop = jumptable.index_operand
312-
condition = self.xdata.xprs[1]
313-
(ll_cond, _, _) = indexop.ast_rvalue(astree)
314-
hl_cond = XU.xxpr_to_ast_def_expr(
315-
condition, self.xdata, self.iaddr, astree)
316-
317-
astree.add_expr_mapping(hl_cond, ll_cond)
318-
astree.add_expr_reachingdefs(hl_cond, self.xdata.reachingdefs)
319-
astree.add_condition_address(
320-
ll_cond, (self.xdata.subsumes() + [self.iaddr]))
321-
322-
return (hl_cond, ll_cond)
312+
condition = self.xdata.xprs_r[1]
313+
if condition is not None:
314+
(ll_cond, _, _) = indexop.ast_rvalue(astree)
315+
hl_cond = XU.xxpr_to_ast_def_expr(
316+
condition, self.xdata, self.iaddr, astree)
317+
318+
astree.add_expr_mapping(hl_cond, ll_cond)
319+
astree.add_expr_reachingdefs(hl_cond, self.xdata.reachingdefs)
320+
astree.add_condition_address(
321+
ll_cond, (self.xdata.subsumes() + [self.iaddr]))
322+
323+
return (hl_cond, ll_cond)
324+
else:
325+
chklogger.logger.error(
326+
"Error value encountered at address %s", self.iaddr)
327+
raise UF.CHBError("Jumptable without condition")
323328

324329
else:
325330
return self.opcode.ast_switch_condition_prov(

chb/arm/opcodes/ARMBitwiseExclusiveOr.py

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2024 Aarno Labs LLC
7+
# Copyright (c) 2021-2025 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
@@ -30,7 +30,7 @@
3030
from chb.app.InstrXData import InstrXData
3131

3232
from chb.arm.ARMDictionaryRecord import armregistry
33-
from chb.arm.ARMOpcode import ARMOpcode, simplify_result
33+
from chb.arm.ARMOpcode import ARMOpcode, ARMOpcodeXData, simplify_result
3434
from chb.arm.ARMOperand import ARMOperand
3535

3636
import chb.util.fileutil as UF
@@ -39,11 +39,49 @@
3939
from chb.astinterface.ASTInterface import ASTInterface
4040

4141
import chb.invariants.XXprUtil as XU
42-
4342
from chb.util.IndexedTable import IndexedTableValue
43+
from chb.util.loggingutil import chklogger
4444

4545
if TYPE_CHECKING:
46-
import chb.arm.ARMDictionary
46+
from chb.arm.ARMDictionary import ARMDictionary
47+
from chb.invariants.XVariable import XVariable
48+
from chb.invariants.XXpr import XXpr
49+
50+
51+
class ARMBitwiseExclusiveOrXData(ARMOpcodeXData):
52+
53+
def __init__(self, xdata: InstrXData) -> None:
54+
ARMOpcodeXData.__init__(self, xdata)
55+
56+
@property
57+
def vrd(self) -> "XVariable":
58+
return self.var(0, "vrd")
59+
60+
@property
61+
def xrn(self) -> "XXpr":
62+
return self.xpr(0, "xrn")
63+
64+
@property
65+
def xrm(self) -> "XXpr":
66+
return self.xpr(1, "xrm")
67+
68+
@property
69+
def result(self) -> "XXpr":
70+
return self.xpr(2, "result")
71+
72+
@property
73+
def rresult(self) -> "XXpr":
74+
return self.xpr(3, "rresult")
75+
76+
@property
77+
def result_simplified(self) -> str:
78+
return simplify_result(
79+
self.xdata.args[3], self.xdata.args[4], self.result, self.rresult)
80+
81+
@property
82+
def annotation(self) -> str:
83+
assignment = str(self.vrd) + " := " + self.result_simplified
84+
return self.add_instruction_condition(assignment)
4785

4886

4987
@armregistry.register_tag("EOR", ARMOpcode)
@@ -74,10 +112,7 @@ class ARMBitwiseExclusiveOr(ARMOpcode):
74112
useshigh[0]: lhs
75113
"""
76114

77-
def __init__(
78-
self,
79-
d: "chb.arm.ARMDictionary.ARMDictionary",
80-
ixval: IndexedTableValue) -> None:
115+
def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
81116
ARMOpcode.__init__(self, d, ixval)
82117
self.check_key(2, 5, "BitwiseExclusiveOr")
83118

@@ -95,18 +130,11 @@ def opargs(self) -> List[ARMOperand]:
95130
return [self.armd.arm_operand(i) for i in self.args[1: -1]]
96131

97132
def annotation(self, xdata: InstrXData) -> str:
98-
lhs = str(xdata.vars[0])
99-
result = xdata.xprs[2]
100-
rresult = xdata.xprs[3]
101-
xresult = simplify_result(xdata.args[3], xdata.args[4], result, rresult)
102-
assignment = lhs + " := " + xresult
103-
if xdata.has_unknown_instruction_condition():
104-
return "if ? then " + assignment
105-
elif xdata.has_instruction_condition():
106-
c = str(xdata.xprs[1])
107-
return "if " + c + " then " + assignment
133+
xd = ARMBitwiseExclusiveOrXData(xdata)
134+
if xd.is_ok:
135+
return xd.annotation
108136
else:
109-
return assignment
137+
return "Error value"
110138

111139
def ast_prov(
112140
self,
@@ -137,8 +165,14 @@ def ast_prov(
137165

138166
# high-level assignment
139167

140-
lhs = xdata.vars[0]
141-
rhs = xdata.xprs[3]
168+
xd = ARMBitwiseExclusiveOrXData(xdata)
169+
if not xd.is_ok:
170+
chklogger.logger.error(
171+
"Encountered error value at address %s", iaddr)
172+
return ([], [])
173+
174+
lhs = xd.vrd
175+
rhs = xd.rresult
142176
defuses = xdata.defuses
143177
defuseshigh = xdata.defuseshigh
144178

chb/arm/opcodes/ARMBitwiseNot.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def rresult(self) -> "XXpr":
7373
@property
7474
def result_simplified(self) -> str:
7575
return simplify_result(
76-
self.xdata.args[1], self.xdata.args[2], self.result, self.rresult)
76+
self.xdata.args[2], self.xdata.args[3], self.result, self.rresult)
7777

7878
@property
7979
def annotation(self) -> str:
@@ -158,6 +158,7 @@ def ast_prov(
158158
annotations=annotations)
159159

160160
# high-level assignment
161+
161162
xd = ARMBitwiseNotXData(xdata)
162163
if not xd.is_ok:
163164
chklogger.logger.error(

chb/arm/opcodes/ARMCompareBranchZero.py

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2024 Aarno Labs LLC
7+
# Copyright (c) 2021-2025 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
@@ -30,7 +30,7 @@
3030
from chb.app.InstrXData import InstrXData
3131

3232
from chb.arm.ARMDictionaryRecord import armregistry
33-
from chb.arm.ARMOpcode import ARMOpcode, simplify_result
33+
from chb.arm.ARMOpcode import ARMOpcode, ARMOpcodeXData, simplify_result
3434
from chb.arm.ARMOperand import ARMOperand
3535

3636
import chb.ast.ASTNode as AST
@@ -46,6 +46,41 @@
4646

4747
if TYPE_CHECKING:
4848
from chb.arm.ARMDictionary import ARMDictionary
49+
from chb.invariants.XXpr import XXpr
50+
51+
52+
class ARMCompareBranchZeroXData(ARMOpcodeXData):
53+
54+
def __init__(self, xdata: InstrXData) -> None:
55+
ARMOpcodeXData.__init__(self, xdata)
56+
57+
@property
58+
def xrn(self) -> "XXpr":
59+
return self.xpr(0, "xrn")
60+
61+
@property
62+
def txpr(self) -> "XXpr":
63+
return self.xpr(1, "txpr")
64+
65+
@property
66+
def fxpr(self) -> "XXpr":
67+
return self.xpr(2, "fxpr")
68+
69+
@property
70+
def tcond(self) -> "XXpr":
71+
return self.xpr(3, "tcond")
72+
73+
@property
74+
def fcond(self) -> "XXpr":
75+
return self.xpr(4, "fcond")
76+
77+
@property
78+
def xtgt(self) -> "XXpr":
79+
return self.xpr(5, "xtgt")
80+
81+
@property
82+
def annotation(self) -> str:
83+
return "if " + str(self.tcond) + " goto " + str(self.xtgt)
4984

5085

5186
@armregistry.register_tag("CBZ", ARMOpcode)
@@ -67,10 +102,7 @@ class ARMCompareBranchZero(ARMOpcode):
67102
xprs[5]: target
68103
"""
69104

70-
def __init__(
71-
self,
72-
d: "ARMDictionary",
73-
ixval: IndexedTableValue) -> None:
105+
def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
74106
ARMOpcode.__init__(self, d, ixval)
75107
self.check_key(1, 2, "CompareBranchZero")
76108

@@ -84,14 +116,22 @@ def opargs(self) -> List[ARMOperand]:
84116

85117
def ft_conditions(self, xdata: InstrXData) -> Sequence[XXpr]:
86118
if xdata.has_branch_conditions():
87-
return [xdata.xprs[4], xdata.xprs[3]]
119+
xd = ARMCompareBranchZeroXData(xdata)
120+
if xd.is_ok:
121+
return [xd.fcond, xd.tcond]
122+
else:
123+
chklogger.logger.warning(
124+
"CBZ: Encountered error condition at address")
125+
return []
88126
else:
89127
return []
90128

91129
def annotation(self, xdata: InstrXData) -> str:
92-
xpr = str(xdata.xprs[3])
93-
tgt = str(xdata.xprs[5])
94-
return "if " + xpr + " goto " + tgt
130+
xd = ARMCompareBranchZeroXData(xdata)
131+
if xd.is_ok:
132+
return xd.annotation
133+
else:
134+
return "Error value"
95135

96136
def ast_prov(
97137
self,

chb/arm/opcodes/ARMLoadRegister.py

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,6 @@ class ARMLoadRegisterXData(ARMOpcodeXData):
5656

5757
def __init__(self, xdata: InstrXData) -> None:
5858
ARMOpcodeXData.__init__(self, xdata)
59-
self._varnames = ["vrt", "vmem"]
60-
self._xprnames = ["xrn", "xrm", "xmem", "xrmem", "xaddr"]
61-
62-
@property
63-
def error_value_indices(self) -> Tuple[List[int], List[int]]:
64-
return self._xdata.error_values
65-
66-
@property
67-
def error_value_names(self) -> List[str]:
68-
result: List[str] = []
69-
(vars_e, xprs_e) = self.error_value_indices
70-
for i in vars_e:
71-
result.append(self._varnames[i])
72-
for i in xprs_e:
73-
result.append(self._xprnames[i])
74-
return result
7559

7660
@property
7761
def vrt(self) -> "XVariable":
@@ -102,19 +86,19 @@ def xaddr(self) -> "XXpr":
10286
return self.xpr(4, "xaddr")
10387

10488
@property
105-
def is_memval_unknown(self) -> bool:
106-
return "xrmem" in self.error_value_names
89+
def is_xrmem_unknown(self) -> bool:
90+
return self.xdata.xprs_r[3] is None
10791

10892
@property
10993
def is_address_known(self) -> bool:
110-
return "xaddr" not in self.error_value_names
94+
return self.xdata.xprs_r[4] is not None
11195

11296
@property
11397
def annotation(self) -> str:
11498
wbu = self.writeback_update()
11599
if self.is_ok:
116100
assignment = str(self.vrt) + " := " + str(self.xrmem)
117-
elif self.is_memval_unknown and self.is_address_known:
101+
elif self.is_xrmem_unknown and self.is_address_known:
118102
assignment = str(self.vrt) + " := *(" + str(self.xaddr) + ")"
119103
else:
120104
assignment = "Error value"
@@ -230,7 +214,7 @@ def ast_prov(
230214
hl_rhs = XU.xxpr_to_ast_def_expr(
231215
rhs, xdata, iaddr, astree, memaddr=xaddr)
232216

233-
elif xd.is_memval_unknown and xd.is_address_known:
217+
elif xd.is_xrmem_unknown and xd.is_address_known:
234218
xaddr = xd.xaddr
235219
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
236220
hl_rhs = XU.xmemory_dereference_lval_expr(

0 commit comments

Comments
 (0)