Skip to content

Commit a918c00

Browse files
committed
CHB: add more functionality for handling stack variables
1 parent 0bb0342 commit a918c00

File tree

11 files changed

+169
-79
lines changed

11 files changed

+169
-79
lines changed

CodeHawk/CHB/bchlib/bCHCPURegisters.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
Copyright (c) 2005-2020 Kestrel Technology LLC
88
Copyright (c) 2020 Henny Sipma
9-
Copyright (c) 2021-2024 Aarno Labs LLC
9+
Copyright (c) 2021-2025 Aarno Labs LLC
1010
1111
Permission is hereby granted, free of charge, to any person obtaining a copy
1212
of this software and associated documentation files (the "Software"), to deal
@@ -864,3 +864,10 @@ let index_to_byte_register (index:int) =
864864
| 6 -> Dh
865865
| 7 -> Bh
866866
| _ -> raise (Invalid_argument ("index_to_byte_register with " ^ (string_of_int index)))
867+
868+
869+
let is_temporary_register (reg: register_t): bool =
870+
match reg with
871+
| ARMRegister r -> List.mem r arm_temporaries
872+
| MIPSRegister r -> List.mem r mips_temporaries
873+
| _ -> false

CodeHawk/CHB/bchlib/bCHCPURegisters.mli

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
Copyright (c) 2005-2019 Kestrel Technology LLC
88
Copyright (c) 2020 Henny Sipma
9-
Copyright (c) 2021-2024 Aarno Labs LLC
9+
Copyright (c) 2021-2025 Aarno Labs LLC
1010
1111
Permission is hereby granted, free of charge, to any person obtaining a copy
1212
of this software and associated documentation files (the "Software"), to deal
@@ -156,6 +156,9 @@ val is_stackpointer_register: register_t -> bool
156156

157157
val is_register: string -> bool
158158

159+
val is_temporary_register: register_t -> bool
160+
161+
159162
(** {2 x86}*)
160163

161164
val byte_reg_of_reg : cpureg_t -> cpureg_t (* raises Invalid_argument *)

CodeHawk/CHB/bchlib/bCHFunctionInfo.ml

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ object (self)
878878
Ok (self#mk_variable (self#varmgr#make_global_variable dw#to_numerical))
879879

880880
method mk_stack_variable
881+
?(size=4)
881882
(stackframe: stackframe_int)
882883
(offset: numerical_t): variable_t traceresult =
883884
match stackframe#containing_stackslot offset#toInt with
@@ -894,7 +895,8 @@ object (self)
894895
self#set_variable_name svar name;
895896
svar
896897
end)
897-
(stackslot#frame_offset_memory_offset (num_constant_expr offset))
898+
(stackslot#frame_offset_memory_offset
899+
~tgtsize:(Some size) (num_constant_expr offset))
898900
| _ ->
899901
Error [
900902
__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
@@ -1803,34 +1805,37 @@ object (self)
18031805
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
18041806

18051807
method save_register
1806-
(vmem: variable_t) (iaddr:ctxt_iaddress_t) (reg:register_t) =
1807-
if self#env#is_stack_variable vmem then
1808-
TR.tfold
1809-
~ok:(fun offset ->
1810-
match offset with
1811-
| ConstantOffset (n, NoOffset) ->
1812-
self#stackframe#add_register_spill ~offset:n#toInt reg iaddr
1813-
| _ ->
1814-
log_error_result
1815-
~msg:"save_register:not a constant offset"
1816-
__FILE__ __LINE__
1817-
["(" ^ (p2s self#get_address#toPretty) ^ "," ^ iaddr ^ "): ";
1818-
(p2s vmem#toPretty) ^ " with " ^ (register_to_string reg)
1819-
^ " and offset " ^ (memory_offset_to_string offset)])
1820-
~error:(fun e ->
1821-
log_error_result
1822-
~msg:"save_register"
1823-
__FILE__ __LINE__
1824-
(["(" ^ (p2s self#get_address#toPretty) ^ "," ^ iaddr ^ "): ";
1825-
(p2s vmem#toPretty) ^ " with " ^ (register_to_string reg)] @ e))
1826-
(self#env#get_memvar_offset vmem)
1808+
(vmem: variable_t) (iaddr: ctxt_iaddress_t) (reg: register_t) =
1809+
if BCHCPURegisters.is_temporary_register reg then
1810+
()
18271811
else
1828-
log_error_result
1829-
~msg:"save register:not a stack variable"
1830-
__FILE__ __LINE__
1831-
["(" ^ (p2s self#get_address#toPretty) ^ "," ^ iaddr ^ "): ";
1832-
"not a stack variable: "
1833-
^ (p2s vmem#toPretty) ^ " with " ^ (register_to_string reg)]
1812+
if self#env#is_stack_variable vmem then
1813+
TR.tfold
1814+
~ok:(fun offset ->
1815+
match offset with
1816+
| ConstantOffset (n, NoOffset) ->
1817+
self#stackframe#add_register_spill ~offset:n#toInt reg iaddr
1818+
| _ ->
1819+
log_error_result
1820+
~msg:"save_register:not a constant offset"
1821+
__FILE__ __LINE__
1822+
["(" ^ (p2s self#get_address#toPretty) ^ "," ^ iaddr ^ "): ";
1823+
(p2s vmem#toPretty) ^ " with " ^ (register_to_string reg)
1824+
^ " and offset " ^ (memory_offset_to_string offset)])
1825+
~error:(fun e ->
1826+
log_error_result
1827+
~msg:"save_register"
1828+
__FILE__ __LINE__
1829+
(["(" ^ (p2s self#get_address#toPretty) ^ "," ^ iaddr ^ "): ";
1830+
(p2s vmem#toPretty) ^ " with " ^ (register_to_string reg)] @ e))
1831+
(self#env#get_memvar_offset vmem)
1832+
else
1833+
log_error_result
1834+
~msg:"save register:not a stack variable"
1835+
__FILE__ __LINE__
1836+
["(" ^ (p2s self#get_address#toPretty) ^ "," ^ iaddr ^ "): ";
1837+
"not a stack variable: "
1838+
^ (p2s vmem#toPretty) ^ " with " ^ (register_to_string reg)]
18341839

18351840
method restore_register
18361841
(memaddr: xpr_t) (iaddr:ctxt_iaddress_t) (reg:register_t) =

CodeHawk/CHB/bchlib/bCHFunctionStackframe.ml

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ object (self)
102102
| Ok (TArray _) -> true
103103
| _ -> false
104104

105-
method size = sslot.sslot_size
105+
method is_scalar: bool =
106+
match resolve_type self#btype with
107+
| Ok t -> is_scalar t
108+
| _ -> false
109+
110+
method size: int option = sslot.sslot_size
106111

107112
method desc = sslot.sslot_desc
108113

@@ -137,7 +142,9 @@ object (self)
137142
?(tgtbtype=t_unknown)
138143
(xoffset: xpr_t): memory_offset_t traceresult =
139144
match xoffset with
140-
| XConst (IntConst n) when n#equal CHNumerical.numerical_zero ->
145+
| XConst (IntConst n)
146+
when n#equal CHNumerical.numerical_zero
147+
&& (not self#is_typed || self#is_scalar) ->
141148
Ok NoOffset
142149
| XConst (IntConst n) when not self#is_typed ->
143150
Ok (ConstantOffset (n, NoOffset))
@@ -234,6 +241,31 @@ object (self)
234241
match tgtsize with
235242
| Some s -> string_of_int s
236243
| _ -> "?" in
244+
let check_tgttype_compliance (t: btype_t) (s: int) =
245+
match tgtsize, tgtbtype with
246+
| None, None -> true
247+
| Some size, None -> size = s
248+
| Some size, Some (TVoid _) -> size = s
249+
| None, Some (TVoid _) -> true
250+
| None, Some ty -> btype_equal ty t
251+
| Some size, Some ty -> size = s && btype_equal ty t in
252+
let compliance_failure (t: btype_t) (s: int) =
253+
let size_discrepancy size s =
254+
"size discrepancy between tgtsize: "
255+
^ (string_of_int size)
256+
^ " and field size: "
257+
^ (string_of_int s) in
258+
let type_discrepancy ty t =
259+
"type discrepancy between tgttype: "
260+
^ (btype_to_string ty)
261+
^ " and field type: "
262+
^ (btype_to_string t) in
263+
match tgtsize, tgtbtype with
264+
| Some size, Some ty when (size != s) && (not (btype_equal ty t)) ->
265+
(size_discrepancy size s) ^ " and " ^ (type_discrepancy ty t)
266+
| Some size, _ when size != s -> size_discrepancy size s
267+
| _, Some ty when not (btype_equal ty t) -> type_discrepancy ty t
268+
| _ -> "" in
237269
match xoffset with
238270
| XConst (IntConst n) ->
239271
let offset = n#toInt in
@@ -266,9 +298,14 @@ object (self)
266298
Ok (Some (FieldOffset
267299
((finfo.bfname, finfo.bfckey), NoOffset)))
268300
else if offset = 0
269-
&& (is_scalar fldtype) then
301+
&& (is_scalar fldtype)
302+
&& (check_tgttype_compliance fldtype sz) then
270303
Ok (Some (FieldOffset
271304
((finfo.bfname, finfo.bfckey), NoOffset)))
305+
else if offset = 0 && is_scalar fldtype then
306+
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
307+
^ "Scalar type or size is not consistent: "
308+
^ (compliance_failure fldtype sz)]
272309
else
273310
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
274311
^ "Field offset "
@@ -473,25 +510,27 @@ object (self)
473510
end
474511

475512
method add_load
476-
~(offset:int)
513+
~(baseoffset:int)
514+
~(offset:memory_offset_t)
477515
~(size:int option)
478516
~(typ:btype_t option)
479517
(var: variable_t)
480518
(iaddr:ctxt_iaddress_t) =
481519
let ty = match typ with Some t -> t | _ -> t_unknown in
482520
let load = StackLoad (var, offset, size, ty) in
483-
self#add_access offset iaddr load
521+
self#add_access baseoffset iaddr load
484522

485523
method add_store
486-
~(offset:int)
524+
~(baseoffset:int)
525+
~(offset:memory_offset_t)
487526
~(size:int option)
488527
~(typ:btype_t option)
489528
~(xpr:xpr_t option)
490529
(var: variable_t)
491530
(iaddr:ctxt_iaddress_t) =
492531
let ty = match typ with Some t -> t | _ -> t_unknown in
493532
let store = StackStore (var, offset, size, ty, xpr) in
494-
self#add_access offset iaddr store
533+
self#add_access baseoffset iaddr store
495534

496535
method add_block_read
497536
~(offset:int)
@@ -513,15 +552,13 @@ object (self)
513552
self#add_access offset iaddr store
514553

515554
method private write_xml_stack_slots (node: xml_element_int) =
516-
let slotsnode = xmlElement "stack-slots" in
517555
begin
518556
H.iter (fun _ slot ->
519557
let slotnode = xmlElement "slot" in
520558
begin
521559
slot#write_xml slotnode;
522-
slotsnode#appendChildren [slotnode]
560+
node#appendChildren [slotnode]
523561
end) stackslots;
524-
node#appendChildren [slotsnode]
525562
end
526563

527564
method private write_xml_stack_accesses (node: xml_element_int) =

CodeHawk/CHB/bchlib/bCHLibTypes.mli

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,9 +3736,10 @@ type stack_access_t =
37363736
(** stack offset *)
37373737
| RegisterRestore of int * register_t
37383738
(** stack offset *)
3739-
| StackLoad of variable_t * int * int option * btype_t
3739+
| StackLoad of variable_t * memory_offset_t * int option * btype_t
37403740
(** variable, offset, size *)
3741-
| StackStore of variable_t * int * int option * btype_t * xpr_t option
3741+
| StackStore of
3742+
variable_t * memory_offset_t * int option * btype_t * xpr_t option
37423743
(** variable, offset, size, value *)
37433744
| StackBlockRead of int * int option * btype_t
37443745
(** offset, size *)
@@ -4560,6 +4561,7 @@ class type stackslot_int =
45604561
-> memory_offset_t traceresult
45614562

45624563
method is_typed: bool
4564+
method is_scalar: bool
45634565
method is_struct: bool
45644566
method is_array: bool
45654567
method is_spill: bool
@@ -4588,15 +4590,17 @@ class type stackframe_int =
45884590
method containing_stackslot: int -> stackslot_int option
45894591

45904592
method add_load:
4591-
offset:int
4593+
baseoffset:int
4594+
-> offset: memory_offset_t
45924595
-> size:int option
45934596
-> typ:btype_t option
45944597
-> variable_t
45954598
-> ctxt_iaddress_t
45964599
-> unit
45974600

45984601
method add_store:
4599-
offset:int
4602+
baseoffset:int
4603+
-> offset: memory_offset_t
46004604
-> size:int option
46014605
-> typ:btype_t option
46024606
-> xpr:xpr_t option
@@ -4764,7 +4768,8 @@ class type function_environment_int =
47644768
method mk_gloc_variable:
47654769
global_location_int -> memory_offset_t -> variable_t
47664770

4767-
method mk_stack_variable: stackframe_int -> numerical_t -> variable_t traceresult
4771+
method mk_stack_variable:
4772+
?size: int -> stackframe_int -> numerical_t -> variable_t traceresult
47684773

47694774
(** [mk_initial_memory_value var] returns an auxiliary variable that
47704775
represents the initial value of [var] at function entry.

0 commit comments

Comments
 (0)