5151
5252
5353class ARMStoreRegisterHalfwordXData (ARMOpcodeXData ):
54+ """Data format:
55+ - variables:
56+ 0: vmem_r (lhs)
57+
58+ - c variables:
59+ 0: cvmem_r (lhs)
60+
61+ - expressions:
62+ 0: xrn
63+ 1: xrm
64+ 2: xrt (rhs)
65+ 3: xxrt (rhs, rewritten)
66+ 4: xaddr (lhs address)
67+ 5: xxaddr (lhs address, rewritten)
68+
69+ - c expressions:
70+ 0: cxrt (rhs)
71+ 1: cxaddr (lhs address)
72+ """
5473
5574 def __init__ (self , xdata : InstrXData ) -> None :
5675 ARMOpcodeXData .__init__ (self , xdata )
@@ -60,8 +79,16 @@ def vmem(self) -> "XVariable":
6079 return self .var (0 , "vmem" )
6180
6281 @property
63- def is_vmem_unknown (self ) -> bool :
64- return self .xdata .vars_r [0 ] is None
82+ def is_vmem_ok (self ) -> bool :
83+ return self .is_var_ok (0 )
84+
85+ @property
86+ def cvmem (self ) -> "XVariable" :
87+ return self .cvar (0 , "cvmem" )
88+
89+ @property
90+ def is_cvmem_ok (self ) -> bool :
91+ return self .is_cvar_ok (0 )
6592
6693 @property
6794 def xrn (self ) -> "XXpr" :
@@ -80,31 +107,65 @@ def xxrt(self) -> "XXpr":
80107 return self .xpr (3 , "xxrt" )
81108
82109 @property
83- def is_xxrt_known (self ) -> bool :
84- return self .xdata .xprs_r [3 ] is not None
110+ def is_xxrt_ok (self ) -> bool :
111+ return self .is_xpr_ok (3 )
112+
113+ @property
114+ def cxrt (self ) -> "XXpr" :
115+ return self .cxpr (0 , "cxrt" )
116+
117+ @property
118+ def is_cxrt_ok (self ) -> bool :
119+ return self .is_cxpr_ok (0 )
85120
86121 @property
87122 def xaddr (self ) -> "XXpr" :
88123 return self .xpr (4 , "xaddr" )
89124
90125 @property
91- def is_address_known (self ) -> bool :
92- return self .xdata .xprs_r [4 ] is not None
126+ def is_xaddr_ok (self ) -> "bool" :
127+ return self .is_xpr_ok (4 )
128+
129+ @property
130+ def xxaddr (self ) -> "XXpr" :
131+ return self .xpr (5 , "xxaddr" )
132+
133+ @property
134+ def is_xxaddr_ok (self ) -> bool :
135+ return self .is_xpr_ok (5 )
136+
137+ @property
138+ def cxaddr (self ) -> "XXpr" :
139+ return self .cxpr (1 , "cxaddr" )
140+
141+ @property
142+ def is_cxaddr_ok (self ) -> bool :
143+ return self .is_cxpr_ok (1 )
93144
94145 @property
95146 def annotation (self ) -> str :
96147 wbu = self .writeback_update ()
97- if self .is_ok :
98- assignment = str (self .vmem ) + " := " + str (self .xxrt )
99- elif not self .is_xxrt_known :
100- assignment = "(*" + str (self .xaddr ) + ") := " + str (self .xrt )
101- elif self .is_vmem_unknown and self .is_address_known :
102- assignment = "*(" + str (self .xaddr ) + ") := " + str (self .xxrt )
148+ clhs = str (self .cvmem ) if self .is_cvmem_ok else "None"
149+ crhs = str (self .cxrt ) if self .is_cxrt_ok else "None"
150+ assignc = "(C: " + clhs + " := " + crhs + ")"
151+ if self .is_vmem_ok :
152+ lhs = str (self .vmem )
153+ elif self .is_xxaddr_ok :
154+ lhs = "*(" + str (self .xxaddr ) + ")"
155+ elif self .is_xaddr_ok :
156+ lhs = "*(" + str (self .xaddr ) + ")"
157+ else :
158+ lhs = "Error addr"
159+ if self .is_xxrt_ok :
160+ rhs = str (self .xxrt )
103161 else :
104- assignment = "Error value"
162+ rhs = "Error value"
163+ assign = lhs + " := " + rhs
164+ assignment = assign + " " + assignc
105165 return self .add_instruction_condition (assignment + wbu )
106166
107167
168+
108169@armregistry .register_tag ("STRH" , ARMOpcode )
109170class ARMStoreRegisterHalfword (ARMOpcode ):
110171 """Stores the least significant halfword from a register into memory.
@@ -118,15 +179,8 @@ class ARMStoreRegisterHalfword(ARMOpcode):
118179 args[3]: index of memory location in armdictionary
119180 args[4]: is-wide (thumb)
120181
121- xdata format: a:vxxxxrrrdh
122- --------------------------
123- vars[0]: lhs
124- xprs[0]: xrn (base register)
125- xprs[1]: xrm (index)
126- xprs[2]: xrt (rhs, source register)
127- xprs[3]: xrt (rhs, simplified)
128- xprs[4]: address of memory location
129- xprs[5]: condition (if TC is set)
182+ xdata format:
183+ -------------
130184 rdefs[0]: rn
131185 rdefs[1]: rm
132186 rdefs[2]: rt
@@ -193,24 +247,40 @@ def ast_prov(
193247
194248 xd = ARMStoreRegisterHalfwordXData (xdata )
195249
196- if xd .is_ok :
250+ if xd .is_cvmem_ok :
251+ lhs = xd .cvmem
252+ hl_lhs = XU .xvariable_to_ast_lval (lhs , xdata , iaddr , astree )
253+
254+ elif xd .is_vmem_ok :
197255 lhs = xd .vmem
198- memaddr = xd .xaddr
199- hl_lhs = XU .xvariable_to_ast_lval (
200- lhs , xdata , iaddr , astree , memaddr = memaddr )
256+ hl_lhs = XU .xvariable_to_ast_lval (lhs , xdata , iaddr , astree )
201257
202- elif xd .is_vmem_unknown and xd .is_address_known :
258+ elif xd .is_cxaddr_ok :
259+ memaddr = xd .cxaddr
260+ hl_lhs = XU .xmemory_dereference_lval (memaddr , xdata , iaddr , astree )
261+
262+ elif xd .is_xxaddr_ok :
263+ memaddr = xd .xxaddr
264+ hl_lhs = XU .xmemory_dereference_lval (memaddr , xdata , iaddr , astree )
265+
266+ elif xd .is_xaddr_ok :
203267 memaddr = xd .xaddr
204268 hl_lhs = XU .xmemory_dereference_lval (memaddr , xdata , iaddr , astree )
205269
206270 else :
207271 chklogger .logger .error (
208272 "STRH: Lhs lval and address both have error values: skipping "
209- + "store instruction at address %s" ,
210- iaddr )
211- return ([], [])
273+ "store instruction at address %s" , iaddr )
274+ return ([], (ll_preinstrs + [ll_assign ] + ll_postinstrs ))
275+
276+ if xd .is_cxrt_ok :
277+ rhs = xd .cxrt
278+ elif xd .is_xxrt_ok :
279+ rhs = xd .xxrt
280+ else :
281+ rhs = xd .xrt
282+ hl_rhs = XU .xxpr_to_ast_def_expr (rhs , xdata , iaddr , astree )
212283
213- rhs = xd .xxrt
214284 rdefs = xdata .reachingdefs
215285 defuses = xdata .defuses
216286 defuseshigh = xdata .defuseshigh
@@ -228,7 +298,7 @@ def ast_prov(
228298 # to variables that are part of a struct or array variable, so these
229299 # assignments must be explicitly forced to appear in the lifting
230300 if (
231- xd .is_vmem_unknown
301+ ( not xd .is_vmem_ok )
232302 or lhs .is_memory_variable and cast ("VMemoryVariable" ,
233303 lhs .denotation ).base .is_basevar
234304 or hl_lhs .offset .is_index_offset
@@ -282,4 +352,4 @@ def ast_prov(
282352 ll_assigns = [ll_assign ]
283353 hl_assigns = [hl_assign ]
284354
285- return (hl_assigns , ll_assigns )
355+ return (hl_assigns , ( ll_preinstrs + ll_assigns + ll_postinstrs ) )
0 commit comments