Skip to content

Commit 44cad10

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

File tree

1 file changed

+90
-41
lines changed

1 file changed

+90
-41
lines changed

chb/arm/opcodes/ARMLoadRegister.py

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

5454

5555
class ARMLoadRegisterXData(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

99+
@property
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")
106+
107+
@property
108+
def is_cxrmem_ok(self) -> bool:
109+
return self.is_cxpr_ok(0)
110+
84111
@property
85112
def xaddr(self) -> "XXpr":
86113
return self.xpr(4, "xaddr")
87114

88115
@property
89-
def is_xrmem_unknown(self) -> bool:
90-
return self.xdata.xprs_r[3] is None
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)
91126

92127
@property
93-
def is_address_known(self) -> bool:
94-
return self.xdata.xprs_r[4] is not None
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)
95134

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
@@ -120,28 +170,12 @@ class ARMLoadRegister(ARMOpcode):
120170
121171
xdata format:
122172
-------------
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
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), add "bu" to tags
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__(self, d: "ARMDictionary", ixval: IndexedTableValue) -> None:
@@ -162,13 +196,20 @@ def opargs(self) -> List[ARMOperand]:
162196
return [self.armd.arm_operand(self.args[i]) for i in [0, 1, 2, 3]]
163197

164198
def lhs(self, xdata: InstrXData) -> List[XVariable]:
165-
return [xdata.vars[0]]
199+
xd = ARMLoadRegisterXData(xdata)
200+
return [xd.vrt]
166201

167202
def is_load_instruction(self, xdata: InstrXData) -> bool:
168203
return True
169204

170205
def rhs(self, xdata: InstrXData) -> List[XXpr]:
171-
return [xdata.xprs[1]]
206+
xd = ARMLoadRegisterXData(xdata)
207+
if xd.is_xrmem_ok:
208+
return [xd.xrmem]
209+
elif xd.is_xmem_ok:
210+
return [xd.xmem]
211+
else:
212+
return []
172213

173214
def annotation(self, xdata: InstrXData) -> str:
174215
"""lhs, rhs, with optional instr condition and base update."""
@@ -185,9 +226,7 @@ def ast_prov(
185226

186227
xd = ARMLoadRegisterXData(xdata)
187228

188-
memaddr = xd.xaddr
189-
190-
annotations: List[str] = [iaddr, "LDR", "addr: " + str(memaddr)]
229+
annotations: List[str] = [iaddr, "LDR"]
191230

192231
# low-level assignment
193232

@@ -213,24 +252,34 @@ def has_cast() -> bool:
213252
lhs = xd.vrt
214253

215254
if xd.is_ok:
216-
rhs = xd.xrmem
217-
rhsval = None if has_cast() else xd.xrmem
218-
xaddr = xd.xaddr
219-
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree, rhs=rhsval)
220-
hl_rhs = XU.xxpr_to_ast_def_expr(
221-
rhs, xdata, iaddr, astree, memaddr=xaddr)
255+
rhs = xd.cxrmem
256+
rhsval = None if has_cast() else xd.cxrmem
257+
hl_lhs = XU.xvariable_to_ast_lval(
258+
lhs, xdata, iaddr, astree, rhs=rhsval)
259+
hl_rhs = XU.xxpr_to_ast_def_expr(rhs, xdata, iaddr, astree)
260+
261+
elif xd.is_cxaddr_ok:
262+
cxaddr = xd.cxaddr
263+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
264+
hl_rhs = XU.xmemory_dereference_lval_expr(
265+
cxaddr, xdata, iaddr, astree)
222266

223-
elif xd.is_xrmem_unknown and xd.is_address_known:
267+
elif xd.is_xaddr_ok:
224268
xaddr = xd.xaddr
225269
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree)
226270
hl_rhs = XU.xmemory_dereference_lval_expr(
227271
xaddr, xdata, iaddr, astree)
228272

273+
chklogger.logger.warning(
274+
"LDR: Unable to use a C expression for rhs. Fall back to "
275+
+ "native byte-based address: %s to form rhs %s at address %s",
276+
str(xaddr), str(hl_rhs), iaddr)
277+
229278
else:
230279
chklogger.logger.error(
231280
"LDR: both memory value and address values are error values "
232281
+ "at address %s: ", iaddr)
233-
return ([], [])
282+
return ([], (ll_pre + [ll_assign] + ll_post))
234283

235284
rdefs = xdata.reachingdefs
236285
defuses = xdata.defuses

0 commit comments

Comments
 (0)