Structure parsers reintroduced. ** NOT WORKING **
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 14 Aug 2008 17:19:29 +0000 (18:19 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 14 Aug 2008 17:19:29 +0000 (18:19 +0100)
extract/codegen/code_generation.ml
extract/codegen/code_generation.mli
extract/codegen/compile_kerneldb.ml
extract/codegen/pahole_parser.ml
extract/codegen/pahole_parser.mli
extract/codegen/struct_classify.ml
extract/codegen/struct_classify.mli
lib/.depend
lib/kernel.ml
lib/kernel.mli

index 2dba820..37bffc2 100644 (file)
@@ -94,38 +94,38 @@ let generate_types xs =
   let strs = List.map (
     fun (struct_name, sflist, cflist) ->
       let sflist = List.map (
-       fun { SC.sf_name = name; sf_fields = fields } ->
+       fun { SC.sf_name = sf_name; sf_fields = fields } ->
          if fields <> [] then (
            let fields = List.map (
              fun { PP.field_name = name; PP.field_type = t } ->
                let t = ocaml_type_of_field_type t in
-               <:ctyp< $lid:name$ : $t$ >>
+               <:ctyp< $lid:sf_name^"_"^name$ : $t$ >>
            ) fields in
            let fields = concat_record_fields fields in
 
            <:str_item<
-             type $lid:name$ = { $fields$ }
+             type $lid:sf_name$ = { $fields$ }
             >>
          ) else
-           <:str_item< type $lid:name$ = unit >>
+           <:str_item< type $lid:sf_name$ = unit >>
       ) sflist in
       let sflist = concat_str_items sflist in
 
       let cflist = List.map (
-       fun { SC.cf_name = name; cf_fields = fields } ->
+       fun { SC.cf_name = cf_name; cf_fields = fields } ->
          if fields <> [] then (
            let fields = List.map (
              fun { PP.field_name = name; PP.field_type = t } ->
                let t = ocaml_type_of_field_type t in
-               <:ctyp< $lid:name$ : $t$ >>
+               <:ctyp< $lid:cf_name^"_"^name$ : $t$ >>
            ) fields in
            let fields = concat_record_fields fields in
 
            <:str_item<
-             type $lid:name$ = { $fields$ }
+             type $lid:cf_name$ = { $fields$ }
             >>
          ) else
-           <:str_item< type $lid:name$ = unit >>
+           <:str_item< type $lid:cf_name$ = unit >>
       ) cflist in
       let cflist = concat_str_items cflist in
 
@@ -149,10 +149,179 @@ let generate_types xs =
 
   concat_str_items strs, concat_sig_items sigs
 
-let output_interf ~output_file types =
-  let sigs = concat_sig_items [ types ] in
+let generate_parsers xs =
+  let strs =
+    List.map (
+      fun (struct_name, palist) ->
+       let palist =
+         List.map (
+           fun { SC.pa_name = pa_name } ->
+             <:str_item< let $lid:pa_name$ bits = $str:pa_name$ >>
+         ) palist in
+       concat_str_items palist
+    ) xs in
+
+  let strs = concat_str_items strs in
+  let strs =
+    <:str_item<
+      let match_err = "failed to match kernel structure" ;;
+      let zero = 0 ;;
+      $strs$
+    >> in
+
+  (* The shared parser functions.
+   * 
+   * We could include bitmatch statements directly in here, but
+   * what happens is that the macros get expanded here, resulting
+   * in (even more) unreadable generated code.  So instead just
+   * do a textual substitution later by post-processing the
+   * generated files.  Not type-safe, but we can't have
+   * everything.
+   *)
+  let subs = Hashtbl.create 13 in
+  List.iter (
+    fun (struct_name, palist) ->
+      List.iter (
+       fun ({ SC.pa_name = pa_name;
+              pa_endian = endian; pa_structure = structure;
+              pa_shape_field_struct = sf;
+              pa_content_field_struct = cf }) ->
+         (* Generate the code to match this structure. *)
+         let endian =
+           match endian with
+           | Bitstring.LittleEndian -> "littleendian"
+           | Bitstring.BigEndian -> "bigendian"
+           | _ -> assert false in
+         let patterns =
+           String.concat ";\n      " (
+             List.map (
+               function
+               | { PP.field_name = field_name;
+                   field_type = PP.FInteger;
+                   field_offset = offset;
+                   field_size = size } ->
+                   (* 'zero+' is a hack to force the type to int64. *)
+                   sprintf "%s : zero+%d : offset(%d), %s"
+                     field_name (size*8) (offset*8) endian
+
+               | { PP.field_name = field_name;
+                   field_type = (PP.FStructPointer _
+                                 | PP.FVoidPointer
+                                 | PP.FAnonListHeadPointer
+                                 | PP.FListHeadPointer _);
+                   field_offset = offset;
+                   field_size = size } ->
+                   sprintf "%s : zero+%d : offset(%d), %s"
+                     field_name (size*8) (offset*8) endian
+
+               | { PP.field_name = field_name;
+                   field_type = PP.FString width;
+                   field_offset = offset;
+                   field_size = size } ->
+                   sprintf "%s : %d : offset(%d), string"
+                     field_name (width*8) (offset*8)
+             ) structure.PP.struct_fields
+           ) in
+
+         let shape_assignments =
+           List.map (
+             fun { PP.field_name = field_name;
+                   field_type = field_type;
+                   field_offset = offset } ->
+
+               match field_type with
+               | PP.FListHeadPointer None ->
+                   sprintf "%s_%s = Int64.sub %s %dL"
+                     sf.SC.sf_name field_name field_name offset
+
+               | PP.FListHeadPointer (Some (other_struct_name, other_field_name)) ->
+                   let other_offset = 666 in
+                   sprintf "%s_%s = Int64.sub %s %dL"
+                     sf.SC.sf_name field_name field_name other_offset
+
+               | _ ->
+                   sprintf "%s_%s = %s" sf.SC.sf_name field_name field_name
+           ) sf.SC.sf_fields in
+
+         let shape_assignments =
+           String.concat ";\n        " shape_assignments in
+
+         let content_assignments =
+           List.map (
+             fun { PP.field_name = field_name } ->
+               sprintf "%s_%s = %s" sf.SC.sf_name field_name field_name
+           ) sf.SC.sf_fields in
+
+         let content_assignments =
+           String.concat ";\n        " content_assignments in
+
+         let code =
+           sprintf "
+  bitmatch bits with
+  | { %s } ->
+      let shape =
+      { %s } in
+      let content =
+      { %s } in
+      { %s_shape = shape; %s_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError (%S, %S, match_err))"
+             patterns shape_assignments content_assignments
+             struct_name struct_name
+             struct_name pa_name in
+
+         Hashtbl.add subs pa_name code
+      ) palist;
+  ) xs;
+
+  strs, <:sig_item< >>, subs
+
+let output_interf ~output_file types parsers =
+  let sigs = concat_sig_items [ types; parsers ] in
   Printers.OCaml.print_interf ~output_file sigs
 
-let output_implem ~output_file types =
-  let strs = concat_str_items [ types ] in
-  Printers.OCaml.print_implem ~output_file strs
+(* Finally generate the output files. *)
+let re_subst = Pcre.regexp "^(.*)\"(\\w+_parser_\\d+)\"(.*)$"
+
+let output_implem ~output_file types parsers parser_subs =
+  let new_output_file = output_file ^ ".new" in
+
+  let strs = concat_str_items [ types; parsers ] in
+  Printers.OCaml.print_implem ~output_file:new_output_file strs;
+
+  (* Substitute the parser bodies in the output file. *)
+  let ichan = open_in new_output_file in
+  let ochan = open_out output_file in
+
+  output_string ochan "\
+(* WARNING: This file and the corresponding mli (interface) are
+ * automatically generated by the extract/codegen/ program.
+ *
+ * Any edits you make to this file will be lost.
+ *
+ * To update this file from the latest kernel database, it is recommended
+ * that you do 'make update-kernel-structs'.
+ *)\n\n";
+
+  let rec loop () =
+    let line = input_line ichan in
+    let line =
+      if Pcre.pmatch ~rex:re_subst line then (
+       let subs = Pcre.exec ~rex:re_subst line in
+       let start = Pcre.get_substring subs 1 in
+       let template = Pcre.get_substring subs 2 in
+       let rest = Pcre.get_substring subs 3 in
+       let sub =
+         try Hashtbl.find parser_subs template
+         with Not_found -> assert false in
+       start ^ sub ^ rest
+      ) else line in
+    output_string ochan line; output_char ochan '\n';
+    loop ()
+  in
+  (try loop () with End_of_file -> ());
+
+  close_out ochan;
+  close_in ichan;
+
+  Unix.unlink new_output_file
index efe282f..36140cd 100644 (file)
@@ -39,12 +39,30 @@ val generate_types :
        - content field structures
     *)
 
+(** {2 Generate parsers} *)
+
+val generate_parsers : (string * Struct_classify.parser_ list) list ->
+  Camlp4.PreCast.Syntax.Ast.str_item * Camlp4.PreCast.Syntax.Ast.sig_item
+  * (string, string) Hashtbl.t
+    (** [generate_parsers] generates the parser functions.
+
+       We cannot generate the complete code here because we
+       don't want camlp4 parsing this file to substitute bitmatch
+       code yet.  So we only generate labels, which get substituted
+       by the contents of the returned hash table in {!output_implem}.
+    *)
+
 (** {2 Output final files} *)
 
 val output_interf : output_file:string ->
-  Camlp4.PreCast.Syntax.Ast.sig_item -> unit
+  Camlp4.PreCast.Syntax.Ast.sig_item ->
+  Camlp4.PreCast.Syntax.Ast.sig_item ->
+  unit
   (** Output the interface file. *)
 
 val output_implem : output_file:string ->
-  Camlp4.PreCast.Syntax.Ast.str_item -> unit
+  Camlp4.PreCast.Syntax.Ast.str_item ->
+  Camlp4.PreCast.Syntax.Ast.str_item ->
+  (string, string) Hashtbl.t ->
+  unit
   (** Output the implementation file. *)
index 9d9e89c..31bb000 100644 (file)
@@ -34,7 +34,7 @@ type struct_t = {
 }
 and field_metadata_t =
   | VoidPointerIsReally of string
-  | ListHeadIsReally of string
+  | ListHeadIsReally of (string * string) option
 
 (*----------------------------------------------------------------------
  * This controls what structures & fields we will parse out.
@@ -46,10 +46,10 @@ let good_structs = [
                    "state"; "prio"; "static_prio"; "normal_prio";
                    "comm"; "pid" ];
     field_metadata = [
-      "tasks'next", ListHeadIsReally "task_struct";
-      "tasks'prev", ListHeadIsReally "task_struct";
-      "run_list'next", ListHeadIsReally "task_struct";
-      "run_list'prev", ListHeadIsReally "task_struct";
+      "tasks'next", ListHeadIsReally None;
+      "tasks'prev", ListHeadIsReally None;
+      "run_list'next", ListHeadIsReally None;
+      "run_list'prev", ListHeadIsReally None;
     ];
   };
   "net_device", {
@@ -58,8 +58,8 @@ let good_structs = [
                    "name"; "flags"; "operstate"; "mtu"; "perm_addr";
                    "addr_len" ];
     field_metadata = [
-      "dev_list'next", ListHeadIsReally "net_device";
-      "dev_list'prev", ListHeadIsReally "net_device";
+      "dev_list'next", ListHeadIsReally None;
+      "dev_list'prev", ListHeadIsReally None;
       "ip_ptr", VoidPointerIsReally "in_device";
       "ip6_ptr", VoidPointerIsReally "inet6_dev";
     ];
@@ -67,8 +67,8 @@ let good_structs = [
   "net", {
     good_fields = [ "dev_base_head'next"; "dev_base_head'prev" ];
     field_metadata = [
-      "dev_base_head'next", ListHeadIsReally "net_device";
-      "dev_base_head'prev", ListHeadIsReally "net_device";
+      "dev_base_head'next", ListHeadIsReally (Some ("net_device", "dev_list"));
+      "dev_base_head'prev", ListHeadIsReally (Some ("net_device", "dev_list"));
     ];
   };
   "in_device", {
@@ -90,7 +90,7 @@ let good_structs = [
   };
 ]
 
-let debug = true
+let debug = false
 
 open Camlp4.PreCast
 open Syntax
@@ -342,13 +342,21 @@ Options:
       ) structures
     ) in
 
+  let implem_parsers, interf_parsers, subst_parsers =
+    CG.generate_parsers (
+      List.map (
+       fun (struct_name, (_, _, _, _, _, _, palist, _)) ->
+         (struct_name, palist)
+      ) structures
+    ) in
+
   (* Output the generated code. *)
   let output_file = outputdir // "kernel.mli" in
   printf "Writing kernel data interface to %s ...\n%!" output_file;
-  CG.output_interf ~output_file interf_types;
+  CG.output_interf ~output_file interf_types interf_parsers;
 
   let output_file = outputdir // "kernel.ml" in
   printf "Writing kernel data parsers to %s ...\n%!" output_file;
-  CG.output_implem ~output_file implem_types;
+  CG.output_implem ~output_file implem_types implem_parsers subst_parsers;
 
-  (* XXX Here we need to substitute the parser code. *)
+  printf "Finished.\n"
index d593dca..f8b5bd1 100644 (file)
@@ -49,7 +49,7 @@ and f_type =
   | FStructPointer of string
   | FVoidPointer
   | FAnonListHeadPointer
-  | FListHeadPointer of string
+  | FListHeadPointer of (string * string) option
   | FInteger
   | FString of int
 
@@ -71,8 +71,10 @@ and string_of_f_type = function
   | FStructPointer struct_name -> sprintf "struct %s *" struct_name
   | FVoidPointer -> "void *"
   | FAnonListHeadPointer -> "struct list_head *"
-  | FListHeadPointer struct_name ->
-      sprintf "struct /* %s */ list_head *" struct_name
+  | FListHeadPointer None ->
+      sprintf "struct /* self */ list_head *"
+  | FListHeadPointer (Some (struct_name, field_name)) ->
+      sprintf "struct /* to %s.%s */ list_head *" struct_name field_name
   | FInteger -> "int"
   | FString width -> sprintf "char[%d]" width
 
index 60e5eb2..9c335a7 100644 (file)
@@ -63,8 +63,10 @@ and f_type =
   | FVoidPointer                       (** A [void*] pointer. *)
   | FAnonListHeadPointer               (** A pointer to an unknown
                                            [list_head]. *)
-  | FListHeadPointer of string         (** A pointer to a [list_head] in a
-                                           named struct. *)
+  | FListHeadPointer of (string * string) option
+      (** A pointer to a [list_head].  If the value is not [None] then
+         this relates to another named struct/field, else it relates
+         to this struct/field. *)
   | FInteger                           (** An integer. *)
   | FString of int                     (** A char array of given width. *)
   (** Type of a kernel field. *)
index d10d1c4..d959a1f 100644 (file)
@@ -27,7 +27,9 @@ module PP = Pahole_parser
 type f_class = ShapeField | ContentField
 
 let classify_field names = function
-  | (PP.FStructPointer struct_name | PP.FListHeadPointer struct_name)
+  | PP.FListHeadPointer None -> ShapeField
+  | (PP.FStructPointer struct_name
+    | PP.FListHeadPointer (Some (struct_name, _)))
       when List.mem struct_name names -> ShapeField
     (* .. anything else is a content field: *)
   | PP.FStructPointer _
@@ -53,7 +55,7 @@ and parser_ = {
   pa_i : int;
   pa_name : string;
   pa_endian : Bitstring.endian;
-  pa_fields : Pahole_parser.field list;
+  pa_structure : Pahole_parser.structure;
   pa_shape_field_struct : shape_field_struct;
   pa_content_field_struct : content_field_struct;
 }
@@ -158,11 +160,13 @@ let minimize_parsers struct_name kernels sfhash cfhash =
   let h = Hashtbl.create 13 in
   let rh = Hashtbl.create 13 in
 
+  (* Do not change - see Code_generation.re_subst. *)
   let name_of i = sprintf "%s_parser_%d" struct_name i in
 
   List.iter (
     fun ({ PP.kernel_version = version; arch = arch },
-        { PP.struct_fields = fields; struct_name = name_check }) ->
+        ({ PP.struct_fields = fields; struct_name = name_check }
+           as structure)) ->
       assert (struct_name = name_check);
       let endian = endian_of_architecture arch in
       let key = endian, fields in
@@ -176,8 +180,9 @@ let minimize_parsers struct_name kernels sfhash cfhash =
          let cf =
            try Hashtbl.find cfhash version
            with Not_found -> assert false in
-         let pa = { pa_i = i; pa_name = name_of i; pa_fields = fields;
+         let pa = { pa_i = i; pa_name = name_of i;
                     pa_endian = endian;
+                    pa_structure = structure;
                     pa_shape_field_struct = sf;
                     pa_content_field_struct = cf } in
          Hashtbl.add h key pa;
index 96554bf..23508d7 100644 (file)
@@ -155,7 +155,7 @@ type parser_ (* parser is a reserved word *) = {
   pa_name : string;                    (** Parser function name in output. *)
   (* The input to the parser: *)
   pa_endian : Bitstring.endian;                (** Default field endianness. *)
-  pa_fields : Pahole_parser.field list; (** All fields. *)
+  pa_structure : Pahole_parser.structure; (** Original structure. *)
   (* The output of the parser: *)
   pa_shape_field_struct : shape_field_struct;
   pa_content_field_struct : content_field_struct;
index b320970..301269c 100644 (file)
@@ -7,8 +7,8 @@ virt_mem_net_devices.cmi: virt_mem_types.cmi
 virt_mem_tasks.cmi: virt_mem_types.cmi 
 virt_mem_types.cmi: virt_mem_utils.cmo virt_mem_mmap.cmi 
 virt_mem_utsname.cmi: virt_mem_types.cmi 
-kernel.cmo: virt_mem_mmap.cmi kernel.cmi 
-kernel.cmx: virt_mem_mmap.cmx kernel.cmi 
+kernel.cmo: virt_mem_types.cmi virt_mem_mmap.cmi kernel.cmi 
+kernel.cmx: virt_mem_types.cmx virt_mem_mmap.cmx kernel.cmi 
 test_mmap.cmo: virt_mem_mmap.cmi 
 test_mmap.cmx: virt_mem_mmap.cmx 
 virt_mem_capture.cmo: virt_mem_types.cmi virt_mem_gettext.cmo virt_mem.cmi 
index a75fdad..1a2e91b 100644 (file)
+(* WARNING: This file and the corresponding mli (interface) are
+ * automatically generated by the extract/codegen/ program.
+ *
+ * Any edits you make to this file will be lost.
+ *
+ * To update this file from the latest kernel database, it is recommended
+ * that you do 'make update-kernel-structs'.
+ *)
+
 type ('a, 'b) task_struct =
   { task_struct_shape : 'a; task_struct_content : 'b
   };;
 type task_struct_shape_fields_2 =
-  { tasks'next : Virt_mem_mmap.addr; tasks'prev : Virt_mem_mmap.addr
+  { task_struct_shape_fields_2_tasks'next : Virt_mem_mmap.addr;
+    task_struct_shape_fields_2_tasks'prev : Virt_mem_mmap.addr
   };;
 type task_struct_shape_fields_1 =
-  { run_list'next : Virt_mem_mmap.addr; run_list'prev : Virt_mem_mmap.addr;
-    tasks'next : Virt_mem_mmap.addr; tasks'prev : Virt_mem_mmap.addr
+  { task_struct_shape_fields_1_run_list'next : Virt_mem_mmap.addr;
+    task_struct_shape_fields_1_run_list'prev : Virt_mem_mmap.addr;
+    task_struct_shape_fields_1_tasks'next : Virt_mem_mmap.addr;
+    task_struct_shape_fields_1_tasks'prev : Virt_mem_mmap.addr
   };;
 type task_struct_content_fields_3 =
-  { comm : string; normal_prio : int64; pid : int64; prio : int64;
-    state : int64; static_prio : int64
+  { task_struct_content_fields_3_comm : string;
+    task_struct_content_fields_3_normal_prio : int64;
+    task_struct_content_fields_3_pid : int64;
+    task_struct_content_fields_3_prio : int64;
+    task_struct_content_fields_3_state : int64;
+    task_struct_content_fields_3_static_prio : int64
   };;
 type ('a, 'b) net_device = { net_device_shape : 'a; net_device_content : 'b };;
 type net_device_shape_fields_12 =
-  { ip6_ptr : Virt_mem_mmap.addr; ip_ptr : Virt_mem_mmap.addr;
-    next : Virt_mem_mmap.addr
+  { net_device_shape_fields_12_ip6_ptr : Virt_mem_mmap.addr;
+    net_device_shape_fields_12_ip_ptr : Virt_mem_mmap.addr;
+    net_device_shape_fields_12_next : Virt_mem_mmap.addr
   };;
 type net_device_shape_fields_13 =
-  { dev_list'next : Virt_mem_mmap.addr; dev_list'prev : Virt_mem_mmap.addr;
-    ip6_ptr : Virt_mem_mmap.addr; ip_ptr : Virt_mem_mmap.addr
+  { net_device_shape_fields_13_dev_list'next : Virt_mem_mmap.addr;
+    net_device_shape_fields_13_dev_list'prev : Virt_mem_mmap.addr;
+    net_device_shape_fields_13_ip6_ptr : Virt_mem_mmap.addr;
+    net_device_shape_fields_13_ip_ptr : Virt_mem_mmap.addr
   };;
 type net_device_content_fields_14 =
-  { addr_len : int64; flags : int64; mtu : int64; name : string;
-    operstate : int64; perm_addr : string
+  { net_device_content_fields_14_addr_len : int64;
+    net_device_content_fields_14_flags : int64;
+    net_device_content_fields_14_mtu : int64;
+    net_device_content_fields_14_name : string;
+    net_device_content_fields_14_operstate : int64;
+    net_device_content_fields_14_perm_addr : string
   };;
 type ('a, 'b) net = { net_shape : 'a; net_content : 'b };;
 type net_shape_fields_22 =
-  { dev_base_head'next : Virt_mem_mmap.addr;
-    dev_base_head'prev : Virt_mem_mmap.addr
+  { net_shape_fields_22_dev_base_head'next : Virt_mem_mmap.addr;
+    net_shape_fields_22_dev_base_head'prev : Virt_mem_mmap.addr
   };;
 type net_content_fields_23 = unit;;
 type ('a, 'b) in_device = { in_device_shape : 'a; in_device_content : 'b };;
-type in_device_shape_fields_28 = { ifa_list : Virt_mem_mmap.addr };;
+type in_device_shape_fields_28 =
+  { in_device_shape_fields_28_ifa_list : Virt_mem_mmap.addr
+  };;
 type in_device_content_fields_29 = unit;;
 type ('a, 'b) inet6_dev = { inet6_dev_shape : 'a; inet6_dev_content : 'b };;
-type inet6_dev_shape_fields_34 = { addr_list : Virt_mem_mmap.addr };;
+type inet6_dev_shape_fields_34 =
+  { inet6_dev_shape_fields_34_addr_list : Virt_mem_mmap.addr
+  };;
 type inet6_dev_content_fields_35 = unit;;
 type ('a, 'b) in_ifaddr = { in_ifaddr_shape : 'a; in_ifaddr_content : 'b };;
-type in_ifaddr_shape_fields_40 = { ifa_next : Virt_mem_mmap.addr };;
+type in_ifaddr_shape_fields_40 =
+  { in_ifaddr_shape_fields_40_ifa_next : Virt_mem_mmap.addr
+  };;
 type in_ifaddr_content_fields_41 =
-  { ifa_address : int64; ifa_broadcast : int64; ifa_local : int64;
-    ifa_mask : int64
+  { in_ifaddr_content_fields_41_ifa_address : int64;
+    in_ifaddr_content_fields_41_ifa_broadcast : int64;
+    in_ifaddr_content_fields_41_ifa_local : int64;
+    in_ifaddr_content_fields_41_ifa_mask : int64
   };;
 type ('a, 'b) inet6_ifaddr =
   { inet6_ifaddr_shape : 'a; inet6_ifaddr_content : 'b
   };;
-type inet6_ifaddr_shape_fields_46 = { lst_next : Virt_mem_mmap.addr };;
-type inet6_ifaddr_content_fields_47 = { prefix_len : int64 };;
+type inet6_ifaddr_shape_fields_46 =
+  { inet6_ifaddr_shape_fields_46_lst_next : Virt_mem_mmap.addr
+  };;
+type inet6_ifaddr_content_fields_47 =
+  { inet6_ifaddr_content_fields_47_prefix_len : int64
+  };;
+let match_err = "failed to match kernel structure";;
+let zero = 0;;
+let task_struct_parser_4 bits = 
+  bitmatch bits with
+  | { state : zero+32 : offset(0), littleendian;
+      prio : zero+32 : offset(192), littleendian;
+      static_prio : zero+32 : offset(224), littleendian;
+      normal_prio : zero+32 : offset(256), littleendian;
+      run_list'next : zero+32 : offset(288), littleendian;
+      run_list'prev : zero+32 : offset(320), littleendian;
+      tasks'next : zero+32 : offset(992), littleendian;
+      tasks'prev : zero+32 : offset(1024), littleendian;
+      pid : zero+32 : offset(1344), littleendian;
+      comm : 128 : offset(3232), string } ->
+      let shape =
+      { task_struct_shape_fields_1_run_list'next = Int64.sub run_list'next 36L;
+        task_struct_shape_fields_1_run_list'prev = Int64.sub run_list'prev 40L;
+        task_struct_shape_fields_1_tasks'next = Int64.sub tasks'next 124L;
+        task_struct_shape_fields_1_tasks'prev = Int64.sub tasks'prev 128L } in
+      let content =
+      { task_struct_shape_fields_1_run_list'next = run_list'next;
+        task_struct_shape_fields_1_run_list'prev = run_list'prev;
+        task_struct_shape_fields_1_tasks'next = tasks'next;
+        task_struct_shape_fields_1_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_4", match_err));;
+let task_struct_parser_5 bits = 
+  bitmatch bits with
+  | { state : zero+64 : offset(0), bigendian;
+      prio : zero+32 : offset(320), bigendian;
+      static_prio : zero+32 : offset(352), bigendian;
+      normal_prio : zero+32 : offset(384), bigendian;
+      run_list'next : zero+64 : offset(448), bigendian;
+      run_list'prev : zero+64 : offset(512), bigendian;
+      tasks'next : zero+64 : offset(1600), bigendian;
+      tasks'prev : zero+64 : offset(1664), bigendian;
+      pid : zero+32 : offset(2208), bigendian;
+      comm : 128 : offset(5440), string } ->
+      let shape =
+      { task_struct_shape_fields_1_run_list'next = Int64.sub run_list'next 36L;
+        task_struct_shape_fields_1_run_list'prev = Int64.sub run_list'prev 40L;
+        task_struct_shape_fields_1_tasks'next = Int64.sub tasks'next 124L;
+        task_struct_shape_fields_1_tasks'prev = Int64.sub tasks'prev 128L } in
+      let content =
+      { task_struct_shape_fields_1_run_list'next = run_list'next;
+        task_struct_shape_fields_1_run_list'prev = run_list'prev;
+        task_struct_shape_fields_1_tasks'next = tasks'next;
+        task_struct_shape_fields_1_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_5", match_err));;
+let task_struct_parser_6 bits = 
+  bitmatch bits with
+  | { state : zero+64 : offset(0), littleendian;
+      prio : zero+32 : offset(320), littleendian;
+      static_prio : zero+32 : offset(352), littleendian;
+      normal_prio : zero+32 : offset(384), littleendian;
+      run_list'next : zero+64 : offset(448), littleendian;
+      run_list'prev : zero+64 : offset(512), littleendian;
+      tasks'next : zero+64 : offset(1536), littleendian;
+      tasks'prev : zero+64 : offset(1600), littleendian;
+      pid : zero+32 : offset(2144), littleendian;
+      comm : 128 : offset(5440), string } ->
+      let shape =
+      { task_struct_shape_fields_1_run_list'next = Int64.sub run_list'next 36L;
+        task_struct_shape_fields_1_run_list'prev = Int64.sub run_list'prev 40L;
+        task_struct_shape_fields_1_tasks'next = Int64.sub tasks'next 124L;
+        task_struct_shape_fields_1_tasks'prev = Int64.sub tasks'prev 128L } in
+      let content =
+      { task_struct_shape_fields_1_run_list'next = run_list'next;
+        task_struct_shape_fields_1_run_list'prev = run_list'prev;
+        task_struct_shape_fields_1_tasks'next = tasks'next;
+        task_struct_shape_fields_1_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_6", match_err));;
+let task_struct_parser_7 bits = 
+  bitmatch bits with
+  | { state : zero+32 : offset(0), bigendian;
+      prio : zero+32 : offset(160), bigendian;
+      static_prio : zero+32 : offset(192), bigendian;
+      normal_prio : zero+32 : offset(224), bigendian;
+      run_list'next : zero+32 : offset(256), bigendian;
+      run_list'prev : zero+32 : offset(288), bigendian;
+      tasks'next : zero+32 : offset(2176), bigendian;
+      tasks'prev : zero+32 : offset(2208), bigendian;
+      pid : zero+32 : offset(2528), bigendian;
+      comm : 128 : offset(4416), string } ->
+      let shape =
+      { task_struct_shape_fields_1_run_list'next = Int64.sub run_list'next 36L;
+        task_struct_shape_fields_1_run_list'prev = Int64.sub run_list'prev 40L;
+        task_struct_shape_fields_1_tasks'next = Int64.sub tasks'next 124L;
+        task_struct_shape_fields_1_tasks'prev = Int64.sub tasks'prev 128L } in
+      let content =
+      { task_struct_shape_fields_1_run_list'next = run_list'next;
+        task_struct_shape_fields_1_run_list'prev = run_list'prev;
+        task_struct_shape_fields_1_tasks'next = tasks'next;
+        task_struct_shape_fields_1_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_7", match_err));;
+let task_struct_parser_8 bits = 
+  bitmatch bits with
+  | { state : zero+64 : offset(0), bigendian;
+      prio : zero+32 : offset(224), bigendian;
+      static_prio : zero+32 : offset(256), bigendian;
+      normal_prio : zero+32 : offset(288), bigendian;
+      run_list'next : zero+64 : offset(320), bigendian;
+      run_list'prev : zero+64 : offset(384), bigendian;
+      tasks'next : zero+64 : offset(3648), bigendian;
+      tasks'prev : zero+64 : offset(3712), bigendian;
+      pid : zero+32 : offset(4160), bigendian;
+      comm : 128 : offset(7752), string } ->
+      let shape =
+      { task_struct_shape_fields_1_run_list'next = Int64.sub run_list'next 36L;
+        task_struct_shape_fields_1_run_list'prev = Int64.sub run_list'prev 40L;
+        task_struct_shape_fields_1_tasks'next = Int64.sub tasks'next 124L;
+        task_struct_shape_fields_1_tasks'prev = Int64.sub tasks'prev 128L } in
+      let content =
+      { task_struct_shape_fields_1_run_list'next = run_list'next;
+        task_struct_shape_fields_1_run_list'prev = run_list'prev;
+        task_struct_shape_fields_1_tasks'next = tasks'next;
+        task_struct_shape_fields_1_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_8", match_err));;
+let task_struct_parser_9 bits = 
+  bitmatch bits with
+  | { state : zero+64 : offset(0), littleendian;
+      prio : zero+32 : offset(224), littleendian;
+      static_prio : zero+32 : offset(256), littleendian;
+      normal_prio : zero+32 : offset(288), littleendian;
+      tasks'next : zero+64 : offset(3840), littleendian;
+      tasks'prev : zero+64 : offset(3904), littleendian;
+      pid : zero+32 : offset(4352), littleendian;
+      comm : 128 : offset(8392), string } ->
+      let shape =
+      { task_struct_shape_fields_2_tasks'next = Int64.sub tasks'next 480L;
+        task_struct_shape_fields_2_tasks'prev = Int64.sub tasks'prev 488L } in
+      let content =
+      { task_struct_shape_fields_2_tasks'next = tasks'next;
+        task_struct_shape_fields_2_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_9", match_err));;
+let task_struct_parser_10 bits = 
+  bitmatch bits with
+  | { state : zero+64 : offset(0), bigendian;
+      prio : zero+32 : offset(256), bigendian;
+      static_prio : zero+32 : offset(288), bigendian;
+      normal_prio : zero+32 : offset(320), bigendian;
+      tasks'next : zero+64 : offset(4096), bigendian;
+      tasks'prev : zero+64 : offset(4160), bigendian;
+      pid : zero+32 : offset(4608), bigendian;
+      comm : 128 : offset(8712), string } ->
+      let shape =
+      { task_struct_shape_fields_2_tasks'next = Int64.sub tasks'next 480L;
+        task_struct_shape_fields_2_tasks'prev = Int64.sub tasks'prev 488L } in
+      let content =
+      { task_struct_shape_fields_2_tasks'next = tasks'next;
+        task_struct_shape_fields_2_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_10", match_err));;
+let task_struct_parser_11 bits = 
+  bitmatch bits with
+  | { state : zero+32 : offset(0), bigendian;
+      prio : zero+32 : offset(192), bigendian;
+      static_prio : zero+32 : offset(224), bigendian;
+      normal_prio : zero+32 : offset(256), bigendian;
+      tasks'next : zero+32 : offset(3712), bigendian;
+      tasks'prev : zero+32 : offset(3744), bigendian;
+      pid : zero+32 : offset(4064), bigendian;
+      comm : 128 : offset(6464), string } ->
+      let shape =
+      { task_struct_shape_fields_2_tasks'next = Int64.sub tasks'next 480L;
+        task_struct_shape_fields_2_tasks'prev = Int64.sub tasks'prev 488L } in
+      let content =
+      { task_struct_shape_fields_2_tasks'next = tasks'next;
+        task_struct_shape_fields_2_tasks'prev = tasks'prev } in
+      { task_struct_shape = shape; task_struct_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("task_struct", "task_struct_parser_11", match_err));;
+let net_device_parser_15 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      next : zero+32 : offset(384), littleendian;
+      flags : zero+32 : offset(704), littleendian;
+      operstate : zero+8 : offset(784), littleendian;
+      mtu : zero+32 : offset(800), littleendian;
+      perm_addr : 256 : offset(896), string;
+      addr_len : zero+8 : offset(1152), littleendian;
+      ip_ptr : zero+32 : offset(1344), littleendian;
+      ip6_ptr : zero+32 : offset(1408), littleendian } ->
+      let shape =
+      { net_device_shape_fields_12_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_12_ip_ptr = ip_ptr;
+        net_device_shape_fields_12_next = next } in
+      let content =
+      { net_device_shape_fields_12_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_12_ip_ptr = ip_ptr;
+        net_device_shape_fields_12_next = next } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_15", match_err));;
+let net_device_parser_16 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      next : zero+64 : offset(576), bigendian;
+      flags : zero+32 : offset(1152), bigendian;
+      operstate : zero+8 : offset(1232), bigendian;
+      mtu : zero+32 : offset(1248), bigendian;
+      perm_addr : 256 : offset(1408), string;
+      addr_len : zero+8 : offset(1664), bigendian;
+      ip_ptr : zero+64 : offset(1984), bigendian;
+      ip6_ptr : zero+64 : offset(2112), bigendian } ->
+      let shape =
+      { net_device_shape_fields_12_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_12_ip_ptr = ip_ptr;
+        net_device_shape_fields_12_next = next } in
+      let content =
+      { net_device_shape_fields_12_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_12_ip_ptr = ip_ptr;
+        net_device_shape_fields_12_next = next } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_16", match_err));;
+let net_device_parser_17 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      next : zero+64 : offset(576), littleendian;
+      flags : zero+32 : offset(1152), littleendian;
+      operstate : zero+8 : offset(1232), littleendian;
+      mtu : zero+32 : offset(1248), littleendian;
+      perm_addr : 256 : offset(1408), string;
+      addr_len : zero+8 : offset(1664), littleendian;
+      ip_ptr : zero+64 : offset(1984), littleendian;
+      ip6_ptr : zero+64 : offset(2112), littleendian } ->
+      let shape =
+      { net_device_shape_fields_12_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_12_ip_ptr = ip_ptr;
+        net_device_shape_fields_12_next = next } in
+      let content =
+      { net_device_shape_fields_12_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_12_ip_ptr = ip_ptr;
+        net_device_shape_fields_12_next = next } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_17", match_err));;
+let net_device_parser_18 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      dev_list'next : zero+32 : offset(384), bigendian;
+      dev_list'prev : zero+32 : offset(416), bigendian;
+      flags : zero+32 : offset(1472), bigendian;
+      operstate : zero+8 : offset(1552), bigendian;
+      mtu : zero+32 : offset(1568), bigendian;
+      perm_addr : 256 : offset(1664), string;
+      addr_len : zero+8 : offset(1920), bigendian;
+      ip_ptr : zero+32 : offset(2112), bigendian;
+      ip6_ptr : zero+32 : offset(2176), bigendian } ->
+      let shape =
+      { net_device_shape_fields_13_dev_list'next = Int64.sub dev_list'next 48L;
+        net_device_shape_fields_13_dev_list'prev = Int64.sub dev_list'prev 52L;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      let content =
+      { net_device_shape_fields_13_dev_list'next = dev_list'next;
+        net_device_shape_fields_13_dev_list'prev = dev_list'prev;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_18", match_err));;
+let net_device_parser_19 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      dev_list'next : zero+64 : offset(576), bigendian;
+      dev_list'prev : zero+64 : offset(640), bigendian;
+      flags : zero+32 : offset(2880), bigendian;
+      operstate : zero+8 : offset(2960), bigendian;
+      mtu : zero+32 : offset(2976), bigendian;
+      perm_addr : 256 : offset(3136), string;
+      addr_len : zero+8 : offset(3392), bigendian;
+      ip_ptr : zero+64 : offset(3840), bigendian;
+      ip6_ptr : zero+64 : offset(3968), bigendian } ->
+      let shape =
+      { net_device_shape_fields_13_dev_list'next = Int64.sub dev_list'next 48L;
+        net_device_shape_fields_13_dev_list'prev = Int64.sub dev_list'prev 52L;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      let content =
+      { net_device_shape_fields_13_dev_list'next = dev_list'next;
+        net_device_shape_fields_13_dev_list'prev = dev_list'prev;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_19", match_err));;
+let net_device_parser_20 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      dev_list'next : zero+64 : offset(576), littleendian;
+      dev_list'prev : zero+64 : offset(640), littleendian;
+      flags : zero+32 : offset(2880), littleendian;
+      operstate : zero+8 : offset(2960), littleendian;
+      mtu : zero+32 : offset(2976), littleendian;
+      perm_addr : 256 : offset(3136), string;
+      addr_len : zero+8 : offset(3392), littleendian;
+      ip_ptr : zero+64 : offset(3840), littleendian;
+      ip6_ptr : zero+64 : offset(3968), littleendian } ->
+      let shape =
+      { net_device_shape_fields_13_dev_list'next = Int64.sub dev_list'next 48L;
+        net_device_shape_fields_13_dev_list'prev = Int64.sub dev_list'prev 52L;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      let content =
+      { net_device_shape_fields_13_dev_list'next = dev_list'next;
+        net_device_shape_fields_13_dev_list'prev = dev_list'prev;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_20", match_err));;
+let net_device_parser_21 bits = 
+  bitmatch bits with
+  | { name : 128 : offset(0), string;
+      dev_list'next : zero+32 : offset(384), bigendian;
+      dev_list'prev : zero+32 : offset(416), bigendian;
+      flags : zero+32 : offset(1536), bigendian;
+      operstate : zero+8 : offset(1616), bigendian;
+      mtu : zero+32 : offset(1632), bigendian;
+      perm_addr : 256 : offset(1760), string;
+      addr_len : zero+8 : offset(2016), bigendian;
+      ip_ptr : zero+32 : offset(2432), bigendian;
+      ip6_ptr : zero+32 : offset(2496), bigendian } ->
+      let shape =
+      { net_device_shape_fields_13_dev_list'next = Int64.sub dev_list'next 48L;
+        net_device_shape_fields_13_dev_list'prev = Int64.sub dev_list'prev 52L;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      let content =
+      { net_device_shape_fields_13_dev_list'next = dev_list'next;
+        net_device_shape_fields_13_dev_list'prev = dev_list'prev;
+        net_device_shape_fields_13_ip6_ptr = ip6_ptr;
+        net_device_shape_fields_13_ip_ptr = ip_ptr } in
+      { net_device_shape = shape; net_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net_device", "net_device_parser_21", match_err));;
+let net_parser_24 bits = 
+  bitmatch bits with
+  | { dev_base_head'next : zero+64 : offset(704), bigendian;
+      dev_base_head'prev : zero+64 : offset(768), bigendian } ->
+      let shape =
+      { net_shape_fields_22_dev_base_head'next = Int64.sub dev_base_head'next 666L;
+        net_shape_fields_22_dev_base_head'prev = Int64.sub dev_base_head'prev 666L } in
+      let content =
+      { net_shape_fields_22_dev_base_head'next = dev_base_head'next;
+        net_shape_fields_22_dev_base_head'prev = dev_base_head'prev } in
+      { net_shape = shape; net_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net", "net_parser_24", match_err));;
+let net_parser_25 bits = 
+  bitmatch bits with
+  | { dev_base_head'next : zero+64 : offset(768), littleendian;
+      dev_base_head'prev : zero+64 : offset(832), littleendian } ->
+      let shape =
+      { net_shape_fields_22_dev_base_head'next = Int64.sub dev_base_head'next 666L;
+        net_shape_fields_22_dev_base_head'prev = Int64.sub dev_base_head'prev 666L } in
+      let content =
+      { net_shape_fields_22_dev_base_head'next = dev_base_head'next;
+        net_shape_fields_22_dev_base_head'prev = dev_base_head'prev } in
+      { net_shape = shape; net_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net", "net_parser_25", match_err));;
+let net_parser_26 bits = 
+  bitmatch bits with
+  | { dev_base_head'next : zero+64 : offset(768), bigendian;
+      dev_base_head'prev : zero+64 : offset(832), bigendian } ->
+      let shape =
+      { net_shape_fields_22_dev_base_head'next = Int64.sub dev_base_head'next 666L;
+        net_shape_fields_22_dev_base_head'prev = Int64.sub dev_base_head'prev 666L } in
+      let content =
+      { net_shape_fields_22_dev_base_head'next = dev_base_head'next;
+        net_shape_fields_22_dev_base_head'prev = dev_base_head'prev } in
+      { net_shape = shape; net_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net", "net_parser_26", match_err));;
+let net_parser_27 bits = 
+  bitmatch bits with
+  | { dev_base_head'next : zero+32 : offset(448), bigendian;
+      dev_base_head'prev : zero+32 : offset(480), bigendian } ->
+      let shape =
+      { net_shape_fields_22_dev_base_head'next = Int64.sub dev_base_head'next 666L;
+        net_shape_fields_22_dev_base_head'prev = Int64.sub dev_base_head'prev 666L } in
+      let content =
+      { net_shape_fields_22_dev_base_head'next = dev_base_head'next;
+        net_shape_fields_22_dev_base_head'prev = dev_base_head'prev } in
+      { net_shape = shape; net_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("net", "net_parser_27", match_err));;
+let in_device_parser_30 bits = 
+  bitmatch bits with
+  | { ifa_list : zero+32 : offset(96), littleendian } ->
+      let shape =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      let content =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      { in_device_shape = shape; in_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_device", "in_device_parser_30", match_err));;
+let in_device_parser_33 bits = 
+  bitmatch bits with
+  | { ifa_list : zero+32 : offset(96), bigendian } ->
+      let shape =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      let content =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      { in_device_shape = shape; in_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_device", "in_device_parser_33", match_err));;
+let in_device_parser_32 bits = 
+  bitmatch bits with
+  | { ifa_list : zero+64 : offset(128), littleendian } ->
+      let shape =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      let content =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      { in_device_shape = shape; in_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_device", "in_device_parser_32", match_err));;
+let in_device_parser_31 bits = 
+  bitmatch bits with
+  | { ifa_list : zero+64 : offset(128), bigendian } ->
+      let shape =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      let content =
+      { in_device_shape_fields_28_ifa_list = ifa_list } in
+      { in_device_shape = shape; in_device_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_device", "in_device_parser_31", match_err));;
+let inet6_dev_parser_36 bits = 
+  bitmatch bits with
+  | { addr_list : zero+32 : offset(32), littleendian } ->
+      let shape =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      let content =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      { inet6_dev_shape = shape; inet6_dev_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_dev", "inet6_dev_parser_36", match_err));;
+let inet6_dev_parser_39 bits = 
+  bitmatch bits with
+  | { addr_list : zero+32 : offset(32), bigendian } ->
+      let shape =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      let content =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      { inet6_dev_shape = shape; inet6_dev_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_dev", "inet6_dev_parser_39", match_err));;
+let inet6_dev_parser_38 bits = 
+  bitmatch bits with
+  | { addr_list : zero+64 : offset(64), littleendian } ->
+      let shape =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      let content =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      { inet6_dev_shape = shape; inet6_dev_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_dev", "inet6_dev_parser_38", match_err));;
+let inet6_dev_parser_37 bits = 
+  bitmatch bits with
+  | { addr_list : zero+64 : offset(64), bigendian } ->
+      let shape =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      let content =
+      { inet6_dev_shape_fields_34_addr_list = addr_list } in
+      { inet6_dev_shape = shape; inet6_dev_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_dev", "inet6_dev_parser_37", match_err));;
+let in_ifaddr_parser_42 bits = 
+  bitmatch bits with
+  | { ifa_next : zero+32 : offset(0), littleendian;
+      ifa_local : zero+32 : offset(128), littleendian;
+      ifa_address : zero+32 : offset(160), littleendian;
+      ifa_mask : zero+32 : offset(192), littleendian;
+      ifa_broadcast : zero+32 : offset(224), littleendian } ->
+      let shape =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      let content =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      { in_ifaddr_shape = shape; in_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_ifaddr", "in_ifaddr_parser_42", match_err));;
+let in_ifaddr_parser_45 bits = 
+  bitmatch bits with
+  | { ifa_next : zero+32 : offset(0), bigendian;
+      ifa_local : zero+32 : offset(128), bigendian;
+      ifa_address : zero+32 : offset(160), bigendian;
+      ifa_mask : zero+32 : offset(192), bigendian;
+      ifa_broadcast : zero+32 : offset(224), bigendian } ->
+      let shape =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      let content =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      { in_ifaddr_shape = shape; in_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_ifaddr", "in_ifaddr_parser_45", match_err));;
+let in_ifaddr_parser_43 bits = 
+  bitmatch bits with
+  | { ifa_next : zero+64 : offset(0), bigendian;
+      ifa_local : zero+32 : offset(256), bigendian;
+      ifa_address : zero+32 : offset(288), bigendian;
+      ifa_mask : zero+32 : offset(320), bigendian;
+      ifa_broadcast : zero+32 : offset(352), bigendian } ->
+      let shape =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      let content =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      { in_ifaddr_shape = shape; in_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_ifaddr", "in_ifaddr_parser_43", match_err));;
+let in_ifaddr_parser_44 bits = 
+  bitmatch bits with
+  | { ifa_next : zero+64 : offset(0), littleendian;
+      ifa_local : zero+32 : offset(256), littleendian;
+      ifa_address : zero+32 : offset(288), littleendian;
+      ifa_mask : zero+32 : offset(320), littleendian;
+      ifa_broadcast : zero+32 : offset(352), littleendian } ->
+      let shape =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      let content =
+      { in_ifaddr_shape_fields_40_ifa_next = ifa_next } in
+      { in_ifaddr_shape = shape; in_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("in_ifaddr", "in_ifaddr_parser_44", match_err));;
+let inet6_ifaddr_parser_48 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), littleendian;
+      lst_next : zero+32 : offset(1024), littleendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_48", match_err));;
+let inet6_ifaddr_parser_50 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), littleendian;
+      lst_next : zero+64 : offset(1856), littleendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_50", match_err));;
+let inet6_ifaddr_parser_49 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), bigendian;
+      lst_next : zero+64 : offset(1472), bigendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_49", match_err));;
+let inet6_ifaddr_parser_51 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), littleendian;
+      lst_next : zero+64 : offset(1472), littleendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_51", match_err));;
+let inet6_ifaddr_parser_52 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), bigendian;
+      lst_next : zero+32 : offset(928), bigendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_52", match_err));;
+let inet6_ifaddr_parser_53 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), littleendian;
+      lst_next : zero+64 : offset(1280), littleendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_53", match_err));;
+let inet6_ifaddr_parser_54 bits = 
+  bitmatch bits with
+  | { prefix_len : zero+32 : offset(128), bigendian;
+      lst_next : zero+64 : offset(1280), bigendian } ->
+      let shape =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      let content =
+      { inet6_ifaddr_shape_fields_46_lst_next = lst_next } in
+      { inet6_ifaddr_shape = shape; inet6_ifaddr_content = content }
+  | { _ } ->
+      raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_54", match_err));;
index ef00e87..c9f13f2 100644 (file)
@@ -5,3 +5,4 @@ type ('a, 'b) in_device;;
 type ('a, 'b) inet6_dev;;
 type ('a, 'b) in_ifaddr;;
 type ('a, 'b) inet6_ifaddr;;
+