5353
5454
5555class 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 )
0 commit comments