44 ------------------------------------------------------------------------------
55 The MIT License (MIT)
66
7- Copyright (c) 2023 Aarno Labs LLC
7+ Copyright (c) 2023-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
@@ -33,19 +33,22 @@ open CHUtils
3333
3434(* chutil *)
3535open CHLogger
36+ open CHTraceResult
3637open CHXmlDocument
3738
3839(* xprlib *)
3940open XprTypes
4041
4142(* bchlib *)
4243open BCHBasicTypes
44+ open BCHBCTypePretty
4345open BCHBCTypes
4446open BCHBCTypeUtil
4547open BCHCPURegisters
4648open BCHLibTypes
4749
4850module H = Hashtbl
51+ module TR = CHTraceResult
4952
5053
5154let bd = BCHDictionary. bdictionary
@@ -117,11 +120,98 @@ object (_self:'a)
117120end
118121
119122
120- class stackframe_t (varmgr : variable_manager_int ):stackframe_int =
123+ let stackslot_rec_to_pretty (sslot : stackslot_rec_t ): pretty_t =
124+ LBLOCK [
125+ STR " offset: " ; INT sslot.sslot_offset; NL ;
126+ STR " name : " ; STR sslot.sslot_name; NL ;
127+ STR " type : " ; STR (btype_to_string sslot.sslot_btype); NL ;
128+ (match sslot.sslot_size with
129+ | Some s -> LBLOCK [STR " size : " ; INT s; NL ]
130+ | _ -> STR " " );
131+ (match sslot.sslot_desc with
132+ | Some desc -> LBLOCK [STR " desc : " ; STR desc; NL ]
133+ | _ -> STR " " )
134+ ]
135+
136+
137+ let opt_size_to_string (optsize : int option ): string =
138+ match optsize with
139+ | Some s -> (string_of_int s)
140+ | _ -> " ?"
141+
142+
143+ class stackslot_t (sslot : stackslot_rec_t ): stackslot_int =
144+ object
145+
146+ method sslot_rec = sslot
147+
148+ method name = sslot.sslot_name
149+
150+ method offset = sslot.sslot_offset
151+
152+ method btype = sslot.sslot_btype
153+
154+ method size = sslot.sslot_size
155+
156+ method desc = sslot.sslot_desc
157+
158+ method contains_offset (_offset : int ) = false
159+
160+ method frame2object_offset_value (_xpr : xpr_t ) = Error [" Not yet implemenented" ]
161+
162+ method frame_offset_memory_offset
163+ ?(tgtsize =None )
164+ ?(tgtbtype =t_unknown)
165+ (_xpr : xpr_t ): memory_offset_t traceresult =
166+ Error [" Not yet implemented for btype: "
167+ ^ (btype_to_string tgtbtype)
168+ ^ " and size "
169+ ^ (opt_size_to_string tgtsize)]
170+
171+ method object_offset_memory_offset
172+ ?(tgtsize =None )
173+ ?(tgtbtype =t_unknown)
174+ (_xpr : xpr_t ): memory_offset_t traceresult =
175+ Error [" Not yet implemented: "
176+ ^ (btype_to_string tgtbtype)
177+ ^ " and size "
178+ ^ (opt_size_to_string tgtsize)]
179+
180+ method write_xml (_node : xml_element_int ) = ()
181+
182+ end
183+
184+
185+ class stackframe_t
186+ (fndata : function_data_int )
187+ (varmgr : variable_manager_int ):stackframe_int =
121188object (self )
122189
123190 val saved_registers = H. create 3 (* reg -> saved_register_t *)
124191 val accesses = H. create 3 (* offset -> (iaddr, stack_access_t) list *)
192+ val stackslots =
193+ let slots = H. create 3 in (* offset -> stackslot *)
194+ begin
195+ (match fndata#get_function_annotation with
196+ | Some fnannot ->
197+ List. iter (fun svintro ->
198+ let ty = match svintro.svi_vartype with
199+ | Some ty -> ty
200+ | _ -> t_unknown in
201+ let size = TR. to_option (size_of_btype ty) in
202+ let sslot = {
203+ sslot_offset = svintro.svi_offset;
204+ sslot_name = svintro.svi_name;
205+ sslot_btype = ty;
206+ sslot_desc = Some (" svintro" );
207+ sslot_size = size} in
208+ let stackslot = new stackslot_t sslot in
209+ let _ =
210+ chlog#add " stack slot added" (stackslot_rec_to_pretty sslot) in
211+ H. add slots svintro.svi_offset stackslot) fnannot.stackvarintros
212+ | _ -> () );
213+ slots
214+ end
125215
126216 method private vard = varmgr#vard
127217
@@ -136,6 +226,79 @@ object (self)
136226 [] in
137227 H. replace accesses offset ((iaddr, acc) :: entry)
138228
229+ method containing_stackslot (offset : int ): stackslot_int option =
230+ H. fold (fun _ sslot acc ->
231+ match acc with
232+ | Some _ -> acc
233+ | _ -> if sslot#contains_offset offset then Some sslot else None )
234+ stackslots None
235+
236+ method add_stackslot
237+ ?(name = None )
238+ ?(btype = t_unknown)
239+ ?(size = None )
240+ ?(desc = None )
241+ (offset : int ): stackslot_int traceresult =
242+ if offset < = 0 then
243+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
244+ ^ " Illegal offset for stack slot: "
245+ ^ (string_of_int offset)
246+ ^ " . Offset should be greater than zero." ]
247+ else if H. mem stackslots offset then
248+ begin
249+ log_error_result
250+ ~tag: " duplicate stack slot"
251+ ~msg: (" Stack slot at offset "
252+ ^ (string_of_int offset)
253+ ^ " already exists" )
254+ __FILE__ __LINE__ [] ;
255+ Ok (H. find stackslots offset)
256+ end
257+ else
258+ match self#containing_stackslot offset with
259+ | Some sslot ->
260+ let msg =
261+ " Stackslot at offset "
262+ ^ (string_of_int offset)
263+ ^ " overlaps with "
264+ ^ sslot#name
265+ ^ " ("
266+ ^ (string_of_int sslot#offset)
267+ ^ (match sslot#size with
268+ | Some s -> " , size: " ^ (string_of_int s)
269+ | _ -> " " )
270+ ^ " )" in
271+ begin
272+ log_error_result
273+ ~tag: " overlapping stackslot"
274+ ~msg
275+ __FILE__ __LINE__ [] ;
276+ Error [msg]
277+ end
278+ | _ ->
279+ let sname =
280+ match name with
281+ | Some name -> name
282+ | _ -> " var_" ^ (string_of_int offset) in
283+ let ssrec = {
284+ sslot_name = sname;
285+ sslot_offset = offset;
286+ sslot_btype = btype;
287+ sslot_size = size;
288+ sslot_desc = desc
289+ } in
290+ let sslot = new stackslot_t ssrec in
291+ begin
292+ H. add stackslots offset sslot;
293+ chlog#add
294+ " stackframe:add stackslot"
295+ (LBLOCK [
296+ INT offset;
297+ STR " : " ;
298+ STR sslot#name]);
299+ Ok sslot
300+ end
301+
139302 method add_register_spill
140303 ~(offset : int ) (reg : register_t ) (iaddr :ctxt_iaddress_t ) =
141304 let spill = RegisterSpill (offset, reg) in
0 commit comments