Skip to content

Commit c2782f7

Browse files
committed
CHB: support for conversion to c expr of pointer arithmetic
1 parent 34b7bc9 commit c2782f7

File tree

3 files changed

+112
-14
lines changed

3 files changed

+112
-14
lines changed

CodeHawk/CHB/bchlib/bCHFloc.ml

Lines changed: 106 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ module POAnchorCollections = CHCollections.Make
8989
let x2p = xpr_formatter#pr_expr
9090
let p2s = pretty_to_string
9191
let x2s x = p2s (x2p x)
92+
let i2s i = string_of_int i
9293

9394
let opti2s (i: int option) =
9495
if Option.is_some i then string_of_int (Option.get i) else "?"
9596

96-
let _ty2s (ty: btype_t) =
97+
let ty2s (ty: btype_t) =
9798
if is_unknown_type ty then "?" else btype_to_string ty
9899
let optty2s (ty: btype_t option) =
99100
if Option.is_some ty then btype_to_string (Option.get ty) else "?"
@@ -1379,8 +1380,31 @@ object (self)
13791380
(default ())
13801381
(numerical_to_doubleword n)
13811382
| _ ->
1382-
default ()
1383-
1383+
default ()
1384+
1385+
(* Handles the following cases:
1386+
- initial_register_value:
1387+
if the register is a function parameter: get parameter type
1388+
otherwise: Error
1389+
1390+
- initial_memory_value:
1391+
get type of corresponding memory variable
1392+
1393+
- memory_variable:
1394+
separate base from offset
1395+
* global: retrieve type from global-memory-map if addresses match
1396+
otherwise: Error
1397+
Note: this may lead to confusion between type of first field and
1398+
type of struct
1399+
1400+
* basevar:
1401+
if no-offset: type-of *basevar
1402+
otherwise: type dependent on offset
1403+
1404+
- return_value:
1405+
if callsite has a typed var-intro: retrieve type of var-intro
1406+
otherwise: Error (not yet handled)
1407+
*)
13841408
method get_variable_type (v: variable_t): btype_t traceresult =
13851409
let is_zero (x: xpr_t) =
13861410
match x with
@@ -1527,14 +1551,52 @@ object (self)
15271551
^ " at address " ^ loc#i#to_hex_string
15281552
^ " not yet handled"])
15291553
(self#f#env#get_call_site v)
1554+
else if self#f#env#is_register_variable v then
1555+
let vrdefs = self#get_variable_rdefs v in
1556+
let fndata = self#f#get_function_data in
1557+
match vrdefs with
1558+
| h :: _ ->
1559+
let optty_r =
1560+
TR.tmap
1561+
(fun r -> fndata#get_reglhs_type r h#getBaseName)
1562+
(self#f#env#get_register v) in
1563+
TR.tfold
1564+
~ok:(fun optty ->
1565+
match optty with
1566+
| Some ty -> Ok ty
1567+
| _ ->
1568+
Error [
1569+
(elocm __LINE__)
1570+
^ "No reglhs type assignment found for variable "
1571+
^ (p2s v#toPretty)
1572+
^ " at location "
1573+
^ h#getBaseName])
1574+
~error:(fun e -> Error ((elocm __LINE__) :: e))
1575+
optty_r
1576+
| _ ->
1577+
Error [
1578+
(elocm __LINE__)
1579+
^ "Unable to find reachingdefs for variable "
1580+
^ (p2s v#toPretty)]
15301581
else
15311582
let ty = self#env#get_variable_type v in
15321583
match ty with
15331584
| None -> Error [(elocm __LINE__) ^ "variable: " ^ (x2s (XVar v))]
15341585
| Some t -> Ok t
15351586

1587+
method private get_variable_rdefs (v: variable_t): symbol_t list =
1588+
let symvar = self#f#env#mk_symbolic_variable v in
1589+
let varinvs = self#varinv#get_var_reaching_defs symvar in
1590+
(match varinvs with
1591+
| [vinv] -> vinv#get_reaching_defs
1592+
| _ ->
1593+
List.concat (List.map (fun vinv -> vinv#get_reaching_defs) varinvs))
1594+
15361595
method xpr_to_cxpr
1537-
?(size=None) ?(xtype=None) (x: xpr_t): xpr_t traceresult =
1596+
?(arithm=false)
1597+
?(size=None)
1598+
?(xtype=None)
1599+
(x: xpr_t): xpr_t traceresult =
15381600
let _ =
15391601
log_diagnostics_result
15401602
~msg:(p2s self#l#toPretty)
@@ -1543,14 +1605,45 @@ object (self)
15431605
["size: " ^ (opti2s size);
15441606
"xtype: " ^ (optty2s xtype);
15451607
"x: " ^ (x2s x)] in
1546-
match xtype with
1547-
| None -> self#convert_xpr_offsets ~size x
1548-
| Some t ->
1549-
match x with
1550-
| XConst (IntConst n)
1551-
when n#equal (mkNumerical 0xffffffff) && is_int t ->
1552-
Ok (int_constant_expr (-1))
1553-
| _ -> self#convert_xpr_offsets ~xtype ~size x
1608+
let is_pointer (y: xpr_t) =
1609+
TR.tfold_default BCHBCTypeUtil.is_pointer false (self#get_xpr_type y) in
1610+
let default () = self#convert_xpr_offsets ~xtype ~size x in
1611+
match x with
1612+
| XOp (XPlus, [y; XConst (IntConst n)]) when is_pointer y && arithm ->
1613+
let derefty = BCHBCTypeUtil.ptr_deref (TR.tget_ok (self#get_xpr_type y)) in
1614+
let _ =
1615+
log_diagnostics_result
1616+
~msg:(p2s self#l#toPretty)
1617+
~tag:"xpr_to_cxpr:pointer expression"
1618+
__FILE__ __LINE__
1619+
["x: " ^ (x2s x); "*ty: " ^ (ty2s derefty)] in
1620+
TR.tmap2
1621+
~msg1:(eloc __LINE__)
1622+
~msg2:(eloc __LINE__)
1623+
(fun cy size ->
1624+
let scaledincr = XConst (IntConst (n#div (mkNumerical size))) in
1625+
let result = XOp (XPlus, [cy; scaledincr]) in
1626+
let _ =
1627+
log_diagnostics_result
1628+
~msg:(p2s self#l#toPretty)
1629+
~tag:"xpr_to_cxpr:pointer expression"
1630+
__FILE__ __LINE__
1631+
["x: " ^ (x2s x);
1632+
"cy: " ^ (x2s cy);
1633+
"size: " ^ (i2s size);
1634+
"result: " ^ (x2s result)] in
1635+
result)
1636+
(self#xpr_to_cxpr y)
1637+
(BCHBCTypeUtil.size_of_btype derefty)
1638+
| _ ->
1639+
match xtype with
1640+
| None -> default ()
1641+
| Some t ->
1642+
match x with
1643+
| XConst (IntConst n)
1644+
when n#equal (mkNumerical 0xffffffff) && is_int t ->
1645+
Ok (int_constant_expr (-1))
1646+
| _ -> default ()
15541647

15551648
method addr_to_ctgt_xpr
15561649
?(size=None) ?(xtype=None) (a: xpr_t): xpr_t traceresult =
@@ -1852,6 +1945,7 @@ object (self)
18521945
method get_xpr_type (x: xpr_t): btype_t traceresult =
18531946
match x with
18541947
| XVar v -> self#get_variable_type v
1948+
| XOp (XPlus, [XVar v; XConst (IntConst _)]) -> self#get_variable_type v
18551949
| _ -> Error [(elocm __LINE__) ^ "xpr: " ^ (x2s x)]
18561950

18571951
method decompose_memaddr (x: xpr_t):

CodeHawk/CHB/bchlib/bCHLibTypes.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6162,7 +6162,11 @@ class type floc_int =
61626162
(** {1 Conversion to c expressions / variables}*)
61636163

61646164
method xpr_to_cxpr:
6165-
?size:int option -> ?xtype:btype_t option -> xpr_t -> xpr_t traceresult
6165+
?arithm:bool
6166+
-> ?size:int option
6167+
-> ?xtype:btype_t option
6168+
-> xpr_t
6169+
-> xpr_t traceresult
61666170

61676171
method addr_to_ctgt_xpr:
61686172
?size:int option -> ?xtype:btype_t option -> xpr_t -> xpr_t traceresult

CodeHawk/CHB/bchlibarm32/bCHFnARMDictionary.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ object (self)
796796
let xxrm_r = TR.tmap rewrite_expr xrm_r in
797797
let rresult_r = TR.tmap (rewrite_expr ?restrict:(Some 4)) result_r in
798798
let cresult_r =
799-
TR.tbind (floc#xpr_to_cxpr ~size:(Some 4)) rresult_r in
799+
TR.tbind (floc#xpr_to_cxpr ~arithm:true ~size:(Some 4)) rresult_r in
800800
let _ =
801801
TR.tfold_default
802802
(fun r -> ignore (get_string_reference floc r)) () rresult_r in

0 commit comments

Comments
 (0)