44 ------------------------------------------------------------------------------
55 The MIT License (MIT)
66
7- Copyright (c) 2024 Aarno Labs LLC
7+ Copyright (c) 2024-2025 Aarno Labs LLC
88
99 Permission is hereby granted, free of charge, to any person obtaining a copy
1010 of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,7 @@ open CHPretty
3232
3333(* chutil *)
3434open CHLogger
35+ open CHTraceResult
3536
3637(* xprlib *)
3738open XprTypes
@@ -126,6 +127,9 @@ object (self)
126127 | [vinv] -> vinv#get_reaching_defs
127128 | _ -> [] ) in
128129
130+ let get_variable_rdefs_r (v_r : variable_t traceresult ): symbol_t list =
131+ TR. tfold_default get_variable_rdefs [] v_r in
132+
129133 let get_variable_defuses (v : variable_t ): symbol_t list =
130134 let symvar = floc#f#env#mk_symbolic_variable v in
131135 let varinvs = floc#varinv#get_var_def_uses symvar in
@@ -137,6 +141,9 @@ object (self)
137141 let defuses = get_variable_defuses v in
138142 List. exists (fun s -> s#getBaseName = " exit" ) defuses in
139143
144+ let has_exit_use_r (v_r : variable_t traceresult ): bool =
145+ TR. tfold_default has_exit_use false v_r in
146+
140147 let getopt_initial_argument_value (x : xpr_t ): (register_t * int) option =
141148 match (rewrite_expr x) with
142149 | XVar v when floc#f#env#is_initial_arm_argument_value v ->
@@ -148,6 +155,10 @@ object (self)
148155 n#toInt)
149156 | _ -> None in
150157
158+ let getopt_initial_argument_value_r
159+ (x_r : xpr_t traceresult ): (register_t * int) option =
160+ TR. tfold_default getopt_initial_argument_value None x_r in
161+
151162 let getopt_stackaddress (x : xpr_t ): int option =
152163 match (rewrite_expr x) with
153164 | XOp (xop, [XVar v; XConst (IntConst n)])
@@ -167,6 +178,9 @@ object (self)
167178 (floc#f#env#get_initial_register_value_register v)
168179 | _ -> None in
169180
181+ let getopt_stackaddress_r (x_r : xpr_t traceresult ): int option =
182+ TR. tfold_default getopt_stackaddress None x_r in
183+
170184 let getopt_global_address (x : xpr_t ): doubleword_int option =
171185 match (rewrite_expr x) with
172186 | XConst (IntConst num ) ->
@@ -178,6 +192,9 @@ object (self)
178192 | _ ->
179193 None in
180194
195+ let getopt_global_address_r (x_r : xpr_t traceresult ): doubleword_int option =
196+ TR. tfold_default getopt_global_address None x_r in
197+
181198 let log_subtype_constraint
182199 (kind : string ) (ty1 : type_term_t ) (ty2 : type_term_t ) =
183200 let tag = " add " ^ kind ^ " subtype constraint" in
@@ -208,13 +225,13 @@ object (self)
208225 match instr#get_opcode with
209226
210227 | Add (_ , _ , rd , rn , rm , _ ) ->
211- let xrn = rn#to_expr floc in
228+ let xrn_r = rn#to_expr floc in
212229 begin
213230
214231 (if rm#is_immediate && (rm#to_numerical#toInt < 256 ) then
215232 let rdreg = rd#to_register in
216233 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
217- let rndefs = get_variable_rdefs (rn#to_variable floc) in
234+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
218235 let rnreg = rn#to_register in
219236 List. iter (fun rnsym ->
220237 let rnaddr = rnsym#getBaseName in
@@ -226,12 +243,12 @@ object (self)
226243 store#add_subtype_constraint rntypeterm lhstypeterm
227244 end ) rndefs);
228245
229- (match getopt_global_address (rn#to_expr floc) with
246+ (match getopt_global_address_r (rn#to_expr floc) with
230247 | Some gaddr ->
231248 if BCHConstantDefinitions. is_in_global_arrayvar gaddr then
232249 (match (BCHConstantDefinitions. get_arrayvar_base_offset gaddr) with
233250 | Some _ ->
234- let rmdefs = get_variable_rdefs (rm#to_variable floc) in
251+ let rmdefs = get_variable_rdefs_r (rm#to_variable floc) in
235252 let rmreg = rm#to_register in
236253 List. iter (fun rmsym ->
237254 let rmaddr = rmsym#getBaseName in
@@ -248,7 +265,7 @@ object (self)
248265 ()
249266 | _ -> () );
250267
251- (match getopt_initial_argument_value xrn with
268+ (match getopt_initial_argument_value_r xrn_r with
252269 | Some (reg , _ ) ->
253270 let ftvar = mk_function_typevar faddr in
254271 let ftvar = add_freg_param_capability reg ftvar in
@@ -267,7 +284,7 @@ object (self)
267284 let rdreg = rd#to_register in
268285 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
269286 let rnreg = rn#to_register in
270- let rndefs = get_variable_rdefs (rn#to_variable floc) in
287+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
271288 begin
272289
273290 (* ASR results in a signed integer *)
@@ -295,7 +312,7 @@ object (self)
295312 | BitwiseAnd (_ , _ , rd , rn , _ , _ ) ->
296313 let rdreg = rd#to_register in
297314 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
298- let rndefs = get_variable_rdefs (rn#to_variable floc) in
315+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
299316 let rnreg = rn#to_register in
300317 begin
301318
@@ -330,7 +347,7 @@ object (self)
330347 | BitwiseOr (_ , _ , rd , rn , _ , _ ) ->
331348 let rdreg = rd#to_register in
332349 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
333- let rndefs = get_variable_rdefs (rn#to_variable floc) in
350+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
334351 let rnreg = rn#to_register in
335352 begin
336353
@@ -345,7 +362,6 @@ object (self)
345362 end ) rndefs
346363 end
347364
348-
349365 | Branch _ ->
350366 (* no type information gained *)
351367 ()
@@ -466,7 +482,7 @@ object (self)
466482 end
467483
468484 | Compare (_ , rn , rm , _ ) when rm#is_immediate ->
469- let rndefs = get_variable_rdefs (rn#to_variable floc) in
485+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
470486 let rnreg = rn#to_register in
471487 let immval = rm#to_numerical#toInt in
472488 if immval = 0 then
@@ -484,8 +500,8 @@ object (self)
484500 end ) rndefs
485501
486502 | Compare (_ , rn , rm , _ ) when rm#is_register ->
487- let rndefs = get_variable_rdefs (rn#to_variable floc) in
488- let rmdefs = get_variable_rdefs (rm#to_variable floc) in
503+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
504+ let rmdefs = get_variable_rdefs_r (rm#to_variable floc) in
489505 let rnreg = rn#to_register in
490506 let rmreg = rm#to_register in
491507 let pairs = CHUtil. xproduct rndefs rmdefs in
@@ -506,8 +522,8 @@ object (self)
506522 store#add_subtype_constraint rntypeterm rmtypeterm
507523 end ) pairs);
508524
509- (let xrn = rn#to_expr floc in
510- match getopt_initial_argument_value xrn with
525+ (let xrn_r = rn#to_expr floc in
526+ match getopt_initial_argument_value_r xrn_r with
511527 | Some (reg , _ ) ->
512528 let ftvar = mk_function_typevar faddr in
513529 let ftvar = add_freg_param_capability reg ftvar in
@@ -522,8 +538,8 @@ object (self)
522538 end ) rmdefs
523539 | _ -> () );
524540
525- (let xrm = rm#to_expr floc in
526- match getopt_initial_argument_value xrm with
541+ (let xrm_r = rm#to_expr floc in
542+ match getopt_initial_argument_value_r xrm_r with
527543 | Some (reg , _ ) ->
528544 let ftvar = mk_function_typevar faddr in
529545 let ftvar = add_freg_param_capability reg ftvar in
@@ -545,7 +561,7 @@ object (self)
545561 begin
546562
547563 (* LDR rt, [rn, rm] : X_rndef.load <: X_rt *)
548- (let xrdef = get_variable_rdefs (rn#to_variable floc) in
564+ (let xrdef = get_variable_rdefs_r (rn#to_variable floc) in
549565 let rnreg = rn#to_register in
550566 let offset = rm#to_numerical#toInt in
551567 List. iter (fun rdsym ->
@@ -559,8 +575,9 @@ object (self)
559575 store#add_subtype_constraint rdtypeterm rttypeterm
560576 end ) xrdef);
561577
562- (match rewrite_expr (memop#to_expr floc) with
563- | XVar v ->
578+ (match TR. tmap rewrite_expr (memop#to_expr floc) with
579+ | Error _ -> ()
580+ | Ok (XVar v ) ->
564581 (match floc#f#env#get_variable_type v with
565582 | Some ty ->
566583 let opttc = mk_btype_constraint rttypevar ty in
@@ -576,7 +593,7 @@ object (self)
576593
577594 (* if the address to load from is the address of a global struct field,
578595 assign the type of that field to the destination register. *)
579- (match getopt_global_address (memop#to_address floc) with
596+ (match getopt_global_address_r (memop#to_address floc) with
580597 | Some gaddr ->
581598 if BCHConstantDefinitions. is_in_global_structvar gaddr then
582599 match (BCHConstantDefinitions. get_structvar_base_offset gaddr) with
@@ -630,7 +647,7 @@ object (self)
630647
631648 (* if the value loaded is the start address of a global array,
632649 assign that array type to the destination register. *)
633- (match getopt_global_address (memop#to_expr floc) with
650+ (match getopt_global_address_r (memop#to_expr floc) with
634651 | Some gaddr ->
635652 if BCHConstantDefinitions. is_in_global_arrayvar gaddr then
636653 (match (BCHConstantDefinitions. get_arrayvar_base_offset gaddr) with
@@ -662,7 +679,7 @@ object (self)
662679 | _ -> () )
663680 | _ -> () );
664681
665- (match getopt_stackaddress (memop#to_address floc) with
682+ (match getopt_stackaddress_r (memop#to_address floc) with
666683 | None -> ()
667684 | Some offset ->
668685 let rhstypevar = mk_localstack_lhs_typevar offset faddr iaddr in
@@ -680,7 +697,7 @@ object (self)
680697 begin
681698
682699 (* LDRB rt, [rn, rm] : X_rndef.load <: X_rt *)
683- (let xrdefs = get_variable_rdefs (rn#to_variable floc) in
700+ (let xrdefs = get_variable_rdefs_r (rn#to_variable floc) in
684701 let rnreg = rn#to_register in
685702 let offset = rm#to_numerical#toInt in
686703 List. iter (fun rdsym ->
@@ -727,7 +744,7 @@ object (self)
727744 begin
728745
729746 (* LDRH rt, [rn, rm] : X_rndef.load <: X_rt *)
730- (let xrdef = get_variable_rdefs (rn#to_variable floc) in
747+ (let xrdef = get_variable_rdefs_r (rn#to_variable floc) in
731748 let rnreg = rn#to_register in
732749 let offset = rm#to_numerical#toInt in
733750 List. iter (fun rdsym ->
@@ -762,7 +779,7 @@ object (self)
762779 let rdreg = rd#to_register in
763780 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
764781 let rnreg = rn#to_register in
765- let rndefs = get_variable_rdefs (rn#to_variable floc) in
782+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
766783
767784 (* LSL results in an unsigned integer *)
768785 (let tc = mk_int_type_constant Unsigned 32 in
@@ -789,7 +806,7 @@ object (self)
789806 let rdreg = rd#to_register in
790807 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
791808 let rnreg = rn#to_register in
792- let rndefs = get_variable_rdefs (rn#to_variable floc) in
809+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
793810
794811 (* LSR results in an unsigned integer *)
795812 (let tc = mk_int_type_constant Unsigned 32 in
@@ -834,11 +851,11 @@ object (self)
834851
835852 (* Move x, y --- x := y --- Y <: X *)
836853 | Move (_ , _ , rd , rm , _ , _ ) when rm#is_register ->
837- let xrm = rm#to_expr floc in
854+ let xrm_r = rm#to_expr floc in
838855 let rdreg = rd#to_register in
839856 begin
840857 (* propagate function argument type *)
841- (match getopt_initial_argument_value xrm with
858+ (match getopt_initial_argument_value_r xrm_r with
842859 | Some (rmreg , off ) when off = 0 ->
843860 let rhstypevar = mk_function_typevar faddr in
844861 let rhstypevar = add_freg_param_capability rmreg rhstypevar in
@@ -852,7 +869,7 @@ object (self)
852869 | _ -> () );
853870
854871 (* propagate function return type *)
855- (if rd#get_register = AR0 && (has_exit_use (rd#to_variable floc)) then
872+ (if rd#get_register = AR0 && (has_exit_use_r (rd#to_variable floc)) then
856873 let regvar = mk_reglhs_typevar rdreg faddr iaddr in
857874 let fvar = mk_function_typevar faddr in
858875 let fvar = add_return_capability fvar in
@@ -865,8 +882,8 @@ object (self)
865882
866883 (* use reaching defs *)
867884 (let rmreg = rm#to_register in
868- let rmvar = rm#to_variable floc in
869- let rmrdefs = get_variable_rdefs rmvar in
885+ let rmvar_r = rm#to_variable floc in
886+ let rmrdefs = get_variable_rdefs_r rmvar_r in
870887 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
871888 List. iter (fun rmrdef ->
872889 let rmaddr = rmrdef#getBaseName in
@@ -912,15 +929,15 @@ object (self)
912929
913930 (* Store x in y --- *y := x --- X <: Y.store *)
914931 | StoreRegister (_ , rt , _rn , rm , memvarop , _ ) when rm#is_immediate ->
915- let xaddr = memvarop#to_address floc in
916- let xrt = rt#to_expr floc in
917- (match getopt_stackaddress xaddr with
932+ let xaddr_r = memvarop#to_address floc in
933+ let xrt_r = rt#to_expr floc in
934+ (match getopt_stackaddress_r xaddr_r with
918935 | None -> ()
919936 | Some offset ->
920937 let lhstypevar = mk_localstack_lhs_typevar offset faddr iaddr in
921938 begin
922939 (* propagate function argument type *)
923- (match getopt_initial_argument_value xrt with
940+ (match getopt_initial_argument_value_r xrt_r with
924941 | Some (rtreg , off ) when off = 0 ->
925942 let rhstypevar = mk_function_typevar faddr in
926943 let rhstypevar = add_freg_param_capability rtreg rhstypevar in
@@ -934,8 +951,8 @@ object (self)
934951
935952 (* propagate src register type from rdefs *)
936953 (let rtreg = rt#to_register in
937- let rtvar = rt#to_variable floc in
938- let rtrdefs = get_variable_rdefs rtvar in
954+ let rtvar_r = rt#to_variable floc in
955+ let rtrdefs = get_variable_rdefs_r rtvar_r in
939956 List. iter (fun rtrdef ->
940957 let rtaddr = rtrdef#getBaseName in
941958 if rtaddr != " init" then
@@ -950,10 +967,10 @@ object (self)
950967 )
951968
952969 | StoreRegisterByte (_ , rt , rn , rm , _memvarop , _ ) when rm#is_immediate ->
953- let rnrdefs = get_variable_rdefs (rn#to_variable floc) in
970+ let rnrdefs = get_variable_rdefs_r (rn#to_variable floc) in
954971 let rnreg = rn#to_register in
955972 let offset = rm#to_numerical#toInt in
956- let rtrdefs = get_variable_rdefs (rt#to_variable floc) in
973+ let rtrdefs = get_variable_rdefs_r (rt#to_variable floc) in
957974 let rtreg = rt#to_register in
958975 begin
959976
@@ -1003,7 +1020,7 @@ object (self)
10031020 | Subtract (_ , _ , rd , rn , _ , _ , _ ) ->
10041021 let rdreg = rd#to_register in
10051022 let lhstypevar = mk_reglhs_typevar rdreg faddr iaddr in
1006- let rndefs = get_variable_rdefs (rn#to_variable floc) in
1023+ let rndefs = get_variable_rdefs_r (rn#to_variable floc) in
10071024 let rnreg = rn#to_register in
10081025 begin
10091026
0 commit comments