3838from chb .astinterface .ASTInterface import ASTInterface
3939
4040from chb .invariants .XXpr import XXpr
41-
41+ import chb . invariants . XXprUtil as XU
4242
4343import chb .util .fileutil as UF
4444from chb .util .loggingutil import chklogger
@@ -69,6 +69,14 @@ def xxtgt(self) -> "XXpr":
6969 def has_return_xpr (self ) -> bool :
7070 return self .xdata .has_return_xpr ()
7171
72+ @property
73+ def is_return_xpr_ok (self ) -> bool :
74+ return self .xdata .is_return_xpr_ok
75+
76+ @property
77+ def is_return_xxpr_ok (self ) -> bool :
78+ return self .xdata .is_return_xxpr_ok
79+
7280 def returnval (self ) -> "XXpr" :
7381 return self .xdata .get_return_xpr ()
7482
@@ -81,6 +89,18 @@ def has_creturnval(self) -> bool:
8189 def creturnval (self ) -> "XXpr" :
8290 return self .xdata .get_return_cxpr ()
8391
92+ def has_instruction_condition (self ) -> bool :
93+ return self .xdata .has_instruction_condition ()
94+
95+ def get_instruction_condition (self ) -> "XXpr" :
96+ return self .xdata .get_instruction_condition ()
97+
98+ def has_valid_instruction_c_condition (self ) -> bool :
99+ return self .xdata .has_valid_instruction_c_condition ()
100+
101+ def get_instruction_c_condition (self ) -> "XXpr" :
102+ return self .xdata .get_instruction_c_condition ()
103+
84104 @property
85105 def annotation (self ) -> str :
86106 if self .xdata .is_bx_call :
@@ -89,8 +109,10 @@ def annotation(self) -> str:
89109 cx = (" (C: "
90110 + (str (self .creturnval ()) if self .has_creturnval () else "None" )
91111 + ")" )
92- if self .is_ok :
112+ if self .is_return_xxpr_ok :
93113 return "return " + str (self .rreturnval ()) + cx
114+ elif self .is_return_xpr_ok :
115+ return "return " + str (self .returnval ()) + cx
94116 else :
95117 return "Error value"
96118 else :
@@ -126,11 +148,20 @@ def is_return_instruction(self, xdata: InstrXData) -> bool:
126148 else :
127149 return False
128150
151+ def is_conditional_return_instruction (self , xdata : InstrXData ) -> bool :
152+ if self .is_return_instruction (xdata ):
153+ return xdata .has_instruction_condition ()
154+ return False
155+
129156 def return_value (self , xdata : InstrXData ) -> Optional [XXpr ]:
130157 xd = ARMBranchExchangeXData (xdata )
131- if xd .has_creturnval ():
132- if xd .is_ok :
158+ if xd .has_return_xpr ():
159+ if xd .has_creturnval () :
133160 return xd .creturnval ()
161+ elif xd .is_return_xxpr_ok :
162+ return xd .rreturnval ()
163+ elif xd .is_return_xpr_ok :
164+ return xd .returnval ()
134165 else :
135166 chklogger .logger .warning (
136167 "Return value is an error value" )
@@ -174,6 +205,38 @@ def assembly_ast(
174205 """Need check for branch on LR, which should emit a return statement."""
175206 return []
176207
208+ def ast_condition_prov (
209+ self ,
210+ astree : ASTInterface ,
211+ iaddr : str ,
212+ bytestring : str ,
213+ xdata : InstrXData ,
214+ reverse : bool
215+ ) -> Tuple [Optional [AST .ASTExpr ], Optional [AST .ASTExpr ]]:
216+
217+ ll_astcond = self .ast_cc_expr (astree )
218+
219+ if xdata .has_instruction_condition ():
220+ xd = ARMBranchExchangeXData (xdata )
221+ if xd .has_valid_instruction_c_condition ():
222+ pcond = xd .get_instruction_c_condition ()
223+ else :
224+ pcond = xd .get_instruction_condition ()
225+ hl_astcond = XU .xxpr_to_ast_def_expr (pcond , xdata , iaddr , astree )
226+
227+ astree .add_expr_mapping (hl_astcond , ll_astcond )
228+ astree .add_expr_reachingdefs (hl_astcond , xdata .reachingdefs )
229+ astree .add_flag_expr_reachingdefs (ll_astcond , xdata .flag_reachingdefs )
230+ astree .add_condition_address (ll_astcond , [iaddr ])
231+
232+ return (hl_astcond , ll_astcond )
233+
234+ else :
235+ chklogger .logger .error (
236+ "No condition found at address %s" , iaddr )
237+ hl_astcond = astree .mk_temp_lval_expression ()
238+ return (hl_astcond , ll_astcond )
239+
177240 def ast_prov (
178241 self ,
179242 astree : ASTInterface ,
0 commit comments