@@ -68,7 +68,9 @@ class ARMCallOpcodeXData(ARMOpcodeXData):
6868 """
6969 xdata format: a:x[2n]xr[n]dh, call (n arguments)
7070 -------------------------------------------------
71- xprs[0..2n-1]: (arg location expr, arg value expr) * n
71+ xprs_r[0..n-1]: arg values
72+ xprs_r[n..2n-1]: register arg values
73+ cxprs_r[0..n-1]: arg value (C representation)
7274 xprs[2n]: call target expression
7375 rdefs[0..n-1]: arg location reaching definitions
7476 uses[0]: lhs
@@ -110,11 +112,58 @@ def arguments(self) -> List["XXpr"]:
110112 arguments .append (x )
111113 return arguments
112114
115+ @property
116+ def c_arguments (self ) -> List [Optional ["XXpr" ]]:
117+ argcount = self .argument_count
118+ c_args : List [Optional ["XXpr" ]] = []
119+ for i in range (argcount ):
120+ x = self ._xdata .cxprs_r [i ]
121+ c_args .append (x )
122+ return c_args
123+
124+ @property
125+ def cx_arguments (self ) -> List ["XXpr" ]:
126+ argcount = self .argument_count
127+ result : List ["XXpr" ] = []
128+ for i in range (argcount ):
129+ x = self .c_arguments [i ]
130+ if x is None :
131+ x = self .arguments [i ]
132+ result .append (x )
133+ return result
134+
113135 @property
114136 def argumentxvars (self ) -> List ["XXpr" ]:
115137 argcount = self .argument_count
116- return [x for x in self ._xdata .xprs_r [argcount :2 * argcount ]
117- if x is not None ]
138+ argvars : List ["XXpr" ] = []
139+ for i in range (argcount ):
140+ x = self ._xdata .xprs_r [i + argcount ]
141+ if x is None :
142+ raise UF .CHBError (
143+ "Unexpected None-value call argument at index "
144+ + str (i ))
145+ argvars .append (x )
146+ return argvars
147+
148+ def argument (self , index : int ) -> Tuple [Optional ["XXpr" ], Optional [str ]]:
149+ """Returns argument for (1-based) index."""
150+
151+ if index > self .argument_count :
152+ msg = (
153+ "argument index " + str (index ) + " exceeds argument count "
154+ + str (self .argument_count ))
155+ return (None , msg )
156+ if index <= 0 :
157+ msg = (
158+ "argument index " + str (index ) + " is invalid. A positive "
159+ + "value is expected" )
160+ return (None , msg )
161+ c_arg = self .c_arguments [index - 1 ]
162+ if c_arg is None :
163+ x_arg = self .arguments [index - 1 ]
164+ return (x_arg , "fall-back to x-expression" )
165+ else :
166+ return (c_arg , None )
118167
119168 @property
120169 def calltarget (self ) -> "CallTarget" :
@@ -124,7 +173,8 @@ def calltarget(self) -> "CallTarget":
124173 def annotation (self ) -> str :
125174 tgt = str (self .calltarget )
126175 args = ", " .join (str (x ) for x in self .arguments )
127- call = "call " + str (tgt ) + "(" + args + ")"
176+ cargs = " (C: (" + ", " .join (str (x ) for x in self .c_arguments ) + "))"
177+ call = "call " + str (tgt ) + "(" + args + ")" + cargs
128178 return self .add_instruction_condition (call )
129179
130180
@@ -310,15 +360,15 @@ def ast_call_prov(
310360 if len (astargtypes ) < argcount :
311361 astargtypes += ([None ] * (argcount - len (astargtypes )))
312362
313- xargs = xd .arguments
363+ xargs = xd .cx_arguments
314364 xvarargs = xd .argumentxvars
315365 if len (rdefs ) >= argcount :
316366 llrdefs = rdefs [:argcount ]
317367 # x represents the (invariant-enhanced) argument value.
318368 # xv represents the location of the argument, which can be
319369 # either a register, or a stack location, where the stack
320370 # location is represented by an expression of the form
321- # (sp + n), with n is the offset from the current stackpointer
371+ # (sp + n), where n is the offset from the current stackpointer
322372 # in bytes (note: not the stackpointer at function entry).
323373 # rdef represents the reaching definition for the argument
324374 # location.
0 commit comments