4949 from chb .invariants .VConstantValueVariable import (
5050 VInitialRegisterValue , VInitialMemoryValue , VFunctionReturnValue ,
5151 SymbolicValue , MemoryAddress )
52- from chb .invariants .VMemoryBase import VMemoryBaseBaseArray
52+ from chb .invariants .VMemoryBase import (
53+ VMemoryBase , VMemoryBaseBaseArray , VMemoryBaseBaseStruct )
5354 from chb .invariants .VMemoryOffset import (
5455 VMemoryOffset ,
5556 VMemoryOffsetConstantOffset ,
5960 from chb .mips .MIPSRegister import MIPSRegister
6061
6162
63+ def prdebug (
64+ s : str , iaddr : Optional [str ] = None , iaddrs : List [str ] = []) -> None :
65+ if iaddr is None :
66+ print ("DEBUG: " + s )
67+ elif iaddr in iaddrs :
68+ print ("DEBUG: " + iaddr + ": " + s )
69+ else :
70+ None
71+
72+
6273def is_struct_field_address (xpr : X .XXpr , astree : ASTInterface ) -> bool :
6374 """Return true if the expression is the address of a known struct."""
6475
@@ -254,6 +265,37 @@ def vreturn_deref_value_to_ast_lval_expression(
254265 return astree .mk_temp_lval_expression ()
255266
256267
268+ def memory_variable_to_lval_expression (
269+ base : "VMemoryBase" ,
270+ offset : "VMemoryOffset" ,
271+ xdata : "InstrXData" ,
272+ iaddr : str ,
273+ astree : ASTInterface ,
274+ size : int = 4 ) -> AST .ASTExpr :
275+
276+ name = str (base )
277+
278+ if not astree .globalsymboltable .has_symbol (name ):
279+ chklogger .logger .error (
280+ "AST conversion of memory variable %s not in global symbol "
281+ + "table not yet supported at address %s" ,
282+ name , iaddr )
283+ return astree .mk_temp_lval_expression ()
284+
285+ vinfo = astree .globalsymboltable .get_symbol (name )
286+ if offset .is_field_offset :
287+ offset = cast ("VMemoryOffsetFieldOffset" , offset )
288+ astoffset = field_offset_to_ast_offset (offset , xdata , iaddr , astree )
289+ return astree .mk_vinfo_lval_expression (vinfo , astoffset )
290+
291+ chklogger .logger .error (
292+ "AST conversion of memory variable %s with other offset not yet "
293+ + "supported at address %s" ,
294+ name , iaddr )
295+
296+ return astree .mk_temp_lval_expression ()
297+
298+
257299def global_variable_to_lval_expression (
258300 offset : "VMemoryOffset" ,
259301 xdata : "InstrXData" ,
@@ -565,6 +607,11 @@ def xvariable_to_ast_def_lval_expression(
565607 return global_variable_to_lval_expression (
566608 memvar .offset , xdata , iaddr , astree )
567609
610+ if xvar .is_memory_variable :
611+ memvar = cast ("VMemoryVariable" , xvar .denotation )
612+ return memory_variable_to_lval_expression (
613+ memvar .base , memvar .offset , xdata , iaddr , astree )
614+
568615 if xvar .is_local_stack_variable :
569616 stackvar = cast ("VMemoryVariable" , xvar .denotation )
570617 offset = stackvar .offset .offsetvalue ()
@@ -826,6 +873,7 @@ def default() -> AST.ASTExpr:
826873
827874 if hl_addr .is_ast_lval_expr :
828875 hl_addr_type = hl_addr .ctype (astree .ctyper )
876+
829877 if hl_addr_type is None :
830878 return default ()
831879
@@ -845,6 +893,11 @@ def default() -> AST.ASTExpr:
845893 else :
846894 return default ()
847895
896+ if hl_addr .is_ast_addressof :
897+ hl_addr = cast (AST .ASTAddressOf , hl_addr )
898+ hl_lval = hl_addr .lval
899+ return astree .mk_lval_expr (hl_lval )
900+
848901 if hl_addr .is_ast_binary_op :
849902 hl_addr = cast (AST .ASTBinaryOp , hl_addr )
850903
@@ -980,7 +1033,6 @@ def stack_variable_to_ast_lval(
9801033
9811034
9821035def array_offset_to_ast_offset (
983- elementtyp : AST .ASTTyp ,
9841036 offset : "VMemoryOffsetArrayIndexOffset" ,
9851037 xdata : "InstrXData" ,
9861038 iaddr : str ,
@@ -1001,7 +1053,36 @@ def to_ast_offset(suboffset: "VMemoryOffset") -> AST.ASTOffset:
10011053 else :
10021054 return nooffset
10031055
1004- return astree .mk_expr_index_offset (indexxpr , offset = to_ast_offset (offset .offset ))
1056+ return astree .mk_expr_index_offset (
1057+ indexxpr , offset = to_ast_offset (offset .offset ))
1058+
1059+
1060+ def field_offset_to_ast_offset (
1061+ offset : "VMemoryOffsetFieldOffset" ,
1062+ xdata : "InstrXData" ,
1063+ iaddr : str ,
1064+ astree : ASTInterface ) -> AST .ASTOffset :
1065+
1066+ if offset .has_no_offset ():
1067+ return astree .mk_field_offset (offset .fieldname , offset .ckey )
1068+
1069+ if offset .offset .is_field_offset :
1070+ fieldoffset = cast ("VMemoryOffsetFieldOffset" , offset .offset )
1071+ suboffset = field_offset_to_ast_offset (
1072+ fieldoffset , xdata , iaddr , astree )
1073+ elif offset .offset .is_array_index_offset :
1074+ arrayindexoffset = cast ("VMemoryOffsetArrayIndexOffset" , offset .offset )
1075+ suboffset = array_offset_to_ast_offset (
1076+ arrayindexoffset , xdata , iaddr , astree )
1077+ elif offset .offset .is_constant_value_offset :
1078+ suboffset = astree .mk_scalar_index_offset (offset .offset .offsetvalue ())
1079+ else :
1080+ suboffset = nooffset
1081+
1082+ return astree .mk_field_offset (
1083+ offset .fieldname , offset .ckey , offset = suboffset )
1084+
1085+
10051086
10061087def array_variable_to_ast_lval (
10071088 base : "MemoryAddress" ,
@@ -1035,7 +1116,6 @@ def array_variable_to_ast_lval(
10351116 return astree .mk_temp_lval ()
10361117
10371118 astoffset = array_offset_to_ast_offset (
1038- elementtyp ,
10391119 cast ("VMemoryOffsetArrayIndexOffset" , offset ),
10401120 xdata ,
10411121 iaddr ,
@@ -1050,6 +1130,46 @@ def array_variable_to_ast_lval(
10501130 return astree .mk_temp_lval ()
10511131
10521132
1133+ def struct_variable_to_ast_lval (
1134+ base : "MemoryAddress" ,
1135+ structtyp : AST .ASTTypComp ,
1136+ offset : "VMemoryOffset" ,
1137+ xdata : "InstrXData" ,
1138+ iaddr : str ,
1139+ astree : ASTInterface ) -> AST .ASTLval :
1140+
1141+ name = base .name
1142+ if name is None :
1143+ chklogger .logger .error (
1144+ "AST conversion of struct variable at %s encountered nameless "
1145+ + "base %s" ,
1146+ str (iaddr ), str (base ))
1147+ return astree .mk_temp_lval ()
1148+
1149+ if not astree .globalsymboltable .has_symbol (name ):
1150+ chklogger .logger .error (
1151+ "AST conversion of memory address value %s not in global symbol "
1152+ + " table not yet supported at address %s" ,
1153+ str (name ), iaddr )
1154+ return astree .mk_temp_lval ()
1155+
1156+ vinfo = astree .globalsymboltable .get_symbol (name )
1157+ if not offset .is_field_offset :
1158+ chklogger .logger .error (
1159+ "AST conversion of struct variable expected to find field offset "
1160+ + "but found %s at address %s" ,
1161+ str (offset ), iaddr )
1162+ return astree .mk_temp_lval ()
1163+
1164+ astoffset = field_offset_to_ast_offset (
1165+ cast ("VMemoryOffsetFieldOffset" , offset ),
1166+ xdata ,
1167+ iaddr ,
1168+ astree )
1169+
1170+ return astree .mk_vinfo_lval (vinfo , offset = astoffset )
1171+
1172+
10531173def global_variable_to_ast_lval (
10541174 offset : "VMemoryOffset" ,
10551175 xdata : "InstrXData" ,
@@ -1190,8 +1310,8 @@ def xvariable_to_ast_lval(
11901310
11911311 elif (
11921312 xv .is_memory_variable
1193- and cast ("VMemoryVariable" ,
1194- xv .denotation ).base .is_basearray ):
1313+ and cast ("VMemoryVariable" ,
1314+ xv .denotation ).base .is_basearray ):
11951315 xvmem = cast ("VMemoryVariable" , xv .denotation )
11961316 base = cast ("VMemoryBaseBaseArray" , xvmem .base ).basearray
11971317 if not base .is_memory_address_value :
@@ -1209,6 +1329,27 @@ def xvariable_to_ast_lval(
12091329 iaddr ,
12101330 astree )
12111331
1332+ elif (
1333+ xv .is_memory_variable
1334+ and cast ("VMemoryVariable" ,
1335+ xv .denotation ).base .is_basestruct ):
1336+ xvmem = cast ("VMemoryVariable" , xv .denotation )
1337+ base = cast ("VMemoryBaseBaseStruct" , xvmem .base ).basestruct
1338+ if not base .is_memory_address_value :
1339+ chklogger .logger .error (
1340+ "AST conversion of lval %s encountered invalie BaseStruct at %s" ,
1341+ str (xv ), iaddr )
1342+ return astree .mk_temp_lval ()
1343+ basevar = cast ("MemoryAddress" , base .denotation .auxvar )
1344+ basetyp = cast ("VMemoryBaseBaseStruct" , xvmem .base ).basetyp .convert (astree .typconverter )
1345+ return struct_variable_to_ast_lval (
1346+ basevar ,
1347+ cast (AST .ASTTypComp , basetyp ),
1348+ xvmem .offset ,
1349+ xdata ,
1350+ iaddr ,
1351+ astree )
1352+
12121353 else :
12131354 chklogger .logger .error (
12141355 "AST conversion of lval %s at address %s not yet supported" ,
0 commit comments