5757
5858
5959class 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