Skip to content

Commit 9dc36c5

Browse files
committed
CHB: add facility to decompose array expressions
1 parent 2fd52d4 commit 9dc36c5

16 files changed

+382
-89
lines changed

CodeHawk/CHB/bchlib/bCHBCTypeUtil.ml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ open BCHBCFiles
4141
open BCHBCTypePretty
4242
open BCHBCTypes
4343

44+
4445
let string_printer = CHPrettyUtil.string_printer
4546
let p2s = string_printer#print
4647

@@ -941,6 +942,32 @@ let get_compinfo_field (c: bcompinfo_t) (fname: string): bfieldinfo_t =
941942
STR fname]))
942943

943944

945+
let get_struct_field_at_offset
946+
(cinfo: bcompinfo_t) (offset: int): (bfieldinfo_t * int) option =
947+
let finfos = cinfo.bcfields in
948+
let field0 = List.hd finfos in
949+
if offset = 0 then
950+
Some (field0, 0)
951+
else
952+
let field0type = resolve_type field0.bftype in
953+
if offset < size_of_btype field0type then
954+
Some (field0, offset)
955+
else
956+
List.fold_left (fun acc finfo ->
957+
match acc with
958+
| Some _ -> acc
959+
| _ ->
960+
match finfo.bfieldlayout with
961+
| Some (foffset, size) ->
962+
if offset = foffset then
963+
Some (finfo, 0)
964+
else if offset > foffset && offset < foffset + size then
965+
Some (finfo, offset - foffset)
966+
else
967+
None
968+
| _ -> None) None finfos
969+
970+
944971
let rec get_compinfo_scalar_type_at_offset
945972
(cinfo: bcompinfo_t) (offset: int): btype_t option =
946973
let finfos = cinfo.bcfields in

CodeHawk/CHB/bchlib/bCHBCTypeUtil.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,15 @@ val get_struct_type_compinfo: btype_t -> bcompinfo_t
226226

227227
val get_struct_type_fields: btype_t -> bfieldinfo_t list
228228

229+
val get_struct_field_at_offset: bcompinfo_t -> int -> (bfieldinfo_t * int) option
230+
229231
val get_compinfo_struct_type: bcompinfo_t -> btype_t
230232

231233
val get_compinfo_field: bcompinfo_t -> string -> bfieldinfo_t
232234

233235
val get_compinfo_scalar_type_at_offset: bcompinfo_t -> int -> btype_t option
234236

237+
235238
(** {2 Fieldinfos}*)
236239

237240
val get_struct_field_name: bfieldinfo_t -> string

CodeHawk/CHB/bchlib/bCHConstantDefinitions.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,8 @@ val read_xml_symbolic_flags: xml_element_int -> unit
148148
narrowed to a particular type [ty].*)
149149
val has_constant_value: ?ty:btype_t option -> string -> bool
150150
val get_constant_value: ?ty:btype_t option -> string -> doubleword_int
151+
152+
153+
(** {1 Access for unit tests} *)
154+
155+
val add_address: constant_definition_t -> unit

CodeHawk/CHB/bchlib/bCHFloc.ml

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,29 +1069,51 @@ object (self)
10691069

10701070
method get_fts_parameter_expr (_p: fts_parameter_t) = None
10711071

1072-
method private get_offset ox =
1073-
let oxs = simplify_xpr ox in
1074-
match oxs with
1075-
| XConst (IntConst n) -> ConstantOffset (n, NoOffset)
1076-
| XVar v -> IndexOffset (v, 1, NoOffset)
1077-
| XOp (XMult, [XConst (IntConst n); XVar v]) when n#is_int ->
1078-
IndexOffset (v, n#toInt, NoOffset)
1079-
| XOp (XMult, [XConst (IntConst _); XVar _]) ->
1080-
let msg = LBLOCK [self#l#toPretty; STR ": floc#get_offset: "; x2p oxs] in
1081-
begin
1082-
ch_error_log#add "number too large" msg;
1083-
UnknownOffset
1084-
end
1085-
| XOp (XPlus, [XConst (IntConst n); y]) ->
1086-
ConstantOffset (n, self#get_offset y)
1087-
| _ ->
1088-
let msg = (LBLOCK [STR "offset expr: "; x2p oxs]) in
1089-
begin
1090-
ch_error_log#add
1091-
"unknown offset expr"
1092-
(LBLOCK [self#l#toPretty; STR " "; msg]);
1093-
UnknownOffset
1094-
end
1072+
method decompose_array_address
1073+
(x: xpr_t): (memory_reference_int * memory_offset_t) option =
1074+
let _ = chlog#add "decompose_array_address" (LBLOCK [STR "xpr: "; x2p x]) in
1075+
let vars = vars_as_positive_terms x in
1076+
let memaddrs = List.filter self#f#env#is_memory_address_variable vars in
1077+
let optbase =
1078+
match memaddrs with
1079+
| [base] ->
1080+
let (_, _, _, optty) =
1081+
self#f#env#varmgr#get_memory_address_meminfo base in
1082+
let offset = simplify_xpr (XOp (XMinus, [x; XVar base])) in
1083+
Some (XVar base, offset, optty)
1084+
| _ ->
1085+
None in
1086+
match optbase with
1087+
| None -> None
1088+
| Some (_, _, None) -> None
1089+
| Some (XVar base, xoffset, Some ty) ->
1090+
let _ =
1091+
chlog#add
1092+
"decompose_array_address" (LBLOCK [STR "xoffset: "; x2p xoffset]) in
1093+
let eltty = get_element_type ty in
1094+
let elttysize = size_of_btype eltty in
1095+
let optmemref = TR.to_option (self#env#mk_base_variable_reference base) in
1096+
let optindex = get_array_index_offset xoffset elttysize in
1097+
let memoffset =
1098+
match optindex with
1099+
| None ->
1100+
let _ =
1101+
chlog#add
1102+
"decompose_array_address"
1103+
(LBLOCK [
1104+
STR "Unable to get array index offset for ";
1105+
x2p xoffset;
1106+
STR " with size ";
1107+
INT elttysize]) in
1108+
UnknownOffset
1109+
| Some (indexxpr, rem) ->
1110+
let remoffset = mk_maximal_memory_offset rem eltty in
1111+
ArrayIndexOffset (indexxpr, remoffset) in
1112+
(match (optmemref, memoffset) with
1113+
| (_, UnknownOffset) -> None
1114+
| (Some memref, memoffset) -> Some (memref, memoffset)
1115+
| _ -> None)
1116+
| _ -> None
10951117

10961118

10971119
(* the objective is to extract a base pointer and an offset expression

CodeHawk/CHB/bchlib/bCHFunctionInfo.ml

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -789,19 +789,25 @@ object (self)
789789
?(size=4)
790790
?(offset=0)
791791
(var: variable_t): variable_t =
792-
if self#is_memory_address_variable var then
793-
let (memrefix, memoffset, optname) = varmgr#get_memory_address_meminfo var in
794-
let memref = TR.tget_ok (varmgr#memrefmgr#get_memory_reference memrefix) in
795-
let v = self#mk_index_offset_memory_variable memref memoffset in
796-
let _ =
797-
match optname with
798-
| Some name -> self#set_variable_name v name
799-
| _ -> () in
800-
v
792+
if offset = 0 then
793+
if self#is_memory_address_variable var then
794+
let (memrefix, memoffset, optname, _optty) =
795+
varmgr#get_memory_address_meminfo var in
796+
let memref = TR.tget_ok (varmgr#memrefmgr#get_memory_reference memrefix) in
797+
let v = self#mk_index_offset_memory_variable ~size memref memoffset in
798+
let _ =
799+
match optname with
800+
| Some name -> self#set_variable_name v name
801+
| _ -> () in
802+
v
803+
else
804+
raise
805+
(BCH_failure
806+
(LBLOCK [STR "Not a memory address variable"; var#toPretty]))
801807
else
802808
raise
803809
(BCH_failure
804-
(LBLOCK [STR "Not a memory address variable"; var#toPretty]))
810+
(LBLOCK [STR "Nonstandard size or offset not yet supported"]))
805811

806812
method mk_index_offset_global_memory_variable
807813
?(elementsize=4)
@@ -929,8 +935,9 @@ object (self)
929935
else
930936
default ()
931937

932-
method mk_global_memory_address ?(optname = None) (n: numerical_t) =
933-
self#mk_variable (varmgr#make_global_memory_address ~optname n)
938+
method mk_global_memory_address
939+
?(optname = None) ?(opttype=None) (n: numerical_t) =
940+
self#mk_variable (varmgr#make_global_memory_address ~optname ~opttype n)
934941

935942
method mk_register_variable (register:register_t) =
936943
self#mk_variable (varmgr#make_register_variable register)

CodeHawk/CHB/bchlib/bCHLibTypes.mli

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,8 +3218,13 @@ type memory_base_t =
32183218
| BRealignedStackFrame (** local stack frame after realignment *)
32193219
| BAllocatedStackFrame (** extended stack frame from alloca *)
32203220
| BGlobal (** global data *)
3221-
| BaseVar of variable_t (** base provided by an externally controlled variable,
3222-
e.g., argument to the function, or return value from malloc *)
3221+
| BaseVar of variable_t
3222+
(** base provided by an externally controlled variable,
3223+
e.g., argument to the function, or return value from malloc *)
3224+
3225+
| BaseArray of variable_t * btype_t
3226+
(** base provided by a typed array address *)
3227+
32233228
| BaseUnknown of string (** address without interpretation *)
32243229

32253230

@@ -3228,7 +3233,8 @@ type memory_offset_t =
32283233
| NoOffset
32293234
| ConstantOffset of numerical_t * memory_offset_t
32303235
| FieldOffset of fielduse_t * memory_offset_t
3231-
| IndexOffset of variable_t * int * memory_offset_t
3236+
| IndexOffset of variable_t * int * memory_offset_t (* deprecated *)
3237+
| ArrayIndexOffset of xpr_t * memory_offset_t (* scaled by element type size *)
32323238
| UnknownOffset
32333239

32343240

@@ -3269,6 +3275,7 @@ object
32693275
method mk_allocated_stack_reference: memory_reference_int
32703276
method mk_realigned_stack_reference: memory_reference_int
32713277
method mk_basevar_reference: variable_t -> memory_reference_int
3278+
method mk_base_array_reference: variable_t -> btype_t -> memory_reference_int
32723279
method mk_unknown_reference: string -> memory_reference_int
32733280

32743281
(* accessors *)
@@ -3375,8 +3382,8 @@ and constant_value_variable_t =
33753382
assigned by the callee at call site [iaddr] to the argument with
33763383
name [name].*)
33773384

3378-
| MemoryAddress of int * memory_offset_t * string option
3379-
(** [MemoryAddress (memrefix, offset, optname) represents a memory
3385+
| MemoryAddress of int * memory_offset_t * string option * btype_t option
3386+
(** [MemoryAddress (memrefix, offset, optname, opttype) represents a memory
33803387
address with external meaning (e.g., a global arrray) *)
33813388

33823389
| BridgeVariable of ctxt_iaddress_t * int (* call site, argument index *)
@@ -3427,7 +3434,8 @@ object ('a)
34273434
Returns [Error] if this variable is not a memory variable. *)
34283435
method get_memory_offset: memory_offset_t traceresult
34293436

3430-
method get_memory_address_meminfo: (int * memory_offset_t * string option)
3437+
method get_memory_address_meminfo:
3438+
(int * memory_offset_t * string option * btype_t option)
34313439

34323440
(** Returns the name of the associated function pointer.
34333441
@@ -3658,7 +3666,10 @@ object
36583666
-> assembly_variable_int
36593667

36603668
method make_global_memory_address:
3661-
?optname:string option -> numerical_t -> assembly_variable_int
3669+
?optname:string option
3670+
-> ?opttype:btype_t option
3671+
-> numerical_t
3672+
-> assembly_variable_int
36623673

36633674
(** {2 Auxiliary variables}*)
36643675

@@ -3820,7 +3831,7 @@ object
38203831
method is_memory_address_variable: variable_t -> bool
38213832

38223833
method get_memory_address_meminfo:
3823-
variable_t -> (int * memory_offset_t * string option)
3834+
variable_t -> (int * memory_offset_t * string option * btype_t option)
38243835

38253836

38263837
(** {2 Memory offsets} *)
@@ -4215,7 +4226,10 @@ class type function_environment_int =
42154226
?size:int -> ?offset:memory_offset_t -> numerical_t -> variable_t
42164227

42174228
method mk_global_memory_address:
4218-
?optname: string option -> numerical_t -> variable_t
4229+
?optname: string option
4230+
-> ?opttype: btype_t option
4231+
-> numerical_t
4232+
-> variable_t
42194233

42204234
method mk_initial_memory_value: variable_t -> variable_t
42214235

@@ -4243,7 +4257,10 @@ class type function_environment_int =
42434257
(** {2 Memory address variables} *)
42444258

42454259
method mk_global_memory_address:
4246-
?optname: string option -> numerical_t -> variable_t
4260+
?optname: string option
4261+
-> ?opttype: btype_t option
4262+
-> numerical_t
4263+
-> variable_t
42474264

42484265
(** {2 Other variables} *)
42494266

@@ -5449,6 +5466,9 @@ class type floc_int =
54495466
(* returns the memory reference that corresponds to the address expression *)
54505467
method decompose_address: xpr_t -> (memory_reference_int * memory_offset_t)
54515468

5469+
method decompose_array_address:
5470+
xpr_t -> (memory_reference_int * memory_offset_t) option
5471+
54525472
(* returns the variable associated with the address expression *)
54535473
method get_lhs_from_address: xpr_t -> variable_t
54545474

0 commit comments

Comments
 (0)