5353
5454
5555class 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