+ (* Create a "field signature" which describes certain aspects
+ * of the fields which vary between kernel versions.
+ *)
+ let fieldsig_type, fieldsigs =
+ let fieldsig_type =
+ let fields = List.map (
+ fun (name, _) ->
+ let fsname = "__fs_" ^ name in
+ <:ctyp< $lid:fsname$ : Virt_mem_types.fieldsig >>
+ ) field_types in
+ let fields = concat_record_fields _loc fields in
+ <:str_item< type fs_t = { $fields$ } >> in
+
+ let fieldsigs = List.map (
+ fun (i, (_, fields, fields_not_present)) ->
+ let make_fieldsig field_name available offset =
+ let available =
+ if available then <:expr< true >> else <:expr< false >> in
+ let fsname = "__fs_" ^ field_name in
+ <:rec_binding<
+ $lid:fsname$ =
+ { Virt_mem_types.field_available = $available$;
+ field_offset = $`int:offset$ }
+ >>
+ in
+ let fields = List.map (
+ fun (field_name, (_, offset, _)) ->
+ make_fieldsig field_name true offset
+ ) fields in
+ let fields_not_present = List.map (
+ fun field_name ->
+ make_fieldsig field_name false (-1)
+ ) fields_not_present in
+
+ let fieldsigs = fields @ fields_not_present in
+ let fsname = sprintf "fieldsig_%d" i in
+ let fieldsigs = concat_record_bindings _loc fieldsigs in
+ <:str_item<
+ let $lid:fsname$ = { () with $fieldsigs$ }
+ >>
+ ) parsers in
+
+ let fieldsigs = concat_str_items _loc fieldsigs in
+
+ fieldsig_type, fieldsigs in
+