Follower code now works
authorRichard W.M. Jones <rjones@redhat.com>
Sat, 16 Aug 2008 10:31:04 +0000 (11:31 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Sat, 16 Aug 2008 10:31:04 +0000 (11:31 +0100)
.hgignore
extract/codegen/code_generation.ml
lib/kernel.ml

index 06a3ff6..345b572 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -32,3 +32,4 @@ ps/virt-ps
 mem/virt-mem
 samples
 lib/*.so
+tmp-kernels
\ No newline at end of file
index 7b0262b..c5e735f 100644 (file)
@@ -126,9 +126,21 @@ let generate_types xs =
          if fields <> [] then (
            let fields = List.map (
              fun (name, t) ->
-               let t = ocaml_type_of_field_type t in
-               <:ctyp< $lid:sf_name^"_"^name$ : $t$ >>
+               match t with
+               | PP.FListHeadPointer _ ->
+                   (* A list head turns into three fields, the pointer,
+                    * the offset within current struct, and the adjustment
+                    * (offset within destination struct).
+                    *)
+                   let t = ocaml_type_of_field_type t in
+                   [ <:ctyp< $lid:sf_name^"_"^name$ : $t$ >>;
+                     <:ctyp< $lid:sf_name^"_"^name^"_offset"$ : int >>;
+                     <:ctyp< $lid:sf_name^"_"^name^"_adjustment"$ : int >> ]
+               | _ ->
+                   let t = ocaml_type_of_field_type t in
+                   [ <:ctyp< $lid:sf_name^"_"^name$ : $t$ >> ]
            ) fields in
+           let fields = List.concat fields in
            let fields = concat_record_fields fields in
 
            <:str_item<
@@ -316,15 +328,17 @@ let generate_parsers xs =
                  List.find (fun { PP.field_name = name } -> field_name = name)
                    structure.PP.struct_fields in
 
-               (* Generate assignment code, if necessary we can adjust
-                * the list_head.
+               (* Generate assignment code.  List_heads are treated
+                * specially because they have an implicit adjustment.
                 *)
                match field_type with
                | PP.FListHeadPointer None ->
-                   sprintf "%s_%s = (if %s <> 0L then Int64.sub %s %dL else %s)"
-                     sf.SC.sf_name field_name
-                     field_name
-                     field_name offset field_name
+                   sprintf "%s_%s = %s;
+          %s_%s_offset = %d;
+          %s_%s_adjustment = %d"
+                     sf.SC.sf_name field_name field_name
+                     sf.SC.sf_name field_name offset
+                     sf.SC.sf_name field_name offset
 
                | PP.FListHeadPointer (Some (other_struct_name,
                                             other_field_name)) ->
@@ -332,16 +346,14 @@ let generate_parsers xs =
                     * know the offset until runtime, so we have to call
                     * offset_of_<struct>_<field> to find it.
                     *)
-                   sprintf "%s_%s = (
-                      if %s <> 0L then (
-                        let offset = offset_of_%s_%s kernel_version in
-                        let offset = Int64.of_int offset in
-                        Int64.sub %s offset
-                      ) else %s
-                    )"
+                   sprintf "%s_%s = %s;
+          %s_%s_offset = %d;
+          %s_%s_adjustment = offset_of_%s_%s kernel_version"
                      sf.SC.sf_name field_name field_name
-                     other_struct_name other_field_name
-                     field_name field_name
+                     sf.SC.sf_name field_name offset (* in this struct *)
+                     sf.SC.sf_name field_name        (* ... & in other struct*)
+                       other_struct_name other_field_name
+
                | _ ->
                    sprintf "%s_%s = %s" sf.SC.sf_name field_name field_name
            ) sf.SC.sf_fields in
@@ -421,16 +433,44 @@ let generate_followers xs =
                | PP.FListHeadPointer (Some (struct_name, _)) -> struct_name
                | PP.FStructPointer struct_name -> struct_name
                | _ -> assert false in
-             tuple_generate_extract follower_tuple follower_name
-               <:patt< f >> <:expr< followers >>
-               <:expr<
-                 let map =
-                   f load followers map shape.$lid:sf_name^"_"^name$ in $body$
-               >>
+
+             match typ with
+             | PP.FListHeadPointer _ ->
+                 tuple_generate_extract follower_tuple follower_name
+                 <:patt< f >> <:expr< followers >>
+                 <:expr<
+                   (* For list head pointers, add the address of the base
+                    * of this virtual structure to the map, then adjust
+                    * the pointer.
+                    *)
+                   let offset = shape.$lid:sf_name^"_"^name^"_offset"$
+                   and adj = shape.$lid:sf_name^"_"^name^"_adjustment"$ in
+                   let offset = Int64.of_int offset
+                   and adj = Int64.of_int adj in
+                   (* 'addr' is base of the virtual struct *)
+                   let addr = Int64.sub (Int64.add addr offset) adj in
+                   let map = AddrMap.add addr ($str:follower_name$, 0) map in
+                   let out_addr =
+                     Int64.sub shape.$lid:sf_name^"_"^name$ adj in
+                   let map =
+                     f load followers map out_addr in
+                   $body$
+                 >>
+
+             | PP.FStructPointer _ ->
+                 tuple_generate_extract follower_tuple follower_name
+                 <:patt< f >> <:expr< followers >>
+                 <:expr<
+                   let map =
+                     f load followers map shape.$lid:sf_name^"_"^name$ in
+                   $body$
+                 >>
+
+             | _ -> assert false
          ) fields <:expr< map >> in
 
          <:str_item<
-           let $lid:sf_name^"_follower"$ load followers map shape =
+           let $lid:sf_name^"_follower"$ load followers map addr shape =
              $body$
          >>
       ) sflist
@@ -454,7 +494,7 @@ let generate_followers xs =
            let map = AddrMap.add addr (struct_name, total_size) map in
            let bits = load struct_name addr total_size in
            let shape, _ = parserfn kernel_version bits in
-           followerfn load followers map shape
+           followerfn load followers map addr shape
          )
          else map
       >> in
@@ -612,7 +652,9 @@ let output_interf ~output_file types offsets parsers followers =
 
   let sigs =
     concat_sig_items [ prologue; types; offsets; parsers; followers ] in
-  Printers.OCaml.print_interf ~output_file sigs
+  Printers.OCaml.print_interf ~output_file sigs;
+
+  ignore (Sys.command (sprintf "wc -l %s" (Filename.quote output_file)))
 
 (* Finally generate the output files. *)
 let re_subst = Pcre.regexp "^(.*)\"(\\w+_parser_\\d+)\"(.*)$"
@@ -621,6 +663,7 @@ let output_implem ~output_file types offsets parsers parser_subs followers =
   (* Some standard code that appears at the top of the implementation file. *)
   let prologue =
     <:str_item<
+      open Printf ;;
       module StringMap = Map.Make (String) ;;
       module AddrMap = Map.Make (Int64) ;;
       type kernel_version = string ;;
@@ -681,4 +724,6 @@ supported Linux distribution, see this page about adding support:
   close_out ochan;
   close_in ichan;
 
-  Unix.unlink new_output_file
+  Unix.unlink new_output_file;
+
+  ignore (Sys.command (sprintf "wc -l %s" (Filename.quote output_file)))
index d04ef22..b02e187 100644 (file)
@@ -7,6 +7,7 @@
  * that you do 'make update-kernel-structs'.
  *)
 
+open Printf;;
 module StringMap = Map.Make(String);;
 module AddrMap = Map.Make(Int64);;
 type kernel_version = string;;
@@ -25,7 +26,9 @@ supported Linux distribution, see this page about adding support:
 let zero = 0;;
 type ('a, 'b) task_struct = ('a * 'b);;
 type task_struct_shape_fields_1 =
-  { task_struct_shape_fields_1_tasks'next : Virt_mem_mmap.addr
+  { task_struct_shape_fields_1_tasks'next : Virt_mem_mmap.addr;
+    task_struct_shape_fields_1_tasks'next_offset : int;
+    task_struct_shape_fields_1_tasks'next_adjustment : int
   };;
 type task_struct_content_fields_2 =
   { task_struct_content_fields_2_comm : string;
@@ -39,6 +42,8 @@ type task_struct_content_fields_2 =
 type ('a, 'b) net_device = ('a * 'b);;
 type net_device_shape_fields_8 =
   { net_device_shape_fields_8_dev_list'next : Virt_mem_mmap.addr;
+    net_device_shape_fields_8_dev_list'next_offset : int;
+    net_device_shape_fields_8_dev_list'next_adjustment : int;
     net_device_shape_fields_8_ip6_ptr : Virt_mem_mmap.addr;
     net_device_shape_fields_8_ip_ptr : Virt_mem_mmap.addr
   };;
@@ -54,7 +59,11 @@ type net_device_content_fields_9 =
 type ('a, 'b) net = ('a * 'b);;
 type net_shape_fields_14 =
   { net_shape_fields_14_dev_base_head'next : Virt_mem_mmap.addr;
-    net_shape_fields_14_dev_base_head'prev : Virt_mem_mmap.addr
+    net_shape_fields_14_dev_base_head'next_offset : int;
+    net_shape_fields_14_dev_base_head'next_adjustment : int;
+    net_shape_fields_14_dev_base_head'prev : Virt_mem_mmap.addr;
+    net_shape_fields_14_dev_base_head'prev_offset : int;
+    net_shape_fields_14_dev_base_head'prev_adjustment : int
   };;
 type net_content_fields_15 = unit;;
 type ('a, 'b) in_device = ('a * 'b);;
@@ -111,7 +120,9 @@ let task_struct_parser_3 kernel_version bits =
       pid : zero+32 : offset(4352), littleendian;
       comm : 128 : offset(8392), string } ->
       let s =
-      { task_struct_shape_fields_1_tasks'next = (if tasks'next <> 0L then Int64.sub tasks'next 480L else tasks'next) } in
+      { task_struct_shape_fields_1_tasks'next = tasks'next;
+          task_struct_shape_fields_1_tasks'next_offset = 480;
+          task_struct_shape_fields_1_tasks'next_adjustment = 480 } in
       let c =
       { task_struct_content_fields_2_comm = comm;
         task_struct_content_fields_2_normal_prio = normal_prio;
@@ -134,7 +145,9 @@ let task_struct_parser_4 kernel_version bits =
       pid : zero+32 : offset(4352), bigendian;
       comm : 128 : offset(8392), string } ->
       let s =
-      { task_struct_shape_fields_1_tasks'next = (if tasks'next <> 0L then Int64.sub tasks'next 480L else tasks'next) } in
+      { task_struct_shape_fields_1_tasks'next = tasks'next;
+          task_struct_shape_fields_1_tasks'next_offset = 480;
+          task_struct_shape_fields_1_tasks'next_adjustment = 480 } in
       let c =
       { task_struct_content_fields_2_comm = comm;
         task_struct_content_fields_2_normal_prio = normal_prio;
@@ -157,7 +170,9 @@ let task_struct_parser_5 kernel_version bits =
       pid : zero+32 : offset(3552), littleendian;
       comm : 128 : offset(5896), string } ->
       let s =
-      { task_struct_shape_fields_1_tasks'next = (if tasks'next <> 0L then Int64.sub tasks'next 400L else tasks'next) } in
+      { task_struct_shape_fields_1_tasks'next = tasks'next;
+          task_struct_shape_fields_1_tasks'next_offset = 400;
+          task_struct_shape_fields_1_tasks'next_adjustment = 400 } in
       let c =
       { task_struct_content_fields_2_comm = comm;
         task_struct_content_fields_2_normal_prio = normal_prio;
@@ -180,7 +195,9 @@ let task_struct_parser_6 kernel_version bits =
       pid : zero+32 : offset(3584), littleendian;
       comm : 128 : offset(5928), string } ->
       let s =
-      { task_struct_shape_fields_1_tasks'next = (if tasks'next <> 0L then Int64.sub tasks'next 404L else tasks'next) } in
+      { task_struct_shape_fields_1_tasks'next = tasks'next;
+          task_struct_shape_fields_1_tasks'next_offset = 404;
+          task_struct_shape_fields_1_tasks'next_adjustment = 404 } in
       let c =
       { task_struct_content_fields_2_comm = comm;
         task_struct_content_fields_2_normal_prio = normal_prio;
@@ -203,7 +220,9 @@ let task_struct_parser_7 kernel_version bits =
       pid : zero+32 : offset(3680), bigendian;
       comm : 128 : offset(6056), string } ->
       let s =
-      { task_struct_shape_fields_1_tasks'next = (if tasks'next <> 0L then Int64.sub tasks'next 416L else tasks'next) } in
+      { task_struct_shape_fields_1_tasks'next = tasks'next;
+          task_struct_shape_fields_1_tasks'next_offset = 416;
+          task_struct_shape_fields_1_tasks'next_adjustment = 416 } in
       let c =
       { task_struct_content_fields_2_comm = comm;
         task_struct_content_fields_2_normal_prio = normal_prio;
@@ -228,7 +247,9 @@ let net_device_parser_10 kernel_version bits =
       ip_ptr : zero+64 : offset(3840), littleendian;
       ip6_ptr : zero+64 : offset(3968), littleendian } ->
       let s =
-      { net_device_shape_fields_8_dev_list'next = (if dev_list'next <> 0L then Int64.sub dev_list'next 72L else dev_list'next);
+      { net_device_shape_fields_8_dev_list'next = dev_list'next;
+          net_device_shape_fields_8_dev_list'next_offset = 72;
+          net_device_shape_fields_8_dev_list'next_adjustment = 72;
         net_device_shape_fields_8_ip6_ptr = ip6_ptr;
         net_device_shape_fields_8_ip_ptr = ip_ptr } in
       let c =
@@ -255,7 +276,9 @@ let net_device_parser_11 kernel_version bits =
       ip_ptr : zero+64 : offset(3840), bigendian;
       ip6_ptr : zero+64 : offset(3968), bigendian } ->
       let s =
-      { net_device_shape_fields_8_dev_list'next = (if dev_list'next <> 0L then Int64.sub dev_list'next 72L else dev_list'next);
+      { net_device_shape_fields_8_dev_list'next = dev_list'next;
+          net_device_shape_fields_8_dev_list'next_offset = 72;
+          net_device_shape_fields_8_dev_list'next_adjustment = 72;
         net_device_shape_fields_8_ip6_ptr = ip6_ptr;
         net_device_shape_fields_8_ip_ptr = ip_ptr } in
       let c =
@@ -282,7 +305,9 @@ let net_device_parser_12 kernel_version bits =
       ip_ptr : zero+32 : offset(2304), littleendian;
       ip6_ptr : zero+32 : offset(2368), littleendian } ->
       let s =
-      { net_device_shape_fields_8_dev_list'next = (if dev_list'next <> 0L then Int64.sub dev_list'next 48L else dev_list'next);
+      { net_device_shape_fields_8_dev_list'next = dev_list'next;
+          net_device_shape_fields_8_dev_list'next_offset = 48;
+          net_device_shape_fields_8_dev_list'next_adjustment = 48;
         net_device_shape_fields_8_ip6_ptr = ip6_ptr;
         net_device_shape_fields_8_ip_ptr = ip_ptr } in
       let c =
@@ -309,7 +334,9 @@ let net_device_parser_13 kernel_version bits =
       ip_ptr : zero+32 : offset(2304), bigendian;
       ip6_ptr : zero+32 : offset(2368), bigendian } ->
       let s =
-      { net_device_shape_fields_8_dev_list'next = (if dev_list'next <> 0L then Int64.sub dev_list'next 48L else dev_list'next);
+      { net_device_shape_fields_8_dev_list'next = dev_list'next;
+          net_device_shape_fields_8_dev_list'next_offset = 48;
+          net_device_shape_fields_8_dev_list'next_adjustment = 48;
         net_device_shape_fields_8_ip6_ptr = ip6_ptr;
         net_device_shape_fields_8_ip_ptr = ip_ptr } in
       let c =
@@ -328,20 +355,12 @@ let net_parser_18 kernel_version bits =
   | { dev_base_head'next : zero+32 : offset(416), littleendian;
       dev_base_head'prev : zero+32 : offset(448), littleendian } ->
       let s =
-      { net_shape_fields_14_dev_base_head'next = (
-                      if dev_base_head'next <> 0L then (
-                        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
-                      ) else dev_base_head'next
-                    );
-        net_shape_fields_14_dev_base_head'prev = (
-                      if dev_base_head'prev <> 0L then (
-                        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
-                      ) else dev_base_head'prev
-                    ) } in
+      { net_shape_fields_14_dev_base_head'next = dev_base_head'next;
+          net_shape_fields_14_dev_base_head'next_offset = 52;
+          net_shape_fields_14_dev_base_head'next_adjustment = offset_of_net_device_dev_list'next kernel_version;
+        net_shape_fields_14_dev_base_head'prev = dev_base_head'prev;
+          net_shape_fields_14_dev_base_head'prev_offset = 56;
+          net_shape_fields_14_dev_base_head'prev_adjustment = offset_of_net_device_dev_list'next kernel_version } in
       let c =
       () in
       (s, c)
@@ -352,20 +371,12 @@ let net_parser_19 kernel_version bits =
   | { dev_base_head'next : zero+32 : offset(416), bigendian;
       dev_base_head'prev : zero+32 : offset(448), bigendian } ->
       let s =
-      { net_shape_fields_14_dev_base_head'next = (
-                      if dev_base_head'next <> 0L then (
-                        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
-                      ) else dev_base_head'next
-                    );
-        net_shape_fields_14_dev_base_head'prev = (
-                      if dev_base_head'prev <> 0L then (
-                        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
-                      ) else dev_base_head'prev
-                    ) } in
+      { net_shape_fields_14_dev_base_head'next = dev_base_head'next;
+          net_shape_fields_14_dev_base_head'next_offset = 52;
+          net_shape_fields_14_dev_base_head'next_adjustment = offset_of_net_device_dev_list'next kernel_version;
+        net_shape_fields_14_dev_base_head'prev = dev_base_head'prev;
+          net_shape_fields_14_dev_base_head'prev_offset = 56;
+          net_shape_fields_14_dev_base_head'prev_adjustment = offset_of_net_device_dev_list'next kernel_version } in
       let c =
       () in
       (s, c)
@@ -376,20 +387,12 @@ let net_parser_16 kernel_version bits =
   | { dev_base_head'next : zero+64 : offset(768), littleendian;
       dev_base_head'prev : zero+64 : offset(832), littleendian } ->
       let s =
-      { net_shape_fields_14_dev_base_head'next = (
-                      if dev_base_head'next <> 0L then (
-                        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
-                      ) else dev_base_head'next
-                    );
-        net_shape_fields_14_dev_base_head'prev = (
-                      if dev_base_head'prev <> 0L then (
-                        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
-                      ) else dev_base_head'prev
-                    ) } in
+      { net_shape_fields_14_dev_base_head'next = dev_base_head'next;
+          net_shape_fields_14_dev_base_head'next_offset = 96;
+          net_shape_fields_14_dev_base_head'next_adjustment = offset_of_net_device_dev_list'next kernel_version;
+        net_shape_fields_14_dev_base_head'prev = dev_base_head'prev;
+          net_shape_fields_14_dev_base_head'prev_offset = 104;
+          net_shape_fields_14_dev_base_head'prev_adjustment = offset_of_net_device_dev_list'next kernel_version } in
       let c =
       () in
       (s, c)
@@ -400,20 +403,12 @@ let net_parser_17 kernel_version bits =
   | { dev_base_head'next : zero+64 : offset(768), bigendian;
       dev_base_head'prev : zero+64 : offset(832), bigendian } ->
       let s =
-      { net_shape_fields_14_dev_base_head'next = (
-                      if dev_base_head'next <> 0L then (
-                        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
-                      ) else dev_base_head'next
-                    );
-        net_shape_fields_14_dev_base_head'prev = (
-                      if dev_base_head'prev <> 0L then (
-                        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
-                      ) else dev_base_head'prev
-                    ) } in
+      { net_shape_fields_14_dev_base_head'next = dev_base_head'next;
+          net_shape_fields_14_dev_base_head'next_offset = 96;
+          net_shape_fields_14_dev_base_head'next_adjustment = offset_of_net_device_dev_list'next kernel_version;
+        net_shape_fields_14_dev_base_head'prev = dev_base_head'prev;
+          net_shape_fields_14_dev_base_head'prev_offset = 104;
+          net_shape_fields_14_dev_base_head'prev_adjustment = offset_of_net_device_dev_list'next kernel_version } in
       let c =
       () in
       (s, c)
@@ -611,39 +606,62 @@ let inet6_ifaddr_parser_43 kernel_version bits =
       (s, c)
   | { _ } ->
       raise (Virt_mem_types.ParseError ("inet6_ifaddr", "inet6_ifaddr_parser_43", match_err));;
-let task_struct_shape_fields_1_follower load followers map shape =
+let task_struct_shape_fields_1_follower load followers map addr shape =
   let (_, _, _, _, _, _, f) = followers in
-  let map = f load followers map shape.task_struct_shape_fields_1_tasks'next
-  in map;;
-let net_device_shape_fields_8_follower load followers map shape =
+  let offset = shape.task_struct_shape_fields_1_tasks'next_offset
+  and adj = shape.task_struct_shape_fields_1_tasks'next_adjustment in
+  let offset = Int64.of_int offset and adj = Int64.of_int adj in
+  let addr = Int64.sub (Int64.add addr offset) adj in
+  let map = AddrMap.add addr ("task_struct", 0) map in
+  let out_addr = Int64.sub shape.task_struct_shape_fields_1_tasks'next adj in
+  let map = f load followers map out_addr in map;;
+let net_device_shape_fields_8_follower load followers map addr shape =
   let (_, _, _, _, _, f, _) = followers in
-  let map =
-    f load followers map shape.net_device_shape_fields_8_dev_list'next in
+  let offset = shape.net_device_shape_fields_8_dev_list'next_offset
+  and adj = shape.net_device_shape_fields_8_dev_list'next_adjustment in
+  let offset = Int64.of_int offset and adj = Int64.of_int adj in
+  let addr = Int64.sub (Int64.add addr offset) adj in
+  let map = AddrMap.add addr ("net_device", 0) map in
+  let out_addr =
+    Int64.sub shape.net_device_shape_fields_8_dev_list'next adj in
+  let map = f load followers map out_addr in
   let (_, _, f, _, _, _, _) = followers in
   let map = f load followers map shape.net_device_shape_fields_8_ip6_ptr in
   let (_, _, _, f, _, _, _) = followers in
   let map = f load followers map shape.net_device_shape_fields_8_ip_ptr
   in map;;
-let net_shape_fields_14_follower load followers map shape =
+let net_shape_fields_14_follower load followers map addr shape =
   let (_, _, _, _, _, f, _) = followers in
-  let map =
-    f load followers map shape.net_shape_fields_14_dev_base_head'next in
+  let offset = shape.net_shape_fields_14_dev_base_head'next_offset
+  and adj = shape.net_shape_fields_14_dev_base_head'next_adjustment in
+  let offset = Int64.of_int offset and adj = Int64.of_int adj in
+  let addr = Int64.sub (Int64.add addr offset) adj in
+  let map = AddrMap.add addr ("net_device", 0) map in
+  let out_addr =
+    Int64.sub shape.net_shape_fields_14_dev_base_head'next adj in
+  let map = f load followers map out_addr in
   let (_, _, _, _, _, f, _) = followers in
-  let map = f load followers map shape.net_shape_fields_14_dev_base_head'prev
-  in map;;
-let in_device_shape_fields_20_follower load followers map shape =
+  let offset = shape.net_shape_fields_14_dev_base_head'prev_offset
+  and adj = shape.net_shape_fields_14_dev_base_head'prev_adjustment in
+  let offset = Int64.of_int offset and adj = Int64.of_int adj in
+  let addr = Int64.sub (Int64.add addr offset) adj in
+  let map = AddrMap.add addr ("net_device", 0) map in
+  let out_addr =
+    Int64.sub shape.net_shape_fields_14_dev_base_head'prev adj in
+  let map = f load followers map out_addr in map;;
+let in_device_shape_fields_20_follower load followers map addr shape =
   let (_, f, _, _, _, _, _) = followers in
   let map = f load followers map shape.in_device_shape_fields_20_ifa_list
   in map;;
-let inet6_dev_shape_fields_26_follower load followers map shape =
+let inet6_dev_shape_fields_26_follower load followers map addr shape =
   let (f, _, _, _, _, _, _) = followers in
   let map = f load followers map shape.inet6_dev_shape_fields_26_addr_list
   in map;;
-let in_ifaddr_shape_fields_32_follower load followers map shape =
+let in_ifaddr_shape_fields_32_follower load followers map addr shape =
   let (_, f, _, _, _, _, _) = followers in
   let map = f load followers map shape.in_ifaddr_shape_fields_32_ifa_next
   in map;;
-let inet6_ifaddr_shape_fields_38_follower load followers map shape =
+let inet6_ifaddr_shape_fields_38_follower load followers map addr shape =
   let (f, _, _, _, _, _, _) = followers in
   let map = f load followers map shape.inet6_ifaddr_shape_fields_38_lst_next
   in map;;
@@ -654,7 +672,7 @@ let kv_follower kernel_version struct_name total_size parserfn followerfn
     (let map = AddrMap.add addr (struct_name, total_size) map in
      let bits = load struct_name addr total_size in
      let (shape, _) = parserfn kernel_version bits
-     in followerfn load followers map shape)
+     in followerfn load followers map addr shape)
   else map;;
 let task_struct_kv0_follower =
   kv_follower "2.6.25.14-69.fc8.x86_64" "task_struct" 2496