3232from chb .app .InstrXData import InstrXData
3333
3434from chb .arm .ARMDictionaryRecord import armregistry
35- from chb .arm .ARMOpcode import ARMOpcode , simplify_result
35+ from chb .arm .ARMOpcode import ARMOpcode , ARMOpcodeXData , simplify_result
3636from chb .arm .ARMOperand import ARMOperand
3737from chb .arm .ARMOperandKind import ARMOperandKind , ARMAbsoluteOp
3838
6464 from chb .invariants .XXpr import XXpr , XprConstant , XprVariable
6565
6666
67- class ARMCallOpcodeXData :
67+ class ARMCallOpcodeXData (ARMOpcodeXData ):
68+ """
69+ xdata format: a:x[2n]xr[n]dh, call (n arguments)
70+ -------------------------------------------------
71+ xprs[0..2n-1]: (arg location expr, arg value expr) * n
72+ xprs[2n]: call target expression
73+ rdefs[0..n-1]: arg location reaching definitions
74+ uses[0]: lhs
75+ useshigh[0]: lhs
76+ """
6877
6978 def __init__ (
7079 self ,
7180 xdata : InstrXData ,
7281 ixd : "InterfaceDictionary" ) -> None :
73- self . _xdata = xdata
82+ ARMOpcodeXData . __init__ ( self , xdata )
7483 self ._ixd = ixd
7584
7685 @property
77- def is_ok (self ) -> bool :
78- return self ._xdata . is_ok
86+ def vrd (self ) -> "XVariable" :
87+ return self .var ( 0 , "vrd" )
7988
8089 @property
8190 def argument_count (self ) -> int :
@@ -101,6 +110,12 @@ def arguments(self) -> List["XXpr"]:
101110 arguments .append (x )
102111 return arguments
103112
113+ @property
114+ def argumentxvars (self ) -> List ["XXpr" ]:
115+ argcount = self .argument_count
116+ return [x for x in self ._xdata .xprs_r [argcount :2 * argcount ]
117+ if x is not None ]
118+
104119 @property
105120 def calltarget (self ) -> "CallTarget" :
106121 return self ._xdata .call_target (self ._ixd )
@@ -109,7 +124,8 @@ def calltarget(self) -> "CallTarget":
109124 def annotation (self ) -> str :
110125 tgt = str (self .calltarget )
111126 args = ", " .join (str (x ) for x in self .arguments )
112- return "call " + str (tgt ) + "(" + args + ")"
127+ call = "call " + str (tgt ) + "(" + args + ")"
128+ return self .add_instruction_condition (call )
113129
114130
115131class ARMCallOpcode (ARMOpcode ):
@@ -118,15 +134,7 @@ class ARMCallOpcode(ARMOpcode):
118134 tags[1]: <c>
119135 args[0]: index of target operand in armdictionary
120136
121- xdata format: a:x[2n]xr[n]dh, call (n arguments)
122- -------------------------------------------------
123- xprs[0..2n-1]: (arg location expr, arg value expr) * n
124- xprs[2n]: call target expression
125- rdefs[0..n-1]: arg location reaching definitions
126- uses[0]: lhs
127- useshigh[0]: lhs
128-
129- or (if call target is not known):
137+ (if call target is not known):
130138 xdata format: a:xxxxx
131139 ---------------------
132140 vars[0]: return value variable
@@ -135,10 +143,7 @@ class ARMCallOpcode(ARMOpcode):
135143 rdefs[0]: target reaching definition
136144 """
137145
138- def __init__ (
139- self ,
140- d : "ARMDictionary" ,
141- ixval : IndexedTableValue ) -> None :
146+ def __init__ (self , d : "ARMDictionary" , ixval : IndexedTableValue ) -> None :
142147 ARMOpcode .__init__ (self , d , ixval )
143148
144149 @property
@@ -150,19 +155,10 @@ def opargs(self) -> List[ARMOperand]:
150155 return [self .armd .arm_operand (self .args [0 ])]
151156
152157 def lhs (self , xdata : InstrXData ) -> List [XVariable ]:
153- if len (xdata .vars ) > 0 :
154- return [xdata .vars [0 ]]
155- else :
156- return []
158+ return [ARMCallOpcodeXData (xdata , self .ixd ).vrd ]
157159
158160 def argument_count (self , xdata : InstrXData ) -> int :
159- if self .is_call_instruction (xdata ):
160- argcount = xdata .call_target_argument_count ()
161- if argcount is not None :
162- return argcount
163- chklogger .logger .warning (
164- "Call instruction does not have argument count" )
165- return 0
161+ return ARMCallOpcodeXData (xdata , self .ixd ).argument_count
166162
167163 def has_string_arguments (self , xdata : InstrXData ) -> bool :
168164 return any ([x .is_string_reference for x in self .arguments (xdata )])
@@ -175,7 +171,7 @@ def annotated_call_arguments(
175171 return [x .to_annotated_value () for x in self .arguments (xdata )]
176172
177173 def arguments (self , xdata : InstrXData ) -> Sequence [XXpr ]:
178- return xdata . xprs [: self .argument_count ( xdata )]
174+ return ARMCallOpcodeXData ( xdata , self .ixd ). arguments
179175
180176 def is_call (self , xdata : InstrXData ) -> bool :
181177 return len (xdata .tags ) >= 2 and xdata .tags [1 ] == "call"
@@ -206,11 +202,13 @@ def ast_call_prov(
206202 chklogger .logger .info ("Inlined call omitted at %s" , iaddr )
207203 return ([], [])
208204
205+ xd = ARMCallOpcodeXData (xdata , self .ixd )
206+
209207 annotations : List [str ] = [iaddr , "BL" ]
210208
211209 # low-level call data
212210
213- lhs = xdata . vars [ 0 ]
211+ lhs = xd . vrd
214212 tgt = self .opargs [0 ]
215213
216214 if not lhs .is_register_variable :
@@ -224,7 +222,7 @@ def ast_call_prov(
224222 ll_lhs = astree .mk_register_variable_lval (str (lhsreg ))
225223 (ll_tgt , _ , _ ) = tgt .ast_rvalue (astree )
226224
227- xprs = xdata . xprs
225+ xprs = xd . arguments
228226 rdefs = xdata .reachingdefs
229227 defuses = xdata .defuses
230228 defuseshigh = xdata .defuseshigh
@@ -284,7 +282,7 @@ def ast_call_prov(
284282
285283 # argument data
286284
287- argcount = self .argument_count ( xdata )
285+ argcount = xd .argument_count
288286
289287 ll_args : List [AST .ASTExpr ] = []
290288 hl_args : List [AST .ASTExpr ] = []
@@ -304,8 +302,8 @@ def ast_call_prov(
304302 if len (astargtypes ) < argcount :
305303 astargtypes += ([None ] * (argcount - len (astargtypes )))
306304
307- xargs = xdata . xprs [: argcount ]
308- xvarargs = xdata . xprs [ argcount :( 2 * argcount )]
305+ xargs = xd . arguments
306+ xvarargs = xd . argumentxvars
309307 if len (rdefs ) >= argcount :
310308 llrdefs = rdefs [:argcount ]
311309 # x represents the (invariant-enhanced) argument value.
@@ -316,7 +314,8 @@ def ast_call_prov(
316314 # in bytes (note: not the stackpointer at function entry).
317315 # rdef represents the reaching definition for the argument
318316 # location.
319- for (x , xv , rdef , argtype ) in zip (xargs , xvarargs , llrdefs , astargtypes ):
317+ for (x , xv , rdef , argtype ) in zip (
318+ xargs , xvarargs , llrdefs , astargtypes ):
320319
321320 # low-level argument
322321
0 commit comments