Skip to content

Commit c8e85d2

Browse files
committed
ARM:STR: update for conversion to C expressions
1 parent 44cad10 commit c8e85d2

File tree

1 file changed

+93
-64
lines changed

1 file changed

+93
-64
lines changed

chb/arm/opcodes/ARMStoreRegister.py

Lines changed: 93 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,25 @@
5757

5858

5959
class ARMStoreRegisterXData(ARMOpcodeXData):
60+
"""Data format:
61+
- variables:
62+
0: vmem_r (lhs)
63+
64+
- c variables:
65+
0: cvmem_r (lhs)
66+
67+
- expressions:
68+
0: xrn
69+
1: xrm
70+
2: xrt (rhs)
71+
3: xxrt (rhs, rewritten)
72+
4: xaddr (lhs address)
73+
5: xxaddr (lhs address, rewritten)
74+
75+
- c expressions:
76+
0: cxrt (rhs)
77+
1: cxaddr (lhs address)
78+
"""
6079

6180
def __init__(self, xdata: InstrXData) -> None:
6281
ARMOpcodeXData.__init__(self, xdata)
@@ -66,32 +85,16 @@ def vmem(self) -> "XVariable":
6685
return self.var(0, "vmem")
6786

6887
@property
69-
def is_vmem_known(self) -> bool:
70-
return self.xdata.vars_r[0] is not None
71-
72-
@property
73-
def is_vmem_unknown(self) -> bool:
74-
return self.xdata.vars_r[0] is None
75-
76-
@property
77-
def lhsvar(self) -> "XVariable":
78-
return self.var(1, "lhsvar")
79-
80-
@property
81-
def is_lhsvar_unknown(self) -> bool:
82-
return self.xdata.vars_r[1] is None
83-
84-
@property
85-
def is_lhsvar_known(self) -> bool:
86-
return self.xdata.vars_r[1] is not None
88+
def is_vmem_ok(self) -> bool:
89+
return self.is_var_ok(0)
8790

8891
@property
89-
def is_xxrtc_known(self) -> bool:
90-
return self.xdata.xprs_r[4] is not None
92+
def cvmem(self) -> "XVariable":
93+
return self.cvar(0, "cvmem")
9194

9295
@property
93-
def vrn(self) -> "XVariable":
94-
return self.var(1, "vrn")
96+
def is_cvmem_ok(self) -> bool:
97+
return self.is_cvar_ok(0)
9598

9699
@property
97100
def xrn(self) -> "XXpr":
@@ -110,31 +113,61 @@ def xxrt(self) -> "XXpr":
110113
return self.xpr(3, "xxrt")
111114

112115
@property
113-
def xxrtc(self) -> "XXpr":
114-
return self.xpr(4, "xxrtc")
116+
def is_xxrt_ok(self) -> bool:
117+
return self.is_xpr_ok(3)
118+
119+
@property
120+
def cxrt(self) -> "XXpr":
121+
return self.cxpr(0, "cxrt")
122+
123+
@property
124+
def is_cxrt_ok(self) -> bool:
125+
return self.is_cxpr_ok(0)
115126

116127
@property
117128
def xaddr(self) -> "XXpr":
118-
return self.xpr(5, "xaddr")
129+
return self.xpr(4, "xaddr")
130+
131+
@property
132+
def is_xaddr_ok(self) -> "bool":
133+
return self.is_xpr_ok(4)
134+
135+
@property
136+
def xxaddr(self) -> "XXpr":
137+
return self.xpr(5, "xxaddr")
119138

120139
@property
121-
def is_address_known(self) -> bool:
122-
return self.xdata.xprs_r[5] is not None
140+
def is_xxaddr_ok(self) -> bool:
141+
return self.is_xpr_ok(5)
123142

124143
@property
125-
def xaddr_updated(self) -> "XXpr":
126-
return self.xpr(6, "xaddr_updated")
144+
def cxaddr(self) -> "XXpr":
145+
return self.cxpr(1, "cxaddr")
146+
147+
@property
148+
def is_cxaddr_ok(self) -> bool:
149+
return self.is_cxpr_ok(1)
127150

128151
@property
129152
def annotation(self) -> str:
130153
wbu = self.writeback_update()
131-
rhs = self.xxrtc if self.is_xxrtc_known else self.xxrt
132-
if self.is_ok or self.is_vmem_known:
133-
assignment = str(self.vmem) + " := " + str(rhs)
134-
elif self.is_vmem_unknown and self.is_address_known:
135-
assignment = "*(" + str(self.xaddr) + ") := " + str(rhs)
154+
clhs = str(self.cvmem) if self.is_cvmem_ok else "None"
155+
crhs = str(self.cxrt) if self.is_cxrt_ok else "None"
156+
assignc = "(C: " + clhs + " := " + crhs + ")"
157+
if self.is_vmem_ok:
158+
lhs = str(self.vmem)
159+
elif self.is_xxaddr_ok:
160+
lhs = "*(" + str(self.xxaddr) + ")"
161+
elif self.is_xaddr_ok:
162+
lhs = "*(" + str(self.xaddr) + ")"
136163
else:
137-
assignment = "Error value"
164+
lhs = "Error addr"
165+
if self.is_xxrt_ok:
166+
rhs = str(self.xxrt)
167+
else:
168+
rhs = "Error value"
169+
assign = lhs + " := " + rhs
170+
assignment = assign + " " + assignc
138171
return self.add_instruction_condition(assignment + wbu)
139172

140173

@@ -153,14 +186,6 @@ class ARMStoreRegister(ARMOpcode):
153186
154187
xdata format
155188
------------
156-
vars[0]: lhs
157-
vars[1]: vrn (base register, only if writeback)
158-
xprs[0]: xrn (base register)
159-
xprs[1]: xrm (index)
160-
xprs[2]: xrt (rhs, source register)
161-
xprs[3]: xrt (rhs, simplified)
162-
xprs[4]: address of memory location
163-
xprs[5]: condition (if TC is set)
164189
rdefs[0]: rn
165190
rdefs[1]: rm
166191
rdefs[2]: rt
@@ -237,7 +262,6 @@ def ast_prov(
237262
xdata: InstrXData) -> Tuple[
238263
List[AST.ASTInstruction], List[AST.ASTInstruction]]:
239264

240-
xd = ARMStoreRegisterXData(xdata)
241265
annotations: List[str] = [iaddr, "STR"]
242266

243267
# low-level assignment
@@ -253,41 +277,46 @@ def ast_prov(
253277

254278
# high-level assignment
255279

256-
if xd.is_ok or xd.is_vmem_known:
280+
xd = ARMStoreRegisterXData(xdata)
281+
282+
if xd.is_cvmem_ok:
283+
lhs = xd.cvmem
284+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
285+
286+
elif xd.is_vmem_ok:
257287
lhs = xd.vmem
258-
memaddr = xd.xaddr
259-
hl_lhs = XU.xvariable_to_ast_lval(
260-
lhs, xdata, iaddr, astree, memaddr=memaddr)
288+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
261289

262-
elif xd.is_vmem_unknown and xd.is_lhsvar_known and xd.is_address_known:
263-
memaddr = xd.xaddr
264-
lhsvar = xd.lhsvar
265-
hl_lhs = XU.xvariable_to_ast_lval(
266-
lhsvar, xdata, iaddr, astree, memaddr=memaddr)
290+
elif xd.is_cxaddr_ok:
291+
memaddr = xd.cxaddr
292+
hl_lhs = XU.xmemory_dereference_lval(memaddr, xdata, iaddr, astree)
293+
294+
elif xd.is_xxaddr_ok:
295+
memaddr = xd.xxaddr
296+
hl_lhs = XU.xmemory_dereference_lval(memaddr, xdata, iaddr, astree)
267297

268-
elif xd.is_address_known:
298+
elif xd.is_xaddr_ok:
269299
memaddr = xd.xaddr
270300
hl_lhs = XU.xmemory_dereference_lval(memaddr, xdata, iaddr, astree)
271301

272302
else:
273303
chklogger.logger.error(
274304
"STR: Lhs lval and address both have error values: skipping "
275-
"store instruction at address %s",
276-
iaddr)
277-
return ([], [])
305+
"store instruction at address %s", iaddr)
306+
return ([], (ll_preinstrs + [ll_assign] + ll_postinstrs))
278307

279-
if xd.is_vmem_unknown:
280-
vmem = "unknown"
308+
if xd.is_cxrt_ok:
309+
rhs = xd.cxrt
310+
elif xd.is_xxrt_ok:
311+
rhs = xd.xxrt
281312
else:
282-
vmem = str(xd.vmem)
313+
rhs = xd.xrt
314+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
283315

284-
rhs = xd.xxrt
285316
rdefs = xdata.reachingdefs
286317
defuses = xdata.defuses
287318
defuseshigh = xdata.defuseshigh
288319

289-
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
290-
291320
if rhs.is_string_reference:
292321
rhsval = cast(XprConstant, rhs).intvalue
293322
saddr = hex(rhsval)
@@ -305,7 +334,7 @@ def ast_prov(
305334
# to variables that are part of a struct or array variable, so these
306335
# assignments must be explicitly forced to appear in the lifting
307336
if (
308-
xd.is_vmem_unknown
337+
(not xd.is_vmem_ok)
309338
or lhs.is_memory_variable and cast("VMemoryVariable",
310339
lhs.denotation).base.is_basevar
311340
or hl_lhs.offset.is_index_offset

0 commit comments

Comments
 (0)