Skip to content

Commit 60ec1ff

Browse files
committed
CHB: convert numeric offsets to field offsets
1 parent 628ce33 commit 60ec1ff

File tree

6 files changed

+168
-25
lines changed

6 files changed

+168
-25
lines changed

CodeHawk/CHB/bchlib/bCHFloc.ml

Lines changed: 137 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ object (self)
676676
let memoff_r =
677677
TR.tbind
678678
(fun memvar ->
679-
let memtype = self#get_variable_type memvar in
679+
let memtype = self#env#get_variable_type memvar in
680680
let memtype =
681681
match memtype with
682682
| Some t -> t
@@ -703,7 +703,8 @@ object (self)
703703
match optbasetype with
704704
| Some t when is_pointer t -> ptr_deref t
705705
| _ -> t_unknown in
706-
address_memory_offset basetype (num_constant_expr memoffset))
706+
address_memory_offset basetype
707+
~tgtsize:(Some size) (num_constant_expr memoffset))
707708
(self#env#get_variable base#getSeqNumber) in
708709
mk_memvar memref_r memoff_r
709710

@@ -1319,23 +1320,139 @@ object (self)
13191320
method private get_variable_type (v: variable_t): btype_t option =
13201321
if self#f#env#is_initial_register_value v then
13211322
let reg_r = self#f#env#get_initial_register_value_register v in
1322-
let param_r =
1323-
TR.tbind
1324-
(fun reg ->
1325-
if self#f#get_summary#has_parameter_for_register reg then
1326-
Ok (self#f#get_summary#get_parameter_for_register reg)
1327-
else
1328-
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
1329-
^ (p2s v#toPretty)
1330-
^ " does not have an associated parameter"])
1331-
reg_r in
13321323
TR.tfold_default
1333-
(fun param -> Some param.apar_type)
1334-
(self#env#get_variable_type v)
1335-
param_r
1324+
(fun reg ->
1325+
if self#f#get_summary#has_parameter_for_register reg then
1326+
let param = self#f#get_summary#get_parameter_for_register reg in
1327+
Some param.apar_type
1328+
else
1329+
self#env#get_variable_type v)
1330+
None
1331+
reg_r
1332+
else if self#env#is_initial_memory_value v then
1333+
let memvar_r = self#env#get_init_value_variable v in
1334+
TR.tfold
1335+
~ok:self#get_variable_type
1336+
~error:(fun e ->
1337+
begin log_error_result __FILE__ __LINE__ e; None end)
1338+
memvar_r
13361339
else
13371340
self#env#get_variable_type v
13381341

1342+
method convert_variable_offsets
1343+
?(size=None) (v: variable_t): variable_t traceresult =
1344+
if self#env#is_basevar_memory_variable v then
1345+
let basevar_r = self#env#get_memvar_basevar v in
1346+
let offset_r = self#env#get_memvar_offset v in
1347+
let cbasevar_r = TR.tbind self#convert_value_offsets basevar_r in
1348+
let basetype_r = TR.tmap self#get_variable_type cbasevar_r in
1349+
let tgttype_r =
1350+
TR.tbind
1351+
(fun basetype ->
1352+
match basetype with
1353+
| Some (TPtr (t, _)) -> Ok t
1354+
| Some t ->
1355+
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
1356+
^ "Type " ^ (btype_to_string t)
1357+
^ " is not a pointer"]
1358+
| _ ->
1359+
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
1360+
^ "No type for variable "
1361+
^ (p2s v#toPretty)
1362+
^ "with basevar "
1363+
^ (p2s (TR.tget_ok cbasevar_r)#toPretty)]) basetype_r in
1364+
let coffset_r =
1365+
TR.tbind
1366+
(fun offset ->
1367+
match offset with
1368+
| ConstantOffset (n, NoOffset) ->
1369+
TR.tbind
1370+
(fun tgttype ->
1371+
address_memory_offset
1372+
~tgtsize:size tgttype (num_constant_expr n)) tgttype_r
1373+
| _ -> Ok offset) offset_r in
1374+
TR.tbind
1375+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": " ^ (p2s v#toPretty))
1376+
(fun cbasevar ->
1377+
TR.tbind
1378+
(fun coffset ->
1379+
self#env#mk_basevar_memory_variable cbasevar coffset
1380+
) coffset_r)
1381+
cbasevar_r
1382+
else
1383+
Ok v
1384+
1385+
method convert_value_offsets
1386+
?(size=None) (v: variable_t): variable_t traceresult =
1387+
if self#env#is_basevar_memory_value v then
1388+
let basevar_r = self#env#get_memval_basevar v in
1389+
let offset_r = self#env#get_memval_offset v in
1390+
let cbasevar_r = TR.tbind self#convert_value_offsets basevar_r in
1391+
let basetype_r = TR.tmap self#get_variable_type cbasevar_r in
1392+
let tgttype_r =
1393+
TR.tbind
1394+
(fun basetype ->
1395+
match basetype with
1396+
| Some (TPtr (t, _)) -> Ok t
1397+
| Some t ->
1398+
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
1399+
^ "Type " ^ (btype_to_string t)
1400+
^ " is not a pointer"]
1401+
| _ ->
1402+
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
1403+
^ "No type for variable "
1404+
^ (p2s v#toPretty)
1405+
^ "with basevar "
1406+
^ (p2s (TR.tget_ok cbasevar_r)#toPretty)]) basetype_r in
1407+
let coffset_r =
1408+
TR.tbind
1409+
(fun offset ->
1410+
match offset with
1411+
| NoOffset ->
1412+
TR.tbind
1413+
(fun tgttype ->
1414+
address_memory_offset
1415+
~tgtsize:size tgttype (int_constant_expr 0)) tgttype_r
1416+
| ConstantOffset (n, NoOffset) ->
1417+
TR.tbind
1418+
(fun tgttype ->
1419+
address_memory_offset
1420+
~tgtsize:size tgttype (num_constant_expr n)) tgttype_r
1421+
| _ -> Ok offset) offset_r in
1422+
TR.tbind
1423+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": " ^ (p2s v#toPretty))
1424+
(fun cbasevar ->
1425+
TR.tbind
1426+
(fun coffset ->
1427+
let memvar_r =
1428+
self#env#mk_basevar_memory_variable cbasevar coffset in
1429+
TR.tbind self#env#mk_initial_memory_value memvar_r
1430+
) coffset_r)
1431+
cbasevar_r
1432+
else
1433+
Ok v
1434+
1435+
method convert_xpr_offsets ?(size=None) (x: xpr_t): xpr_t traceresult =
1436+
let rec aux exp =
1437+
match exp with
1438+
| XVar v when self#env#is_basevar_memory_value v ->
1439+
TR.tmap
1440+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
1441+
(fun v -> XVar v) (self#convert_value_offsets ~size v)
1442+
| XVar v when self#env#is_basevar_memory_variable v ->
1443+
TR.tmap
1444+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
1445+
(fun v -> XVar v) (self#convert_variable_offsets ~size v)
1446+
| XOp ((Xf "addressofvar"), [XVar v]) ->
1447+
TR.tmap
1448+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
1449+
(fun v -> XVar v) (self#convert_variable_offsets ~size v)
1450+
| XOp (op, [xx]) -> TR.tmap (fun x -> XOp (op, [x])) (aux xx)
1451+
| XOp (op, [x1; x2]) ->
1452+
TR.tmap2 (fun x1 x2 -> XOp (op, [x1; x2])) (aux x1) (aux x2)
1453+
| _ -> Ok exp in
1454+
aux x
1455+
13391456
method get_xpr_type (x: xpr_t): btype_t option =
13401457
match x with
13411458
| XVar v -> self#get_variable_type v
@@ -1351,9 +1468,12 @@ object (self)
13511468
| [base] ->
13521469
let offset = simplify_xpr (XOp (XMinus, [x; XVar base])) in
13531470
let memref_r = self#env#mk_base_variable_reference base in
1354-
let vartype = self#get_variable_type base in
1471+
let vartype = self#env#get_variable_type base in
13551472
let vartype = match vartype with None -> t_unknown | Some t -> t in
1356-
let memoff_r = address_memory_offset vartype offset in
1473+
let rvartype = TR.tvalue (resolve_type vartype) ~default:t_unknown in
1474+
let basetype =
1475+
if is_pointer rvartype then ptr_deref rvartype else t_unknown in
1476+
let memoff_r = address_memory_offset basetype offset in
13571477
(*
13581478
(match offset with
13591479
| XConst (IntConst n) -> Ok (ConstantOffset (n, NoOffset))

CodeHawk/CHB/bchlib/bCHFunctionInfo.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,14 @@ object (self)
800800
let avar = varmgr#make_memory_variable memref ~size offset in
801801
self#mk_variable avar
802802

803+
method mk_basevar_memory_variable
804+
?(size=4)
805+
(basevar: variable_t)
806+
(offset: memory_offset_t): variable_t traceresult =
807+
let memref_r = self#mk_base_variable_reference basevar in
808+
TR.tmap
809+
(fun memref -> self#mk_offset_memory_variable ~size memref offset)
810+
memref_r
803811

804812
(*
805813
method mk_index_offset_global_memory_variable

CodeHawk/CHB/bchlib/bCHMemoryReference.ml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ let rec address_memory_offset
186186
Ok NoOffset
187187
| XConst (IntConst n) when is_unknown_type rbasetype ->
188188
Ok (ConstantOffset (n, NoOffset))
189+
| XConst (IntConst n) ->
190+
let tgtbtype =
191+
if is_unknown_type tgtbtype then None else Some tgtbtype in
192+
if is_struct_type rbasetype then
193+
structvar_memory_offset ~tgtsize ~tgtbtype rbasetype xoffset
194+
else if is_array_type rbasetype then
195+
arrayvar_memory_offset ~tgtsize ~tgtbtype rbasetype xoffset
196+
else
197+
Ok (ConstantOffset (n, NoOffset))
189198
| _ ->
190199
let tgtbtype =
191200
if is_unknown_type tgtbtype then None else Some tgtbtype in
@@ -195,9 +204,7 @@ let rec address_memory_offset
195204
arrayvar_memory_offset ~tgtsize ~tgtbtype rbasetype xoffset
196205
else
197206
Error [__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": "
198-
^ (btype_to_string basetype)
199-
^ " (" ^ (btype_to_string rbasetype) ^ ")"
200-
^ " is not known to be a struct or array"]
207+
^ "Offset " ^ (x2s xoffset) ^ " not yet supported"]
201208

202209
and structvar_memory_offset
203210
~(tgtsize: int option)

CodeHawk/CHB/bchlib/bCHTypeConstraintUtil.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,10 @@ let rec mk_btype_constraint (tv: type_variable_t) (ty: btype_t)
437437
| TPtr (pty, _) ->
438438
let ptv = add_deref_capability tv in
439439
mk_btype_constraint ptv pty
440+
| TArray (elty, Some (Const (CInt (i64, _, _))), _) ->
441+
let size = Int64.to_int i64 in
442+
let atv = add_array_access_capability size tv in
443+
mk_btype_constraint atv elty
440444
| TArray (elty, _, _) ->
441445
let size_r = size_of_btype elty in
442446
(match size_r with

CodeHawk/CHB/bchlib/bCHVariable.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ object (self:'a)
9797
| _ ->
9898
(match offset with
9999
| NoOffset -> "__pderef_" ^ basename ^ "_"
100-
| _ -> basename ^ (memory_offset_to_string offset)))
100+
| ConstantOffset _ -> basename ^ (memory_offset_to_string offset)
101+
| _ -> "__pderef_" ^ basename ^ (memory_offset_to_string offset)))
101102
| RegisterVariable reg -> register_to_string reg
102103
| CPUFlagVariable flag -> flag_to_string flag
103104
| AuxiliaryVariable a ->
@@ -1004,7 +1005,10 @@ object (self)
10041005

10051006
method has_constant_offset (v: variable_t) =
10061007
(self#is_memory_variable v)
1007-
&& (tfold_default is_constant_offset false (self#get_memvar_offset v))
1008+
&& (tfold_default
1009+
(fun off -> is_constant_offset off || is_field_offset off)
1010+
false
1011+
(self#get_memvar_offset v))
10081012

10091013
method is_unknown_base_memory_variable (v: variable_t) =
10101014
(self#is_memory_variable v)

CodeHawk/CHB/bchlib/bCHVersion.ml

Lines changed: 3 additions & 3 deletions
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
@@ -95,8 +95,8 @@ end
9595

9696

9797
let version = new version_info_t
98-
~version:"0.6.0_20250210"
99-
~date:"2025-02-10"
98+
~version:"0.6.0_20250222"
99+
~date:"2025-02-22"
100100
~licensee: None
101101
~maxfilesize: None
102102
()

0 commit comments

Comments
 (0)