@@ -73,9 +73,11 @@ def __init__(
7373 self .expanded = False
7474 self ._vars : List [XVariable ] = []
7575 self ._vars_r : List [Optional [XVariable ]] = []
76+ self ._cvars_r : List [Optional [XVariable ]] = []
7677 self ._types : List ["BCTyp" ] = []
7778 self ._xprs : List [XXpr ] = []
7879 self ._xprs_r : List [Optional [XXpr ]] = []
80+ self ._cxprs_r : List [Optional [XXpr ]] = []
7981 self ._intervals : List [XInterval ] = []
8082 self ._strs : List [str ] = []
8183 self ._ints : List [int ] = []
@@ -128,6 +130,12 @@ def vars_r(self) -> List[Optional[XVariable]]:
128130 self ._expand ()
129131 return self ._vars_r
130132
133+ @property
134+ def cvars_r (self ) -> List [Optional [XVariable ]]:
135+ if not self .expanded :
136+ self ._expand ()
137+ return self ._cvars_r
138+
131139 @property
132140 def types (self ) -> List ["BCTyp" ]:
133141 if not self .expanded :
@@ -156,6 +164,17 @@ def get_var_x(self, index: int) -> Optional[XVariable]:
156164 + str (len (self .vars ))
157165 + ")" )
158166
167+ def get_cvar_r (self , index : int ) -> Optional [XVariable ]:
168+ if index < len (self .cvars_r ):
169+ return self .cvars_r [index ]
170+ else :
171+ raise UF .CHBError (
172+ "xdata: cvar-index out-of-bound: "
173+ + str (index )
174+ + " (length is "
175+ + str (len (self .cvars_r ))
176+ + ")" )
177+
159178 @property
160179 def xprs (self ) -> List [XXpr ]:
161180 if not self .expanded :
@@ -168,6 +187,12 @@ def xprs_r(self) -> List[Optional[XXpr]]:
168187 self ._expand ()
169188 return self ._xprs_r
170189
190+ @property
191+ def cxprs_r (self ) -> List [Optional [XXpr ]]:
192+ if not self .expanded :
193+ self ._expand ()
194+ return self ._cxprs_r
195+
171196 @property
172197 def intervals (self ) -> List [XInterval ]:
173198 if not self .expanded :
@@ -232,22 +257,60 @@ def is_ok(self) -> bool:
232257
233258 key = self .tags [0 ]
234259 if key .startswith ("ar:" ):
235- return all (self .vars_r ) and all (self .xprs_r )
260+ return all (self .vars_r ) and all (self .xprs_r ) and all ( self . cxprs_r )
236261 else :
237262 return True
238263
264+ def has_var_r (self , index : int ) -> bool :
265+ return index >= 0 and index < len (self .vars_r )
266+
267+ def is_var_ok (self , index : int ) -> bool :
268+ if self .has_var_r (index ):
269+ v = self .vars_r [index ]
270+ return v is not None
271+ return False
272+
273+ def has_cvar_r (self , index : int ) -> bool :
274+ return index >= 0 and index < len (self .cvars_r )
275+
276+ def is_cvar_ok (self , index : int ) -> bool :
277+ if self .has_cvar_r (index ):
278+ v = self .cvars_r [index ]
279+ return v is not None
280+ return False
281+
282+ def has_xpr_r (self , index : int ) -> bool :
283+ return index >= 0 and index < len (self .xprs_r )
284+
285+ def is_xpr_ok (self , index : int ) -> bool :
286+ if self .has_xpr_r (index ):
287+ x = self .xprs_r [index ]
288+ return x is not None
289+ return False
290+
291+ def has_cxpr_r (self , index : int ) -> bool :
292+ return index >= 0 and index < len (self .cxprs_r )
293+
294+ def is_cxpr_ok (self , index : int ) -> bool :
295+ if self .has_cxpr_r (index ):
296+ cx = self .cxprs_r [index ]
297+ return cx is not None
298+ return False
299+
239300 @property
240- def error_values (self ) -> Tuple [List [int ], List [int ]]:
301+ def error_values (self ) -> Tuple [List [int ], List [int ], List [ int ] ]:
241302
242303 key = self .tags [0 ]
243304 if key .startswith ("ar:" ):
244305 vars_e : List [int ] = [
245306 i for i in range (0 , len (self .vars_r )) if self .vars_r [i ] is None ]
246307 xprs_e : List [int ] = [
247308 i for i in range (0 , len (self .xprs_r )) if self .xprs_r [i ] is None ]
248- return (vars_e , xprs_e )
309+ cxprs_e : List [int ] = [
310+ i for i in range (0 , len (self .cxprs_r )) if self .cxprs_r [i ] is None ]
311+ return (vars_e , xprs_e , cxprs_e )
249312 else :
250- return ([], [])
313+ return ([], [], [] )
251314
252315
253316 def _expand (self ) -> None :
@@ -290,6 +353,12 @@ def _expand(self) -> None:
290353 else :
291354 self ._vars .append (xd .variable (arg ))
292355
356+ elif c == "w" :
357+ if arg == - 2 :
358+ self ._cvars_r .append (None )
359+ else :
360+ self ._cvars_r .append (xd .variable (arg ))
361+
293362 elif c == "x" :
294363 if use_result :
295364 if arg == - 2 :
@@ -299,6 +368,11 @@ def _expand(self) -> None:
299368 else :
300369 self ._xprs .append (xd .xpr (arg ))
301370
371+ elif c == "c" :
372+ if arg == - 2 :
373+ self ._cxprs_r .append (None )
374+ else :
375+ self ._cxprs_r .append (xd .xpr (arg ))
302376 elif c == "a" :
303377 self ._xprs .append (xd .xpr (arg ))
304378 elif c == "s" :
@@ -338,6 +412,7 @@ def is_function_argument(self) -> bool:
338412
339413 @property
340414 def function_argument_callsite (self ) -> AsmAddress :
415+ # Currently only used in x86
341416 if self .is_function_argument :
342417 return self .bdictionary .address (self .args [2 ])
343418 else :
@@ -474,6 +549,15 @@ def get_base_update_xpr(self) -> XXpr:
474549 def has_return_xpr (self ) -> bool :
475550 return any (s .startswith ("return:" ) for s in self .tags )
476551
552+ def has_return_cxpr (self ) -> bool :
553+ if any (s .startswith ("return:" ) for s in self .tags ):
554+ rvtag = next (t for t in self .tags if t .startswith ("return:" ))
555+ rvix = int (rvtag [7 :])
556+ rval = self .args [rvix + 2 ]
557+ return rval >= 0
558+ else :
559+ return False
560+
477561 def get_return_xpr (self ) -> XXpr :
478562 rvtag = next (t for t in self .tags if t .startswith ("return:" ))
479563 rvix = int (rvtag [7 :])
@@ -490,6 +574,14 @@ def get_return_xxpr(self) -> XXpr:
490574 raise UF .CHBError ("Unexpected error in rewritten return value" )
491575 return self .xprdictionary .xpr (rval )
492576
577+ def get_return_cxpr (self ) -> XXpr :
578+ rvtag = next (t for t in self .tags if t .startswith ("return:" ))
579+ rvix = int (rvtag [7 :])
580+ rval = self .args [rvix + 2 ]
581+ if rval == - 2 :
582+ raise UF .CHBError ("Unexpected error in C return value" )
583+ return self .xprdictionary .xpr (rval )
584+
493585 @property
494586 def is_aggregate_jumptable (self ) -> bool :
495587 return "agg-jt" in self .tags
0 commit comments