Cross-references in list_head fields working.
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 14 Aug 2008 18:05:30 +0000 (19:05 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 14 Aug 2008 18:05:30 +0000 (19:05 +0100)
extract/codegen/.depend
extract/codegen/code_generation.ml
extract/codegen/code_generation.mli
extract/codegen/compile_kerneldb.ml
lib/kernel.ml
lib/kernel.mli

index bfdc337..e51636c 100644 (file)
@@ -1,4 +1,4 @@
-code_generation.cmi: struct_classify.cmi 
+code_generation.cmi: struct_classify.cmi pahole_parser.cmi 
 struct_classify.cmi: pahole_parser.cmi 
 code_generation.cmo: struct_classify.cmi pahole_parser.cmi \
     code_generation.cmi 
index 37bffc2..b462af2 100644 (file)
@@ -28,6 +28,19 @@ open Printf
 module PP = Pahole_parser
 module SC = Struct_classify
 
+let rec uniq ?(cmp = Pervasives.compare) = function
+    [] -> []
+  | [x] -> [x]
+  | x :: y :: xs when cmp x y = 0 ->
+      uniq (x :: xs)
+  | x :: y :: xs ->
+      x :: uniq (y :: xs)
+
+let sort_uniq ?cmp xs =
+  let xs = List.sort ?cmp xs in
+  let xs = uniq ?cmp xs in
+  xs
+
 (* We don't care about locations when generating code, so it's
  * useful to just have a single global _loc.
  *)
@@ -83,6 +96,8 @@ let build_tuple_from_exprs exprs =
       Ast.ExTup (_loc,
                 List.fold_left (fun xs x -> Ast.ExCom (_loc, x, xs)) x xs)
 
+type code = Ast.str_item * Ast.sig_item
+
 let ocaml_type_of_field_type = function
   | PP.FInteger -> <:ctyp< int64 >>
   | PP.FString _ -> <:ctyp< string >>
@@ -149,6 +164,82 @@ let generate_types xs =
 
   concat_str_items strs, concat_sig_items sigs
 
+let generate_offsets xs =
+  (* Only need to generate the offset_of_* functions for fields
+   * which are cross-referenced from another field.  Which
+   * ones are those?
+   *)
+  let fields =
+    List.concat (
+      List.map (
+       fun (_, (_, all_fields)) ->
+         List.filter_map (
+           function
+           | (_,
+              PP.FListHeadPointer ((Some (struct_name, field_name)) as f)) ->
+               f
+           | _ ->
+               None
+         ) all_fields
+      ) xs
+    ) in
+
+  let fields = sort_uniq fields in
+
+  let strs =
+    List.map (
+      fun (struct_name, field_name) ->
+       let kernels, _ =
+         try List.assoc struct_name xs
+         with Not_found ->
+           failwith (
+             sprintf "generate_offsets: structure %s not found. This is probably a list_head-related bug."
+               struct_name
+           ) in
+       (* Find the offset of this field in each kernel version. *)
+       let offsets =
+         List.filter_map (
+           fun ({ PP.kernel_version = version },
+                { PP.struct_fields = fields }) ->
+             try
+               let field =
+                 List.find (fun { PP.field_name = name } -> field_name = name)
+                   fields in
+               let offset = field.PP.field_offset in
+               Some (version, offset)
+             with Not_found -> None
+         ) kernels in
+
+       if offsets = [] then
+         failwith (
+           sprintf "generate_offsets: field %s.%s not found in any kernel. This is probably a list_head-related bug."
+             struct_name field_name
+         );
+
+       (* Generate a map of kernel version to offset. *)
+       let map = List.fold_left (
+         fun map (version, offset) ->
+           <:expr< StringMap.add $str:version$ $`int:offset$ $map$ >>
+       ) <:expr< StringMap.empty >> offsets in
+
+       let code =
+         <:str_item<
+           let $lid:"offset_of_"^struct_name^"_"^field_name$ =
+             let map = $map$ in
+             fun kernel_version -> StringMap.find kernel_version map
+         >> in
+       code
+    ) fields in
+
+  let strs = concat_str_items strs in
+  let strs =
+    <:str_item<
+      module StringMap = Map.Make (String) ;;
+      $strs$
+    >> in
+
+  strs, <:sig_item< >>
+
 let generate_parsers xs =
   let strs =
     List.map (
@@ -156,7 +247,9 @@ let generate_parsers xs =
        let palist =
          List.map (
            fun { SC.pa_name = pa_name } ->
-             <:str_item< let $lid:pa_name$ bits = $str:pa_name$ >>
+             <:str_item<
+               let $lid:pa_name$ kernel_version bits = $str:pa_name$
+             >>
          ) palist in
        concat_str_items palist
     ) xs in
@@ -234,11 +327,20 @@ let generate_parsers xs =
                    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
-
+               | PP.FListHeadPointer (Some (other_struct_name,
+                                            other_field_name)) ->
+                   (* A reference to a field in another structure.  We don't
+                    * know the offset until runtime, so we have to call
+                    * offset_of_<struct>_<field> to find it.
+                    *)
+                   sprintf "%s_%s = (
+                      let offset = offset_of_%s_%s kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub %s offset
+                    )"
+                     sf.SC.sf_name field_name
+                     other_struct_name other_field_name
+                     field_name
                | _ ->
                    sprintf "%s_%s = %s" sf.SC.sf_name field_name field_name
            ) sf.SC.sf_fields in
@@ -274,19 +376,19 @@ let generate_parsers xs =
       ) palist;
   ) xs;
 
-  strs, <:sig_item< >>, subs
+  (strs, <:sig_item< >>), subs
 
-let output_interf ~output_file types parsers =
-  let sigs = concat_sig_items [ types; parsers ] in
+let output_interf ~output_file types offsets parsers =
+  let sigs = concat_sig_items [ types; offsets; parsers ] in
   Printers.OCaml.print_interf ~output_file sigs
 
 (* Finally generate the output files. *)
 let re_subst = Pcre.regexp "^(.*)\"(\\w+_parser_\\d+)\"(.*)$"
 
-let output_implem ~output_file types parsers parser_subs =
+let output_implem ~output_file types offsets parsers parser_subs =
   let new_output_file = output_file ^ ".new" in
 
-  let strs = concat_str_items [ types; parsers ] in
+  let strs = concat_str_items [ types; offsets; parsers ] in
   Printers.OCaml.print_implem ~output_file:new_output_file strs;
 
   (* Substitute the parser bodies in the output file. *)
index 36140cd..c2e1271 100644 (file)
    to the kernel structures, and [kernel.ml] is the implementation.
 *)
 
-(** {2 Generate types} *)
+type code =
+    Camlp4.PreCast.Syntax.Ast.str_item * Camlp4.PreCast.Syntax.Ast.sig_item
+
+(** {2 Generate types}
+
+    Our internal types, representing kernel structures.
+*)
 
 val generate_types :
   (string
    * Struct_classify.shape_field_struct list
    * Struct_classify.content_field_struct list) list ->
-  Camlp4.PreCast.Syntax.Ast.str_item * Camlp4.PreCast.Syntax.Ast.sig_item
+  code
     (** [generate_types structures] generates the internal
        types used to store variants of each structure, including:
        - shape field structures
        - content field structures
     *)
 
-(** {2 Generate parsers} *)
+(** {2 Generate offset functions}
+
+    [offset_of_<struct>_<field> kernel_version] functions.
+
+    These actually play a very minor role: We just use them when
+    adjusting [list_head] pointers which cross between structure
+    types, so we only generate functions for those right now.
+*)
+
+val generate_offsets :
+  (string * ((Pahole_parser.info * Pahole_parser.structure) list
+            * (string * Pahole_parser.f_type) list)) list ->
+  code
+    (** [generate_offsets] generates the offset functions. *)
+
+(** {2 Generate parsers}
+
+    Functions which parse the different structures from bitstrings
+    into our internal types.
+*)
 
 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
+  code * (string, string) Hashtbl.t
     (** [generate_parsers] generates the parser functions.
 
        We cannot generate the complete code here because we
@@ -57,12 +81,14 @@ val generate_parsers : (string * Struct_classify.parser_ list) list ->
 val output_interf : output_file:string ->
   Camlp4.PreCast.Syntax.Ast.sig_item ->
   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 ->
   Camlp4.PreCast.Syntax.Ast.str_item ->
+  Camlp4.PreCast.Syntax.Ast.str_item ->
   (string, string) Hashtbl.t ->
   unit
   (** Output the implementation file. *)
index 31bb000..2f7e89a 100644 (file)
@@ -67,8 +67,10 @@ let good_structs = [
   "net", {
     good_fields = [ "dev_base_head'next"; "dev_base_head'prev" ];
     field_metadata = [
-      "dev_base_head'next", ListHeadIsReally (Some ("net_device", "dev_list"));
-      "dev_base_head'prev", ListHeadIsReally (Some ("net_device", "dev_list"));
+      "dev_base_head'next",
+        ListHeadIsReally (Some ("net_device", "dev_list'next"));
+      "dev_base_head'prev",
+        ListHeadIsReally (Some ("net_device", "dev_list'next"));
     ];
   };
   "in_device", {
@@ -342,7 +344,16 @@ Options:
       ) structures
     ) in
 
-  let implem_parsers, interf_parsers, subst_parsers =
+  let implem_offsets, interf_offsets =
+    CG.generate_offsets (
+      List.map (
+       fun (struct_name,
+            (kernels, all_fields, _, _, _, _, _, _)) ->
+         (struct_name, (kernels, all_fields))
+      ) structures
+    ) in
+
+  let (implem_parsers, interf_parsers), subst_parsers =
     CG.generate_parsers (
       List.map (
        fun (struct_name, (_, _, _, _, _, _, palist, _)) ->
@@ -353,10 +364,13 @@ Options:
   (* 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 interf_parsers;
+  CG.output_interf ~output_file
+    interf_types interf_offsets 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 implem_parsers subst_parsers;
+  CG.output_implem ~output_file
+    implem_types implem_offsets implem_parsers
+    subst_parsers;
 
   printf "Finished.\n"
index 1a2e91b..8a7b132 100644 (file)
@@ -83,9 +83,19 @@ type inet6_ifaddr_shape_fields_46 =
 type inet6_ifaddr_content_fields_47 =
   { inet6_ifaddr_content_fields_47_prefix_len : int64
   };;
+module StringMap = Map.Make(String);;
+let offset_of_net_device_dev_list'next =
+  let map =
+    StringMap.add "2.6.27-0.226.rc1.git5.fc10.ppc" 48
+      (StringMap.add "2.6.26.1-9.fc9.ppc64" 72
+         (StringMap.add "2.6.25.14-69.fc8.x86_64" 72
+            (StringMap.add "2.6.24-0.167.rc8.git4.fc9.ppc64" 72
+               (StringMap.add "2.6.22-0.23.rc7.git6.fc8.ppc" 48 StringMap.
+                  empty))))
+  in fun kernel_version -> StringMap.find kernel_version map;;
 let match_err = "failed to match kernel structure";;
 let zero = 0;;
-let task_struct_parser_4 bits = 
+let task_struct_parser_4 kernel_version bits = 
   bitmatch bits with
   | { state : zero+32 : offset(0), littleendian;
       prio : zero+32 : offset(192), littleendian;
@@ -110,7 +120,7 @@ let task_struct_parser_4 bits =
       { 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 = 
+let task_struct_parser_5 kernel_version bits = 
   bitmatch bits with
   | { state : zero+64 : offset(0), bigendian;
       prio : zero+32 : offset(320), bigendian;
@@ -135,7 +145,7 @@ let task_struct_parser_5 bits =
       { 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 = 
+let task_struct_parser_6 kernel_version bits = 
   bitmatch bits with
   | { state : zero+64 : offset(0), littleendian;
       prio : zero+32 : offset(320), littleendian;
@@ -160,7 +170,7 @@ let task_struct_parser_6 bits =
       { 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 = 
+let task_struct_parser_7 kernel_version bits = 
   bitmatch bits with
   | { state : zero+32 : offset(0), bigendian;
       prio : zero+32 : offset(160), bigendian;
@@ -185,7 +195,7 @@ let task_struct_parser_7 bits =
       { 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 = 
+let task_struct_parser_8 kernel_version bits = 
   bitmatch bits with
   | { state : zero+64 : offset(0), bigendian;
       prio : zero+32 : offset(224), bigendian;
@@ -210,7 +220,7 @@ let task_struct_parser_8 bits =
       { 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 = 
+let task_struct_parser_9 kernel_version bits = 
   bitmatch bits with
   | { state : zero+64 : offset(0), littleendian;
       prio : zero+32 : offset(224), littleendian;
@@ -229,7 +239,7 @@ let task_struct_parser_9 bits =
       { 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 = 
+let task_struct_parser_10 kernel_version bits = 
   bitmatch bits with
   | { state : zero+64 : offset(0), bigendian;
       prio : zero+32 : offset(256), bigendian;
@@ -248,7 +258,7 @@ let task_struct_parser_10 bits =
       { 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 = 
+let task_struct_parser_11 kernel_version bits = 
   bitmatch bits with
   | { state : zero+32 : offset(0), bigendian;
       prio : zero+32 : offset(192), bigendian;
@@ -267,7 +277,7 @@ let task_struct_parser_11 bits =
       { 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 = 
+let net_device_parser_15 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       next : zero+32 : offset(384), littleendian;
@@ -289,7 +299,7 @@ let net_device_parser_15 bits =
       { 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 = 
+let net_device_parser_16 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       next : zero+64 : offset(576), bigendian;
@@ -311,7 +321,7 @@ let net_device_parser_16 bits =
       { 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 = 
+let net_device_parser_17 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       next : zero+64 : offset(576), littleendian;
@@ -333,7 +343,7 @@ let net_device_parser_17 bits =
       { 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 = 
+let net_device_parser_18 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       dev_list'next : zero+32 : offset(384), bigendian;
@@ -358,7 +368,7 @@ let net_device_parser_18 bits =
       { 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 = 
+let net_device_parser_19 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       dev_list'next : zero+64 : offset(576), bigendian;
@@ -383,7 +393,7 @@ let net_device_parser_19 bits =
       { 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 = 
+let net_device_parser_20 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       dev_list'next : zero+64 : offset(576), littleendian;
@@ -408,7 +418,7 @@ let net_device_parser_20 bits =
       { 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 = 
+let net_device_parser_21 kernel_version bits = 
   bitmatch bits with
   | { name : 128 : offset(0), string;
       dev_list'next : zero+32 : offset(384), bigendian;
@@ -433,59 +443,91 @@ let net_device_parser_21 bits =
       { 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 = 
+let net_parser_24 kernel_version 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
+      { net_shape_fields_22_dev_base_head'next = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'next offset
+                    );
+        net_shape_fields_22_dev_base_head'prev = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'prev offset
+                    ) } 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 = 
+let net_parser_25 kernel_version 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
+      { net_shape_fields_22_dev_base_head'next = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'next offset
+                    );
+        net_shape_fields_22_dev_base_head'prev = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'prev offset
+                    ) } 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 = 
+let net_parser_26 kernel_version 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
+      { net_shape_fields_22_dev_base_head'next = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'next offset
+                    );
+        net_shape_fields_22_dev_base_head'prev = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'prev offset
+                    ) } 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 = 
+let net_parser_27 kernel_version 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
+      { net_shape_fields_22_dev_base_head'next = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'next offset
+                    );
+        net_shape_fields_22_dev_base_head'prev = (
+                      let offset = offset_of_net_device_dev_list'next kernel_version in
+                      let offset = Int64.of_int offset in
+                      Int64.sub dev_base_head'prev offset
+                    ) } 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 = 
+let in_device_parser_30 kernel_version bits = 
   bitmatch bits with
   | { ifa_list : zero+32 : offset(96), littleendian } ->
       let shape =
@@ -495,7 +537,7 @@ let in_device_parser_30 bits =
       { 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 = 
+let in_device_parser_33 kernel_version bits = 
   bitmatch bits with
   | { ifa_list : zero+32 : offset(96), bigendian } ->
       let shape =
@@ -505,7 +547,7 @@ let in_device_parser_33 bits =
       { 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 = 
+let in_device_parser_32 kernel_version bits = 
   bitmatch bits with
   | { ifa_list : zero+64 : offset(128), littleendian } ->
       let shape =
@@ -515,7 +557,7 @@ let in_device_parser_32 bits =
       { 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 = 
+let in_device_parser_31 kernel_version bits = 
   bitmatch bits with
   | { ifa_list : zero+64 : offset(128), bigendian } ->
       let shape =
@@ -525,7 +567,7 @@ let in_device_parser_31 bits =
       { 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 = 
+let inet6_dev_parser_36 kernel_version bits = 
   bitmatch bits with
   | { addr_list : zero+32 : offset(32), littleendian } ->
       let shape =
@@ -535,7 +577,7 @@ let inet6_dev_parser_36 bits =
       { 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 = 
+let inet6_dev_parser_39 kernel_version bits = 
   bitmatch bits with
   | { addr_list : zero+32 : offset(32), bigendian } ->
       let shape =
@@ -545,7 +587,7 @@ let inet6_dev_parser_39 bits =
       { 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 = 
+let inet6_dev_parser_38 kernel_version bits = 
   bitmatch bits with
   | { addr_list : zero+64 : offset(64), littleendian } ->
       let shape =
@@ -555,7 +597,7 @@ let inet6_dev_parser_38 bits =
       { 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 = 
+let inet6_dev_parser_37 kernel_version bits = 
   bitmatch bits with
   | { addr_list : zero+64 : offset(64), bigendian } ->
       let shape =
@@ -565,7 +607,7 @@ let inet6_dev_parser_37 bits =
       { 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 = 
+let in_ifaddr_parser_42 kernel_version bits = 
   bitmatch bits with
   | { ifa_next : zero+32 : offset(0), littleendian;
       ifa_local : zero+32 : offset(128), littleendian;
@@ -579,7 +621,7 @@ let in_ifaddr_parser_42 bits =
       { 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 = 
+let in_ifaddr_parser_45 kernel_version bits = 
   bitmatch bits with
   | { ifa_next : zero+32 : offset(0), bigendian;
       ifa_local : zero+32 : offset(128), bigendian;
@@ -593,7 +635,7 @@ let in_ifaddr_parser_45 bits =
       { 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 = 
+let in_ifaddr_parser_43 kernel_version bits = 
   bitmatch bits with
   | { ifa_next : zero+64 : offset(0), bigendian;
       ifa_local : zero+32 : offset(256), bigendian;
@@ -607,7 +649,7 @@ let in_ifaddr_parser_43 bits =
       { 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 = 
+let in_ifaddr_parser_44 kernel_version bits = 
   bitmatch bits with
   | { ifa_next : zero+64 : offset(0), littleendian;
       ifa_local : zero+32 : offset(256), littleendian;
@@ -621,7 +663,7 @@ let in_ifaddr_parser_44 bits =
       { 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 = 
+let inet6_ifaddr_parser_48 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), littleendian;
       lst_next : zero+32 : offset(1024), littleendian } ->
@@ -632,7 +674,7 @@ let inet6_ifaddr_parser_48 bits =
       { 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 = 
+let inet6_ifaddr_parser_50 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), littleendian;
       lst_next : zero+64 : offset(1856), littleendian } ->
@@ -643,7 +685,7 @@ let inet6_ifaddr_parser_50 bits =
       { 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 = 
+let inet6_ifaddr_parser_49 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), bigendian;
       lst_next : zero+64 : offset(1472), bigendian } ->
@@ -654,7 +696,7 @@ let inet6_ifaddr_parser_49 bits =
       { 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 = 
+let inet6_ifaddr_parser_51 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), littleendian;
       lst_next : zero+64 : offset(1472), littleendian } ->
@@ -665,7 +707,7 @@ let inet6_ifaddr_parser_51 bits =
       { 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 = 
+let inet6_ifaddr_parser_52 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), bigendian;
       lst_next : zero+32 : offset(928), bigendian } ->
@@ -676,7 +718,7 @@ let inet6_ifaddr_parser_52 bits =
       { 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 = 
+let inet6_ifaddr_parser_53 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), littleendian;
       lst_next : zero+64 : offset(1280), littleendian } ->
@@ -687,7 +729,7 @@ let inet6_ifaddr_parser_53 bits =
       { 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 = 
+let inet6_ifaddr_parser_54 kernel_version bits = 
   bitmatch bits with
   | { prefix_len : zero+32 : offset(128), bigendian;
       lst_next : zero+64 : offset(1280), bigendian } ->
index c9f13f2..3cc41e7 100644 (file)
@@ -6,3 +6,4 @@ type ('a, 'b) inet6_dev;;
 type ('a, 'b) in_ifaddr;;
 type ('a, 'b) inet6_ifaddr;;
 
+