Skip to content

Commit 93e3e1e

Browse files
committed
ARM:LDRB: update for conversion to C expressions
1 parent c762be5 commit 93e3e1e

File tree

2 files changed

+102
-43
lines changed

2 files changed

+102
-43
lines changed

chb/arm/opcodes/ARMLoadRegisterByte.py

Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@
5353

5454

5555
class ARMLoadRegisterByteXData(ARMOpcodeXData):
56+
"""Data format:
57+
- variables:
58+
0: vrt (lhs)
59+
60+
- expressions:
61+
0: xrn
62+
1: xrm
63+
2: xmem (rhs)
64+
3: xrmem (rhs, rewritten)
65+
4: xaddr (address of rhs)
66+
67+
- c expressions:
68+
0: cxrmem (rhs)
69+
1: cxaddr (address of rhs)
70+
"""
5671

5772
def __init__(self, xdata: InstrXData) -> None:
5873
ARMOpcodeXData.__init__(self, xdata)
@@ -61,10 +76,6 @@ def __init__(self, xdata: InstrXData) -> None:
6176
def vrt(self) -> "XVariable":
6277
return self.var(0, "vrt")
6378

64-
@property
65-
def vmem(self) -> "XVariable":
66-
return self.var(1, "vmem")
67-
6879
@property
6980
def xrn(self) -> "XXpr":
7081
return self.xpr(0, "xrn")
@@ -77,29 +88,68 @@ def xrm(self) -> "XXpr":
7788
def xmem(self) -> "XXpr":
7889
return self.xpr(2, "xmem")
7990

91+
@property
92+
def is_xmem_ok(self) -> bool:
93+
return self.is_xpr_ok(2)
94+
8095
@property
8196
def xrmem(self) -> "XXpr":
8297
return self.xpr(3, "xrmem")
8398

8499
@property
85-
def is_xrmem_unknown(self) -> bool:
86-
return self.xdata.xprs_r[3] is None
100+
def is_xrmem_ok(self) -> bool:
101+
return self.is_xpr_ok(3)
102+
103+
@property
104+
def cxrmem(self) -> "XXpr":
105+
return self.cxpr(0, "cxrmem")
87106

88107
@property
89-
def is_address_known(self) -> bool:
90-
return self.xdata.xprs_r[4] is not None
108+
def is_cxrmem_ok(self) -> bool:
109+
return self.is_cxpr_ok(0)
91110

92111
@property
93112
def xaddr(self) -> "XXpr":
94113
return self.xpr(4, "xaddr")
95114

115+
@property
116+
def is_xaddr_ok(self) -> bool:
117+
return self.is_xpr_ok(4)
118+
119+
@property
120+
def xxaddr(self) -> "XXpr":
121+
return self.xpr(5, "xxaddr")
122+
123+
@property
124+
def is_xxaddr_ok(self) -> bool:
125+
return self.is_xpr_ok(5)
126+
127+
@property
128+
def cxaddr(self) -> "XXpr":
129+
return self.cxpr(1, "cxaddr")
130+
131+
@property
132+
def is_cxaddr_ok(self) -> bool:
133+
return self.is_cxpr_ok(1)
134+
96135
@property
97136
def annotation(self) -> str:
98137
wbu = self.writeback_update()
99-
if self.is_ok:
100-
assignment = str(self.vrt) + " := " + str(self.xrmem)
101-
elif self.is_xrmem_unknown and self.is_address_known:
102-
assignment = str(self.vrt) + " := *(" + str(self.xaddr) + ")"
138+
if self.is_cxrmem_ok:
139+
crhs = str(self.cxrmem)
140+
elif self.is_cxaddr_ok:
141+
crhs = "*(" + str(self.cxaddr) + ")"
142+
else:
143+
crhs = "None"
144+
cx = " (C: " + crhs + ")"
145+
addr = str(self.xxaddr if self.is_xxaddr_ok else self.xaddr)
146+
caddr = str(self.cxaddr if self.is_cxaddr_ok else "None")
147+
caddr = " (addr: " + addr + "; C: " + caddr + ")"
148+
if self.is_ok or self.is_xrmem_ok:
149+
assignment = str(self.vrt) + " := " + str(self.xrmem) + cx + caddr
150+
elif self.is_xaddr_ok:
151+
assignment = (
152+
str(self.vrt) + " := *(" + str(self.xaddr) + ")" + cx + caddr)
103153
else:
104154
assignment = "Error value"
105155
return self.add_instruction_condition(assignment) + wbu
@@ -118,30 +168,14 @@ class ARMLoadRegisterByte(ARMOpcode):
118168
args[3]: index of memory location in armdictionary
119169
args[4]: is-wide (thumb)
120170
121-
xdata format: a:vxxxxrrrdh
122-
--------------------------
123-
vars[0]: lhs
124-
vars[1]: memory location expressed as a variable
125-
xprs[0]: value in rn
126-
xprs[1]: value in rm
127-
xprs[2]: value in memory location
128-
xprs[3]: value in memory location (simplified)
129-
xprs[4]: address of memory location
171+
xdata format:
172+
-------------
130173
rdefs[0]: reaching definitions rn
131174
rdefs[1]: reaching definitions rm
132175
rdefs[2]: reaching definitions memory location
133176
rdefs[3..]: reaching definitions for memory value
134177
uses[0]: use of lhs
135178
useshigh[0]: use of lhs at high level
136-
137-
optional:
138-
vars[2]: lhs base register (if base update)
139-
140-
xprs[.]: instruction condition (if has condition)
141-
xprs[.]: new address for base register
142-
143-
uses[1]: use of updated base register
144-
useshigh[1]: use of updated base register
145179
"""
146180

147181
def __init__(
@@ -165,13 +199,20 @@ def opargs(self) -> List[ARMOperand]:
165199
return [self.armd.arm_operand(self.args[i]) for i in [0, 1, 2, 3]]
166200

167201
def lhs(self, xdata: InstrXData) -> List[XVariable]:
168-
return [xdata.vars[0]]
202+
xd = ARMLoadRegisterByteXData(xdata)
203+
return [xd.vrt]
169204

170205
def is_load_instruction(self, xdata: InstrXData) -> bool:
171206
return True
172207

173208
def rhs(self, xdata: InstrXData) -> List[XXpr]:
174-
return [xdata.xprs[1]]
209+
xd = ARMLoadRegisterByteXData(xdata)
210+
if xd.is_xrmem_ok:
211+
return [xd.xrmem]
212+
elif xd.is_xmem_ok:
213+
return [xd.xmem]
214+
else:
215+
return []
175216

176217
def annotation(self, xdata: InstrXData) -> str:
177218
"""lhs, rhs, with optional instr condition and base update."""
@@ -188,9 +229,7 @@ def ast_prov(
188229

189230
xd = ARMLoadRegisterByteXData(xdata)
190231

191-
memaddr = xd.xaddr
192-
193-
annotations: List[str] = [iaddr, "LDRB", "addr:" + str(memaddr)]
232+
annotations: List[str] = [iaddr, "LDRB"]
194233

195234
# low-level assignment
196235

@@ -208,26 +247,42 @@ def ast_prov(
208247

209248
# high-level assignment
210249

250+
def has_cast() -> bool:
251+
return (
252+
astree.has_register_variable_intro(iaddr)
253+
and astree.get_register_variable_intro(iaddr).has_cast())
254+
211255
lhs = xd.vrt
212256

213257
if xd.is_ok:
214-
rhs = xd.xrmem
215-
xaddr = xd.xaddr
216-
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree, rhs=rhs)
217-
hl_rhs = XU.xxpr_to_ast_def_expr(
218-
rhs, xdata, iaddr, astree, size=1, memaddr=xaddr)
258+
rhs = xd.cxrmem
259+
rhsval = None if has_cast() else xd.cxrmem
260+
hl_lhs = XU.xvariable_to_ast_lval(
261+
lhs, xdata, iaddr, astree, rhs=rhsval)
262+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
263+
264+
elif xd.is_cxaddr_ok:
265+
cxaddr = xd.cxaddr
266+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
267+
hl_rhs = XU.xmemory_dereference_lval_expr(
268+
cxaddr, xdata, iaddr, astree)
219269

220-
elif xd.is_xrmem_unknown and xd.is_address_known:
270+
elif xd.is_xaddr_ok:
221271
xaddr = xd.xaddr
222272
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
223273
hl_rhs = XU.xmemory_dereference_lval_expr(
224-
xaddr, xdata, iaddr, astree, size=1)
274+
xaddr, xdata, iaddr, astree)
275+
276+
chklogger.logger.warning(
277+
"LDRB: Unable to use a C expression for rhs. Fall back to "
278+
+ "native byte-based address: %s to form rhs %s at address %s",
279+
str(xaddr), str(hl_rhs), iaddr)
225280

226281
else:
227282
chklogger.logger.error(
228283
"LDRB: both memory value and address values are error values "
229284
+ "at address %s: ", iaddr)
230-
return ([], [])
285+
return ([], (ll_pre + [ll_assign] + ll_post))
231286

232287
rdefs = xdata.reachingdefs
233288
defuses = xdata.defuses
@@ -240,6 +295,9 @@ def ast_prov(
240295
bytestring=bytestring,
241296
annotations=annotations)
242297

298+
if has_cast():
299+
astree.add_expose_instruction(hl_assign.instrid)
300+
243301
astree.add_instr_mapping(hl_assign, ll_assign)
244302
astree.add_instr_address(hl_assign, [iaddr])
245303
astree.add_expr_mapping(hl_rhs, ll_rhs)

chb/arm/opcodes/opcodes_covered.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,7 @@
10981098
]
10991099
},
11001100
"AST": "Y",
1101+
"ASTC": "Y",
11011102
"TC": "Y",
11021103
"A": "Y"
11031104
},

0 commit comments

Comments
 (0)