@@ -403,16 +403,6 @@ object (self)
403403
404404 method memrecorder = mk_memory_recorder self#f self#cia
405405
406- (* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
407- * return values *
408- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
409- (*
410- method record_return_value =
411- let eax = self#env#mk_cpu_register_variable Eax in
412- let returnExpr = self#rewrite_variable_to_external eax in
413- self#f#record_return_value self#cia returnExpr
414- *)
415-
416406 (* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
417407 * call targets *
418408 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
@@ -643,11 +633,67 @@ object (self)
643633 * resolve and save IndReg (cpureg, offset) (memrefs1)
644634 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
645635
636+ method get_memory_variable_numoffset
637+ ?(align =1 )
638+ ?(size =4 )
639+ (var : variable_t )
640+ (numoffset : numerical_t ): variable_t traceresult =
641+ let inv = self#inv in
642+ if inv#is_base_offset_constant var then
643+ let (base, offset) = inv#get_base_offset_constant var in
644+ let memoffset = numoffset#add offset in
645+ TR. tmap
646+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__))
647+ (fun memref -> self#env#mk_memory_variable ~size memref memoffset)
648+ (self#env#mk_base_sym_reference base)
649+ else
650+ let varx =
651+ if align > 1 then
652+ let alignx = int_constant_expr align in
653+ XOp (XMult , [XOp (XDiv , [XVar var; alignx]); alignx])
654+ else
655+ XVar var in
656+ let addr = XOp (XPlus , [varx; num_constant_expr numoffset]) in
657+ let address = inv#rewrite_expr addr in
658+ match address with
659+ | XConst (IntConst n ) ->
660+ let dw = numerical_mod_to_doubleword n in
661+ if system_info#get_image_base#le dw then
662+ tprop
663+ (self#env#mk_global_variable ~size n)
664+ (__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : memref:global" )
665+ else
666+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
667+ ^ " Unable to convert constant value " ^ n#toString
668+ ^ " to a valid program address (should be greater than "
669+ ^ system_info#get_image_base#to_hex_string
670+ ^ " )" ]
671+ | _ ->
672+ let (memref_r, memoffset_r) = self#decompose_memaddr address in
673+ tbind
674+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__))
675+ (fun memref ->
676+ if memref#is_global_reference then
677+ tbind
678+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : memref:global" )
679+ (fun memoff ->
680+ self#env#mk_global_variable (get_total_constant_offset memoff))
681+ memoffset_r
682+ else
683+ tmap
684+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__))
685+ (fun memoff ->
686+ (self#env#mk_memory_variable
687+ memref (get_total_constant_offset memoff)))
688+ memoffset_r)
689+ memref_r
690+
691+
646692 method get_memory_variable_1
647693 ?(align =1 ) (* alignment of var value *)
648694 ?(size =4 )
649695 (var :variable_t )
650- (offset :numerical_t ) =
696+ (offset :numerical_t ): variable_t =
651697 let default () =
652698 self#env#mk_memory_variable
653699 (self#env#mk_unknown_memory_reference " memref-1" ) offset in
@@ -1120,6 +1166,136 @@ object (self)
11201166 Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
11211167 ^ " Unable to create global variable for " ^ (x2s addrvalue)]
11221168
1169+ method decompose_memaddr (x : xpr_t ):
1170+ (memory_reference_int traceresult * memory_offset_t traceresult) =
1171+ let is_external (v : variable_t ) = self#env#is_function_initial_value v in
1172+ let vars = vars_as_positive_terms x in
1173+ let knownpointers = List. filter self#f#is_base_pointer vars in
1174+ match knownpointers with
1175+ (* one known pointer, must be the base *)
1176+ | [base] ->
1177+ let offset = simplify_xpr (XOp (XMinus , [x; XVar base])) in
1178+ let memref_r = self#env#mk_base_variable_reference base in
1179+ let memoff_r =
1180+ (match offset with
1181+ | XConst (IntConst n ) -> Ok (ConstantOffset (n, NoOffset ))
1182+ | XOp (XMult, [XConst (IntConst n ); XVar v ]) ->
1183+ Ok (IndexOffset (v, n#toInt, NoOffset ))
1184+ | _ ->
1185+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1186+ ^ " Offset not recognized: " ^ (x2s offset)]) in
1187+ (memref_r, memoff_r)
1188+
1189+ (* no known pointers, have to find a base *)
1190+ | [] ->
1191+ let maxC = largest_constant_term x in
1192+ if maxC#gt system_info#get_image_base#to_numerical then
1193+ (* global base *)
1194+ let memref_r = Ok self#env#mk_global_memory_reference in
1195+ let offset = simplify_xpr (XOp (XMinus , [x; num_constant_expr maxC])) in
1196+ let gmemoff_r =
1197+ match offset with
1198+ | XConst (IntConst n ) -> Ok (ConstantOffset (n, NoOffset ))
1199+ | XOp (XMult, [XConst (IntConst n ); XVar v ]) ->
1200+ Ok (IndexOffset (v, n#toInt, NoOffset ))
1201+ | XOp (XMult , [XConst (IntConst n); x])
1202+ when self#is_composite_symbolic_value x ->
1203+ let v = self#env#mk_symbolic_value x in
1204+ Ok (IndexOffset (v, n#toInt, NoOffset ))
1205+ | _ ->
1206+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1207+ ^ " Offset not recognized: " ^ (x2s offset)] in
1208+ let memoff_r =
1209+ tmap
1210+ (fun gmemoff -> ConstantOffset (maxC, gmemoff))
1211+ gmemoff_r in
1212+ (memref_r, memoff_r)
1213+
1214+ else
1215+ (* find a candidate base pointer *)
1216+ (match vars with
1217+ | [base] when (self#is_initial_value_variable base)
1218+ || (is_external base) ->
1219+ let _ = self#f#add_base_pointer base in
1220+ let offset = simplify_xpr (XOp (XMinus , [x; XVar base])) in
1221+ let memref_r = self#env#mk_base_variable_reference base in
1222+ let memoff_r =
1223+ match offset with
1224+ | XConst (IntConst n ) -> Ok (ConstantOffset (n, NoOffset ))
1225+ | XOp (XMult, [XConst (IntConst n ); XVar v ]) ->
1226+ Ok (IndexOffset (v, n#toInt, NoOffset ))
1227+ | _ ->
1228+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1229+ ^ " Offset not recognized: " ^ (x2s offset)] in
1230+ (memref_r, memoff_r)
1231+
1232+ | [base] when (self#env#is_stack_parameter_variable base)
1233+ && (self#f#env#has_constant_offset base)
1234+ && (self#has_initial_value base) ->
1235+ let base_r =
1236+ TR. tmap
1237+ (fun baseInit ->
1238+ let _ = self#f#add_base_pointer baseInit in
1239+ baseInit)
1240+ (self#f#env#mk_initial_memory_value base) in
1241+ let memref_r =
1242+ TR. tbind
1243+ (fun base -> self#env#mk_base_variable_reference base)
1244+ base_r in
1245+ let memoff_r =
1246+ TR. tbind
1247+ (fun base ->
1248+ let offset = simplify_xpr (XOp (XMinus , [x; XVar base])) in
1249+ match offset with
1250+ | XConst (IntConst n ) -> Ok (ConstantOffset (n, NoOffset ))
1251+ | XOp (XMult, [XConst (IntConst n ); XVar v ]) ->
1252+ Ok (IndexOffset (v, n#toInt, NoOffset ))
1253+ | _ ->
1254+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1255+ ^ " Offset not recognized: " ^ (x2s offset)])
1256+ base_r in
1257+ (memref_r, memoff_r)
1258+
1259+ | [v] ->
1260+ let memref_r =
1261+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1262+ ^ " No candidate base pointers. Only variable found: "
1263+ ^ (p2s v#toPretty)] in
1264+ let memoff_r =
1265+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__)] in
1266+ (memref_r, memoff_r)
1267+
1268+ | [] ->
1269+ let memref_r =
1270+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1271+ ^ " No candidate pointers. Left with maxC: "
1272+ ^ maxC#toString] in
1273+ let memoff_r =
1274+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__)] in
1275+ (memref_r, memoff_r)
1276+
1277+ (* multiple variables *)
1278+ | _ ->
1279+ let memref_r =
1280+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1281+ ^ " Multiple variables: "
1282+ ^ (String. concat " ; "
1283+ (List. map (fun v -> p2s v#toPretty) vars))] in
1284+ let memoff_r =
1285+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__)] in
1286+ (memref_r, memoff_r))
1287+
1288+ (* multiple known pointers *)
1289+ | _ ->
1290+ let memref_r =
1291+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1292+ ^ " Multiple known pointers: "
1293+ ^ (String. concat " ; "
1294+ (List. map (fun v -> p2s v#toPretty) knownpointers))] in
1295+ let memoff_r =
1296+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__)] in
1297+ (memref_r, memoff_r)
1298+
11231299 (* the objective is to extract a base pointer and an offset expression
11241300 * first check whether the expression contains any variables that are known
11251301 * base pointers;
0 commit comments