Skip to content

Commit 5a9bc2f

Browse files
committed
CHB: add formatstring capability to type inference
1 parent c094ba5 commit 5a9bc2f

12 files changed

Lines changed: 139 additions & 17 deletions

CodeHawk/CHB/bchlib/bCHFunctionInterface.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,9 +1350,10 @@ let function_interface_to_bfuntype (fintf: function_interface_t): btype_t =
13501350
let function_type_resolvents_to_bfuntype
13511351
(name: string)
13521352
(resolvents: (register_t * btype_t option * b_attributes_t) list
1353-
* btype_t option): btype_t =
1354-
let fintf = default_function_interface name in
1355-
let (regtypes, returntype) = resolvents in
1353+
* btype_t option
1354+
* bool): btype_t =
1355+
let (regtypes, returntype, varargs) = resolvents in
1356+
let fintf = default_function_interface ~varargs name in
13561357
let fintf =
13571358
List.fold_left (fun fintf (reg, optty, _) ->
13581359
match optty with

CodeHawk/CHB/bchlib/bCHFunctionInterface.mli

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ val bvarinfo_to_function_interface: bvarinfo_t -> function_interface_t
117117

118118
val function_type_resolvents_to_bfuntype:
119119
string
120-
-> ((register_t * btype_t option * b_attributes_t) list * btype_t option)
120+
-> ((register_t * btype_t option * b_attributes_t) list
121+
* btype_t option
122+
* bool)
121123
-> btype_t
122124

123125

CodeHawk/CHB/bchlib/bCHFunctionSemantics.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,20 @@ let get_type_arg_mode
432432
| _ -> None) None predicates
433433
else
434434
mode in
435+
let mode =
436+
if Option.is_none mode then
437+
List.fold_left (fun acc p ->
438+
match acc with
439+
| Some _ -> acc
440+
| _ ->
441+
match p with
442+
| XXInputFormatString (ArgValue param)
443+
when Option.is_some param.apar_index
444+
&& (Option.get param.apar_index) = argindex ->
445+
Some ArgInputFormatString
446+
| _ -> None) None predicates
447+
else
448+
mode in
435449
let mode =
436450
if Option.is_none mode then
437451
List.fold_left (fun acc p ->

CodeHawk/CHB/bchlib/bCHLibTypes.mli

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,6 +3314,7 @@ type type_arg_mode_t =
33143314
| ArgFunctionPointer
33153315
| ArgScalarValue
33163316
| ArgOutputFormatString
3317+
| ArgInputFormatString
33173318

33183319

33193320
type type_operation_kind_t =
@@ -3334,6 +3335,11 @@ type type_cap_label_t =
33343335
| FlowsToOperation of type_operation_kind_t * bterm_t option
33353336
| FlowsFrom of bterm_t option
33363337

3338+
| FOutputFormatString
3339+
(** parameter is a printf-style format string; implies the function is variadic *)
3340+
| FInputFormatString
3341+
(** parameter is a scanf-style format string; implies the function is variadic *)
3342+
33373343
| FReturn (** for now limited to the default return register *)
33383344
| Load
33393345
| Store
@@ -3492,6 +3498,9 @@ class type type_constraint_store_int =
34923498
string
34933499
-> (register_t * btype_t option * b_attributes_t) list
34943500
* btype_t option
3501+
* bool
3502+
(** The bool is [true] if any parameter was identified as a
3503+
format-string parameter, implying the function is variadic. *)
34953504

34963505
method resolve_reglhs_type:
34973506
register_t -> string -> string -> btype_t option

CodeHawk/CHB/bchlib/bCHSumTypeSerializer.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,9 @@ object
549549
| ArgFunctionPointer -> "fp"
550550
| ArgScalarValue -> "s"
551551
| ArgOutputFormatString -> "fmt"
552+
| ArgInputFormatString -> "ifs"
552553

553-
method !tags = ["d"; "fmt"; "fp"; "r"; "rw"; "s"; "w"]
554+
method !tags = ["d"; "fmt"; "fp"; "ifs"; "r"; "rw"; "s"; "w"]
554555

555556
end
556557

@@ -593,6 +594,8 @@ object
593594
| FlowsToArg _ -> "fta"
594595
| FlowsToOperation _ -> "fto"
595596
| FlowsFrom _ -> "ffm"
597+
| FOutputFormatString -> "fofs"
598+
| FInputFormatString -> "fifs"
596599
| Load -> "l"
597600
| Store -> "s"
598601
| Deref -> "d"
@@ -602,8 +605,8 @@ object
602605
| OffsetAccessA _ -> "aa"
603606

604607
method !tags = [
605-
"a"; "aa"; "d"; "faw"; "ffm"; "fr"; "fs"; "fta"; "fto"; "fx"; "l";
606-
"lsb"; "lsh"; "s"; "sa"]
608+
"a"; "aa"; "d"; "faw"; "ffm"; "fifs"; "fofs"; "fr"; "fs"; "fta"; "fto";
609+
"fx"; "l"; "lsb"; "lsh"; "s"; "sa"]
607610

608611
end
609612

CodeHawk/CHB/bchlib/bCHTypeConstraintDictionary.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ object (self)
9494
| ArgDeallocate
9595
| ArgFunctionPointer
9696
| ArgScalarValue
97-
| ArgOutputFormatString -> (tags, []) in
97+
| ArgOutputFormatString
98+
| ArgInputFormatString -> (tags, []) in
9899
type_arg_mode_table#add key
99100

100101
method get_type_arg_mode (index: int): type_arg_mode_t =
@@ -107,6 +108,7 @@ object (self)
107108
| "d" -> ArgDeallocate
108109
| "fmt" -> ArgOutputFormatString
109110
| "fp" -> ArgFunctionPointer
111+
| "ifs" -> ArgInputFormatString
110112
| "r" -> ArgDerefRead (getsize ())
111113
| "rw" -> ArgDerefReadWrite (getsize ())
112114
| "s" -> ArgScalarValue
@@ -155,6 +157,8 @@ object (self)
155157
| FlowsFrom t ->
156158
(tags,
157159
[match t with Some t -> id#index_bterm t | _ -> (-1)])
160+
| FOutputFormatString -> (tags, [])
161+
| FInputFormatString -> (tags, [])
158162
| Load -> (tags, [])
159163
| Store -> (tags, [])
160164
| Deref -> (tags, [])
@@ -185,6 +189,8 @@ object (self)
185189
| "fto" ->
186190
FlowsToOperation (type_operation_kind_mfts#fs (t 1),
187191
if (a 0) = (-1) then None else Some (id#get_bterm (a 0)))
192+
| "fofs" -> FOutputFormatString
193+
| "fifs" -> FInputFormatString
188194
| "a" -> OffsetAccess (a 0, a 1)
189195
| "aa" -> OffsetAccessA (a 0, a 1)
190196
| s -> raise_tag_error name s type_cap_label_mcts#tags

CodeHawk/CHB/bchlib/bCHTypeConstraintStore.ml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,9 @@ object (self)
564564

565565
method resolve_function_type
566566
(faddr: string)
567-
: (register_t * btype_t option * b_attributes_t) list * btype_t option =
567+
: (register_t * btype_t option * b_attributes_t) list
568+
* btype_t option
569+
* bool =
568570
let evaluation = self#evaluate_function_type faddr in
569571
let result = H.create 4 in
570572
let returnresult = ref None in
@@ -752,7 +754,15 @@ object (self)
752754
"return: " ^ (match !returnresult with
753755
| Some ty -> btype_to_string ty
754756
| _ -> "?")] in
755-
(result, !returnresult)
757+
let varargs =
758+
H.fold (fun _k capslists acc ->
759+
acc
760+
|| List.exists
761+
(fun caps ->
762+
List.mem FOutputFormatString caps
763+
|| List.mem FInputFormatString caps) capslists)
764+
capresult false in
765+
(result, !returnresult, varargs)
756766

757767
method resolve_reglhs_type
758768
(reg: register_t) (faddr: string) (iaddr: string): btype_t option =

CodeHawk/CHB/bchlib/bCHTypeConstraintUtil.ml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ let _type_arg_mode_compare (m1: type_arg_mode_t) (m2: type_arg_mode_t): int =
7474
| (ArgScalarValue, _) -> -1
7575
| (_, ArgScalarValue) -> 1
7676
| (ArgOutputFormatString, ArgOutputFormatString) -> 0
77+
| (ArgOutputFormatString, _) -> -1
78+
| (_, ArgOutputFormatString) -> 1
79+
| (ArgInputFormatString, ArgInputFormatString) -> 0
7780

7881

7982
let type_cap_label_compare (c1: type_cap_label_t) (c2: type_cap_label_t) =
@@ -134,6 +137,12 @@ let type_cap_label_compare (c1: type_cap_label_t) (c2: type_cap_label_t) =
134137
| (_, OffsetAccess _) -> 1
135138
| (OffsetAccessA (n1, m1), OffsetAccessA (n2, m2)) ->
136139
Stdlib.compare (n1, m1) (n2, m2)
140+
| (OffsetAccessA _, _) -> -1
141+
| (_, OffsetAccessA _) -> 1
142+
| (FOutputFormatString, FOutputFormatString) -> 0
143+
| (FOutputFormatString, _) -> -1
144+
| (_, FOutputFormatString) -> 1
145+
| (FInputFormatString, FInputFormatString) -> 0
137146

138147

139148
let type_arg_mode_to_string (m: type_arg_mode_t) =
@@ -149,6 +158,7 @@ let type_arg_mode_to_string (m: type_arg_mode_t) =
149158
| ArgFunctionPointer -> "fp"
150159
| ArgScalarValue -> "sv"
151160
| ArgOutputFormatString -> "ofs"
161+
| ArgInputFormatString -> "ifs"
152162

153163

154164
let type_operation_kind_to_string (op: type_operation_kind_t) =
@@ -180,6 +190,8 @@ let type_cap_label_to_string (c: type_cap_label_t) =
180190
^ (type_operation_kind_to_string op)
181191
^ (optbterm_to_string t)
182192
| FlowsFrom t -> "flowsfrom" ^ (optbterm_to_string t)
193+
| FOutputFormatString -> "output-format-string"
194+
| FInputFormatString -> "input-format-string"
183195
| Load -> "load"
184196
| Store -> "store"
185197
| Deref -> "deref"
@@ -469,6 +481,14 @@ let add_stack_address_capability (offset: int) (tv: type_variable_t)
469481
add_capability [FLocStackAddress offset] tv
470482

471483

484+
let add_output_format_string_capability (tv: type_variable_t): type_variable_t =
485+
add_capability [FOutputFormatString] tv
486+
487+
488+
let add_input_format_string_capability (tv: type_variable_t): type_variable_t =
489+
add_capability [FInputFormatString] tv
490+
491+
472492
let convert_function_capabilities_to_attributes
473493
(paramindex: int) (caps: type_cap_label_t list): b_attributes_t =
474494
let type_arg_mode_to_cons_attrparam (m: type_arg_mode_t) =
@@ -484,6 +504,7 @@ let convert_function_capabilities_to_attributes
484504
| ArgFunctionPointer -> ACons ("fp", [])
485505
| ArgScalarValue -> ACons ("sv", [])
486506
| ArgOutputFormatString -> ACons ("printf_format_string", [])
507+
| ArgInputFormatString -> ACons ("scanf_format_string", [])
487508
in
488509
let result = new CHUtils.IntCollections.set_t in
489510
let _ =
@@ -498,6 +519,14 @@ let convert_function_capabilities_to_attributes
498519
AInt argindex;
499520
type_arg_mode_to_cons_attrparam mode]) in
500521
result#add (bcd#index_attribute attr)
522+
| FOutputFormatString ->
523+
let attr =
524+
Attr ("format", [ACons ("printf", []); AInt paramindex; AInt 0]) in
525+
result#add (bcd#index_attribute attr)
526+
| FInputFormatString ->
527+
let attr =
528+
Attr ("format", [ACons ("scanf", []); AInt paramindex; AInt 0]) in
529+
result#add (bcd#index_attribute attr)
501530
| _ -> ()) caps in
502531
List.map bcd#get_attribute result#toList
503532

CodeHawk/CHB/bchlib/bCHTypeConstraintUtil.mli

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,22 @@ val add_flows_from_capability:
245245
val add_stack_address_capability: int -> type_variable_t -> type_variable_t
246246

247247

248+
(** [add_output_format_string_capability tv] returns a new type variable that
249+
appends an [FOutputFormatString] capability to [tv], which is expected to
250+
already carry an [FRegParameter] prefix (set via [add_freg_param_capability]).
251+
Indicates that the named parameter is a printf-style format string parameter
252+
and thus the enclosing function is variadic. *)
253+
val add_output_format_string_capability: type_variable_t -> type_variable_t
254+
255+
256+
(** [add_input_format_string_capability tv] returns a new type variable that
257+
appends an [FInputFormatString] capability to [tv], which is expected to
258+
already carry an [FRegParameter] prefix (set via [add_freg_param_capability]).
259+
Indicates that the named parameter is a scanf-style format string parameter
260+
and thus the enclosing function is variadic. *)
261+
val add_input_format_string_capability: type_variable_t -> type_variable_t
262+
263+
248264
val drop_capability: type_cap_label_t -> type_variable_t -> type_variable_t
249265

250266

CodeHawk/CHB/bchlib/bCHVersion.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ end
9595

9696

9797
let version = new version_info_t
98-
~version:"0.6.0_20260601"
99-
~date:"2026-06-01"
98+
~version:"0.6.0_20260610"
99+
~date:"2026-06-10"
100100
~licensee: None
101101
~maxfilesize: None
102102
()

0 commit comments

Comments
 (0)