Skip to content

Commit 9ca411c

Browse files
committed
ARM: convert annotations to handle result types
1 parent e56dba7 commit 9ca411c

File tree

8 files changed

+269
-117
lines changed

8 files changed

+269
-117
lines changed

chb/app/InstrXData.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,25 @@ def get_base_update_xpr(self) -> XXpr:
497497
"Unexpected error value in base-update expression")
498498
return self.xprdictionary.xpr(xbuval)
499499

500+
def has_return_xpr(self) -> bool:
501+
return any(s.startswith("return:") for s in self.tags)
502+
503+
def get_return_xpr(self) -> XXpr:
504+
rvtag = next(t for t in self.tags if t.startswith("return:"))
505+
rvix = int(rvtag[7:])
506+
rval = self.args[rvix]
507+
if rval == -2:
508+
raise UF.CHBError("Unexpected error in return value")
509+
return self.xprdictionary.xpr(rval)
510+
511+
def get_return_xxpr(self) -> XXpr:
512+
rvtag = next(t for t in self.tags if t.startswith("return:"))
513+
rvix = int(rvtag[7:])
514+
rval = self.args[rvix + 1]
515+
if rval == -2:
516+
raise UF.CHBError("Unexpected error in rewritten return value")
517+
return self.xprdictionary.xpr(rval)
518+
500519
@property
501520
def is_aggregate_jumptable(self) -> bool:
502521
return "agg-jt" in self.tags

chb/arm/ARMOpcode.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,22 +146,22 @@ def is_writeback(self) -> bool:
146146

147147
def get_base_update_var(self) -> "XVariable":
148148
if self.is_writeback:
149-
return self.get_base_update_var()
149+
return self.xdata.get_base_update_var()
150150
else:
151151
raise UF.CHBError(
152152
self.__class__.__name__ + " does not have writeback")
153153

154154
def get_base_update_xpr(self) -> "XXpr":
155155
if self.is_writeback:
156-
return self.get_base_update_xpr()
156+
return self.xdata.get_base_update_xpr()
157157
else:
158158
raise UF.CHBError(
159159
self.__class__.__name__ + " does not have writeback")
160160

161161
def writeback_update(self) -> str:
162162
if self.xdata.has_base_update():
163-
vbu = self.xdata.get_base_update_var()
164-
xbu = self.xdata.get_base_update_xpr()
163+
vbu = self.get_base_update_var()
164+
xbu = self.get_base_update_xpr()
165165
return "; " + str(vbu) + " := " + str(xbu)
166166
else:
167167
return ""

chb/arm/opcodes/ARMAdd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def rresult(self) -> "XXpr":
9797
@property
9898
def result_simplified(self) -> str:
9999
return simplify_result(
100-
self._xdata.args[3], self._xdata.args[4], self.result, self.rresult)
100+
self.xdata.args[3], self.xdata.args[4], self.result, self.rresult)
101101

102102
@property
103103
def xxrn(self) -> "XXpr":

chb/arm/opcodes/ARMBitwiseNot.py

Lines changed: 52 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.ast.ASTNode as AST
@@ -39,15 +39,50 @@
3939
import chb.invariants.XXprUtil as XU
4040

4141
import chb.util.fileutil as UF
42-
4342
from chb.util.IndexedTable import IndexedTableValue
43+
from chb.util.loggingutil import chklogger
44+
4445

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

4883

4984
@armregistry.register_tag("MVN", ARMOpcode)
50-
class ARMBitwiseBitwiseNot(ARMOpcode):
85+
class ARMBitwiseNot(ARMOpcode):
5186
"""Bitwise inverse of a register or immediate value.
5287
5388
MVN{S}<c> <Rd>, <Rm> {, <shift>}
@@ -70,10 +105,7 @@ class ARMBitwiseBitwiseNot(ARMOpcode):
70105
useshigh[0]: lhs
71106
"""
72107

73-
def __init__(
74-
self,
75-
d: "ARMDictionary",
76-
ixval: IndexedTableValue) -> None:
108+
def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
77109
ARMOpcode.__init__(self, d, ixval)
78110
self.check_key(2, 4, "BitwiseNot")
79111

@@ -96,18 +128,11 @@ def is_writeback(self) -> bool:
96128
return self.args[0] == 1
97129

98130
def annotation(self, xdata: InstrXData) -> str:
99-
lhs = str(xdata.vars[0])
100-
result = xdata.xprs[1]
101-
rresult = xdata.xprs[2]
102-
xresult = simplify_result(xdata.args[2], xdata.args[1], result, rresult)
103-
assignment = lhs + " := " + xresult
104-
if xdata.has_unknown_instruction_condition():
105-
return "if ? then " + assignment
106-
elif xdata.has_instruction_condition():
107-
c = str(xdata.xprs[1])
108-
return "if " + c + " then " + assignment
131+
xd = ARMBitwiseNotXData(xdata)
132+
if xd.is_ok:
133+
return xd.annotation
109134
else:
110-
return assignment
135+
return "Error value"
111136

112137
def ast_prov(
113138
self,
@@ -133,9 +158,15 @@ def ast_prov(
133158
annotations=annotations)
134159

135160
# high-level assignment
161+
xd = ARMBitwiseNotXData(xdata)
162+
if not xd.is_ok:
163+
chklogger.logger.error(
164+
"Encountered error value at address %s", iaddr)
165+
return ([], [])
166+
167+
lhs = xd.vrd
168+
rhs = xd.rresult
136169

137-
lhs = xdata.vars[0]
138-
rhs = xdata.xprs[2]
139170
rdefs = xdata.reachingdefs
140171
defuses = xdata.defuses
141172
defuseshigh = xdata.defuseshigh

chb/arm/opcodes/ARMBitwiseOrNot.py

Lines changed: 64 additions & 45 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-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
@@ -39,11 +39,54 @@
3939
import chb.invariants.XXprUtil as XU
4040

4141
import chb.util.fileutil as UF
42-
4342
from chb.util.IndexedTable import IndexedTableValue
43+
from chb.util.loggingutil import chklogger
44+
4445

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

4891

4992
@armregistry.register_tag("ORN", ARMOpcode)
@@ -74,10 +117,7 @@ class ARMBitwiseOrNot(ARMOpcode):
74117
useshigh[0]: lhs
75118
"""
76119

77-
def __init__(
78-
self,
79-
d: "chb.arm.ARMDictionary.ARMDictionary",
80-
ixval: IndexedTableValue) -> None:
120+
def __init__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
81121
ARMOpcode.__init__(self, d, ixval)
82122
self.check_key(2, 4, "BitwiseOrNot")
83123

@@ -99,18 +139,11 @@ def is_writeback(self) -> bool:
99139
return self.args[0] == 1
100140

101141
def annotation(self, xdata: InstrXData) -> str:
102-
lhs = str(xdata.vars[0])
103-
result = xdata.xprs[3]
104-
rresult = xdata.xprs[4]
105-
xresult = simplify_result(xdata.args[4], xdata.args[5], result, rresult)
106-
assignment = lhs + " := " + xresult
107-
if xdata.has_unknown_instruction_condition():
108-
return "if ? then " + assignment
109-
elif xdata.has_instruction_condition():
110-
c = str(xdata.xprs[1])
111-
return "if " + c + " then " + assignment
142+
xd = ARMBitwiseOrNotXData(xdata)
143+
if xd.is_ok:
144+
return xd.annotation
112145
else:
113-
return assignment
146+
return "Error value"
114147

115148
def ast_prov(
116149
self,
@@ -122,14 +155,6 @@ def ast_prov(
122155

123156
annotations: List[str] = [iaddr, "ORN"]
124157

125-
lhs = xdata.vars[0]
126-
rhs1 = xdata.xprs[0]
127-
rhs2 = xdata.xprs[1]
128-
rhs4 = xdata.xprs[4]
129-
rdefs = xdata.reachingdefs
130-
defuses = xdata.defuses
131-
defuseshigh = xdata.defuseshigh
132-
133158
(ll_lhs, _, _) = self.opargs[0].ast_lvalue(astree)
134159
(ll_op1, _, _) = self.opargs[1].ast_rvalue(astree)
135160
(ll_op2, _, _) = self.opargs[2].ast_rvalue(astree)
@@ -143,27 +168,21 @@ def ast_prov(
143168
bytestring=bytestring,
144169
annotations=annotations)
145170

146-
lhsasts = XU.xvariable_to_ast_lvals(lhs, xdata, astree)
147-
if len(lhsasts) == 0:
148-
raise UF.CHBError("BitwiseOrNot (ORN): no lval found")
149-
150-
if len(lhsasts) > 1:
151-
raise UF.CHBError(
152-
"BitwiseOrNot (ORN): multiple lvals found: "
153-
+ ", ".join(str(v) for v in lhsasts))
154-
155-
hl_lhs = lhsasts[0]
171+
xd = ARMBitwiseOrNotXData(xdata)
172+
if not xd.is_ok:
173+
chklogger.logger.error(
174+
"Encountered error value at address %s", iaddr)
175+
return ([], [])
156176

157-
rhsasts = XU.xxpr_to_ast_def_exprs(rhs4, xdata, iaddr, astree)
158-
if len(rhsasts) == 0:
159-
raise UF.CHBError("BitwiseOrNot (ORN): no lval found")
177+
lhs = xd.vrd
178+
rhs = xd.rresult
160179

161-
if len(rhsasts) > 1:
162-
raise UF.CHBError(
163-
"BitwiseOrNot (ORN): multiple rhs values found: "
164-
+ ", ".join(str(v) for v in rhsasts))
180+
rdefs = xdata.reachingdefs
181+
defuses = xdata.defuses
182+
defuseshigh = xdata.defuseshigh
165183

166-
hl_rhs = rhsasts[0]
184+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
185+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
167186

168187
hl_assign = astree.mk_assign(
169188
hl_lhs,

0 commit comments

Comments
 (0)