Skip to content

Commit db5eae8

Browse files
committed
CHB: add error-enabled assign commands
1 parent 46ab5ba commit db5eae8

File tree

4 files changed

+209
-4
lines changed

4 files changed

+209
-4
lines changed

CodeHawk/CH/chutil/cHTraceResult.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,25 @@ let tmap2
6161
| Error e1, Error e2 -> Error (msg1 :: msg2 :: (e1 @ e2))
6262

6363

64+
let tmap3
65+
?(msg1="")
66+
?(msg2="")
67+
?(msg3="")
68+
(f: 'a -> 'b -> 'c -> 'd)
69+
(r1: 'a traceresult)
70+
(r2: 'b traceresult)
71+
(r3: 'c traceresult): 'd traceresult =
72+
match r1, r2, r3 with
73+
| Ok v1, Ok v2, Ok v3 -> Ok (f v1 v2 v3)
74+
| Error e1, Ok _, Ok _ -> Error (msg1 :: e1)
75+
| Ok _, Error e2, Ok _ -> Error (msg2 :: e2)
76+
| Ok _, Ok _, Error e3 -> Error (msg3 :: e3)
77+
| Error e1, Error e2, Ok _ -> Error (msg1 :: msg2 :: (e1 @ e2))
78+
| Error e1, Ok _, Error e3 -> Error (msg1 :: msg3 :: (e1 @ e3))
79+
| Ok _, Error e2, Error e3 -> Error (msg2 :: msg3 :: (e2 @ e3))
80+
| Error e1, Error e2, Error e3 -> Error (msg1 :: msg2 :: msg3 :: (e1 @ e2 @ e3))
81+
82+
6483
let tbind ?(msg="") (f: 'a -> 'c traceresult) (r: 'a traceresult) =
6584
match r with
6685
| Ok v -> f v

CodeHawk/CH/chutil/cHTraceResult.mli

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ val tmap2:
6565
-> 'c traceresult
6666

6767

68+
(** [tmap3 f r1 r2 r3] is [Ok (f v1 v2 v3)] if [r1] is [Ok v1] and [r2] is
69+
[Ok v2] and [r3] is [Ok v3]; otherwise it returns an [Error] appending
70+
the messages corresponding to the error value as appropriate.*)
71+
val tmap3:
72+
?msg1:string
73+
-> ?msg2:string
74+
-> ?msg3:string
75+
-> ('a -> 'b -> 'c -> 'd)
76+
-> 'a traceresult
77+
-> 'b traceresult
78+
-> 'c traceresult
79+
-> 'd traceresult
80+
81+
6882
(** [tfold ~ok ~error r] is [ok v] if [r] is [Ok v] and [error e] if [r] is
6983
[Error e].*)
7084
val tfold: ok:('a -> 'c) -> error:(string list -> 'c) -> 'a traceresult -> 'c

CodeHawk/CHB/bchlib/bCHFloc.ml

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,31 @@ object (self)
766766
* resolve and save ScaledReg (cpureg1, cpureg2, 1, offset) (memrefs2)
767767
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
768768

769+
method get_memory_variable_varoffset
770+
?(size=4) (var1: variable_t) (var2: variable_t) (offset: numerical_t):
771+
variable_t traceresult =
772+
let addr = XOp (XPlus, [XVar var1; XVar var2]) in
773+
let addr = XOp (XPlus, [addr; num_constant_expr offset]) in
774+
let address = simplify_xpr (self#inv#rewrite_expr addr) in
775+
let (memref_r, memoff_r) = self#decompose_memaddr address in
776+
tbind
777+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
778+
(fun memref ->
779+
if memref#is_global_reference then
780+
tbind
781+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": memref:global")
782+
(fun memoff ->
783+
self#env#mk_global_variable ~size (get_total_constant_offset memoff))
784+
memoff_r
785+
else
786+
tmap
787+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
788+
(fun memoff ->
789+
(self#env#mk_memory_variable
790+
memref (get_total_constant_offset memoff)))
791+
memoff_r)
792+
memref_r
793+
769794
method get_memory_variable_2
770795
?(size=4) (var1:variable_t) (var2:variable_t) (offset:numerical_t) =
771796
let _ = track_function
@@ -792,6 +817,42 @@ object (self)
792817
* resolve and save ScaledReg (cpureg1, cpureg2, s, offset) (memrefs3)
793818
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
794819

820+
method get_memory_variable_scaledoffset
821+
?(size=4)
822+
(base: variable_t)
823+
(index: variable_t)
824+
(scale: int)
825+
(offset: numerical_t): variable_t traceresult =
826+
let indexexpr =
827+
if self#inv#is_constant index then
828+
num_constant_expr (self#inv#get_constant index)
829+
else
830+
XVar index in
831+
let addr = XOp (XPlus, [XVar base; num_constant_expr offset]) in
832+
let addr = self#inv#rewrite_expr addr in
833+
let addr =
834+
XOp (XPlus,
835+
[addr; XOp (XMult, [int_constant_expr scale; indexexpr])]) in
836+
let address = simplify_xpr (self#inv#rewrite_expr addr) in
837+
let (memref_r, memoff_r) = self#decompose_memaddr address in
838+
tbind
839+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
840+
(fun memref ->
841+
if memref#is_global_reference then
842+
tbind
843+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__) ^ ": memref:global")
844+
(fun memoff ->
845+
self#env#mk_global_variable ~size (get_total_constant_offset memoff))
846+
memoff_r
847+
else
848+
tmap
849+
~msg:(__FILE__ ^ ":" ^ (string_of_int __LINE__))
850+
(fun memoff ->
851+
(self#env#mk_memory_variable
852+
memref (get_total_constant_offset memoff)))
853+
memoff_r)
854+
memref_r
855+
795856
method get_memory_variable_3
796857
?(size=4)
797858
(base:variable_t)
@@ -1528,6 +1589,65 @@ object (self)
15281589
(List.length vars) > 0
15291590
&& List.for_all is_fixed_type (variables_in_expr x)
15301591

1592+
method get_assign_commands_r
1593+
?(signed=false)
1594+
?(size=4)
1595+
(lhs_r: variable_t traceresult)
1596+
(rhs_r: xpr_t traceresult): cmd_t list =
1597+
if Result.is_error lhs_r then
1598+
let (cmds, op_args) =
1599+
TR.tfold
1600+
~ok:(fun rhs ->
1601+
let reqN () = self#env#mk_num_temp in
1602+
let reqC = self#env#request_num_constant in
1603+
let (rhscmds, rhs_c) = xpr_to_numexpr reqN reqC rhs in
1604+
(rhscmds, get_rhs_op_args rhs_c))
1605+
~error:(fun e ->
1606+
begin
1607+
log_error_result
1608+
~tag:("assignment lhs unknown")
1609+
~msg:(p2s self#l#toPretty)
1610+
__FILE__ __LINE__ e;
1611+
([], [])
1612+
end)
1613+
rhs_r in
1614+
cmds @ [OPERATION ({op_name = unknown_write_symbol; op_args = op_args})]
1615+
1616+
else if Result.is_error rhs_r then
1617+
let lhs = TR.tget_ok lhs_r in
1618+
[ABSTRACT_VARS [lhs]]
1619+
1620+
else
1621+
let lhs = TR.tget_ok lhs_r in
1622+
let rhs = TR.tget_ok rhs_r in
1623+
let rhs = simplify_xpr (self#inv#rewrite_expr rhs) in
1624+
let rhs =
1625+
if not signed then
1626+
match rhs with
1627+
| XConst (IntConst n) ->
1628+
let n =
1629+
match size with
1630+
| 1 -> n#modulo numerical_e8
1631+
| 2 -> n#modulo numerical_e16
1632+
| 4 -> n#modulo numerical_e32
1633+
| _ -> n in
1634+
num_constant_expr n
1635+
| _ -> rhs
1636+
else
1637+
rhs in
1638+
1639+
let rhs =
1640+
(* if rhs is a composite symbolic expression, create a new variable
1641+
for it *)
1642+
if self#is_composite_symbolic_value rhs then
1643+
XVar (self#env#mk_symbolic_value rhs)
1644+
else
1645+
rhs in
1646+
let reqN () = self#env#mk_num_temp in
1647+
let reqC = self#env#request_num_constant in
1648+
let (rhscmds, rhs_c) = xpr_to_numexpr reqN reqC rhs in
1649+
rhscmds @ [ASSIGN_NUM (lhs, rhs_c)]
1650+
15311651
(* Note: recording of loads and stores is performed by the different
15321652
architectures directly in FnXXXDictionary.*)
15331653
method get_assign_commands
@@ -1753,6 +1873,18 @@ object (self)
17531873
(x2s size) (btype_to_string vtype) in
17541874
[ABSTRACT_VARS [lhs]]
17551875

1876+
method get_abstract_commands_r (lhs_r: variable_t traceresult): cmd_t list =
1877+
TR.tfold
1878+
~ok:(fun lhs -> [ABSTRACT_VARS [lhs]])
1879+
~error:(fun e ->
1880+
begin
1881+
log_error_result
1882+
~tag:"lhs not abstracted" ~msg:(p2s self#l#toPretty)
1883+
__FILE__ __LINE__ e;
1884+
[]
1885+
end)
1886+
lhs_r
1887+
17561888
method get_ssa_abstract_commands (reg: register_t) () =
17571889
let regvar = self#env#mk_register_variable reg in
17581890
(regvar, [ABSTRACT_VARS [regvar]])

CodeHawk/CHB/bchlib/bCHLibTypes.mli

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5785,11 +5785,26 @@ class type floc_int =
57855785
-> numerical_t
57865786
-> variable_t
57875787

5788+
method get_memory_variable_varoffset:
5789+
?size:int
5790+
-> variable_t
5791+
-> variable_t
5792+
-> numerical_t
5793+
-> variable_t traceresult
5794+
57885795
(* returns the memory reference corresponding to a base and index
57895796
variable plus offset *)
57905797
method get_memory_variable_2:
57915798
?size:int -> variable_t -> variable_t -> numerical_t -> variable_t
57925799

5800+
method get_memory_variable_scaledoffset:
5801+
?size:int
5802+
-> variable_t
5803+
-> variable_t
5804+
-> int
5805+
-> numerical_t
5806+
-> variable_t traceresult
5807+
57935808
(* returns the memory reference corresponding to a base and scaled index
57945809
variable plus offset *)
57955810
method get_memory_variable_3:
@@ -5940,7 +5955,7 @@ class type floc_int =
59405955

59415956
(** {2 Assignments} *)
59425957

5943-
(** [floc#get_assign_commands var ~size ~vtype xpr] returns the CHIF commands
5958+
(** [get_assign_commands var ~size ~vtype xpr] returns the CHIF commands
59445959
representing the assignment [var := xpr].
59455960
59465961
If [size] is not None and the left-hand side [var] is externally observable
@@ -5949,6 +5964,8 @@ class type floc_int =
59495964
59505965
If [vtype] is known type facts are added for both [var] and [xpr] for this
59515966
instruction.
5967+
5968+
Deprecated. To be replaced with [get_assign_commands_r].
59525969
*)
59535970
method get_assign_commands:
59545971
variable_t
@@ -5957,13 +5974,31 @@ class type floc_int =
59575974
-> xpr_t
59585975
-> cmd_t list
59595976

5960-
(** [floc#get_ssa_assign_commands reg ~vtype xpr] creates an ssa-register
5977+
(** [get_assign_commands_r var xpr] returns the CHIF commands representing
5978+
the assignment [var := xpr].
5979+
5980+
If [size] of [var] (in bytes) is different from the default value 4,
5981+
the value of [xpr] is restricted to the given width if the value is a
5982+
numerical constant.*)
5983+
method get_assign_commands_r:
5984+
?signed:bool
5985+
-> ?size:int
5986+
-> variable_t traceresult
5987+
-> xpr_t traceresult
5988+
-> cmd_t list
5989+
5990+
5991+
(** [get_ssa_assign_commands reg ~vtype xpr] creates an ssa-register
59615992
variable [ssavar] for the current context address and returns
59625993
a tuple of the register-variable, and the CHIF commands representing
59635994
the assignment and assert-equal:
59645995
{[ reg := xpr
59655996
assert (reg = ssavar)
5966-
]} *)
5997+
]}
5998+
5999+
Deprecated. All ssa variables have been moved to the python front end.
6000+
To be replaced with [get_assign_commands_r].
6001+
*)
59676002
method get_ssa_assign_commands:
59686003
register_t
59696004
-> ?vtype:btype_t
@@ -5977,14 +6012,19 @@ class type floc_int =
59776012

59786013
(** {2 Variable abstraction}*)
59796014

6015+
method get_abstract_commands_r: variable_t traceresult -> cmd_t list
6016+
59806017
(* returns the CHIF code associated with an abstraction of variables *)
59816018
method get_abstract_commands:
59826019
variable_t -> ?size:xpr_t -> ?vtype:btype_t -> unit -> cmd_t list
59836020

59846021
(** floc#[get_ssa_abstract_commands reg ()] creates an ssa-register
59856022
variable [ssavar] for the current context address and returns a tuple of
59866023
the register-variable and the CHIF commands representing the assignment
5987-
{[ reg := ssavar ]}*)
6024+
{[ reg := ssavar ]}
6025+
6026+
Deprecated. To be replaced with [get_abstract_commands_r]
6027+
*)
59886028
method get_ssa_abstract_commands:
59896029
register_t -> unit -> (variable_t * cmd_t list)
59906030

0 commit comments

Comments
 (0)