Experimental automated 'follower' code.
[virt-mem.git] / extract / codegen / pahole_parser.mli
1 (** 'pahole' output parser. *)
2 (* Memory info command for virtual domains.
3    (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
4    http://libvirt.org/
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *)
20
21 (** This parses the output of the pahole command, allowing us
22     to extract the layout of kernel structures for particular
23     kernel versions.
24
25     Its primary input is the [*.info] and [*.data*] files found
26     in the [kernels/] subdirectory (ie. the kerneldb).
27 *)
28
29 (** {2 Types} *)
30
31 type pathname = string
32   (** Path and filenames. *)
33
34 type info = {
35   kv_i : int;                          (** Each kernel is given a unique
36                                            number. *)
37   kernel_version : string;             (** Kernel version that this matches. *)
38   arch : string;                       (** Architecture, eg. "i686", "ppc64". *)
39   basename : string;                   (** [basename.info] is the info
40                                            file and [basename.data*] is
41                                            the data file. *)
42 }
43   (** Kernel metainformation, extracted from the [*.info] file. *)
44
45 type structure = {
46   struct_name : string;                 (** Structure name. *)
47   struct_total_size : int;              (** Total size in bytes. *)
48   struct_fields : field list;           (** Fields in the structure. *)
49 }
50   (** A kernel structure, eg. [task_struct]. *)
51
52 and field = {
53   field_name : string;                  (** Field name. *)
54   field_type : f_type;                  (** Field type. *)
55   field_offset : int;                   (** Offset within the structure. *)
56   field_size : int;                     (** Size of the field (bytes). *)
57 }
58   (** A kernel structure field.
59
60       Note that nested fields are flattened with single quotes (')
61       between elements, so you get names like [tasks'next]. *)
62
63 and f_type =
64   | FStructPointer of string            (** A pointer to a named struct. *)
65   | FVoidPointer                        (** A [void*] pointer. *)
66   | FAnonListHeadPointer                (** A pointer to an unknown
67                                             [list_head]. *)
68   | FListHeadPointer of (string * string) option
69       (** A pointer to a [list_head].  If the value is not [None] then
70           this relates to another named struct/field, else it relates
71           to this struct/field. *)
72   | FInteger                            (** An integer. *)
73   | FString of int                      (** A char array of given width. *)
74   (** Type of a kernel field. *)
75
76 val string_of_info : info -> string
77 val string_of_structure : structure -> string
78 val string_of_field : field -> string
79 val string_of_f_type : f_type -> string
80   (** Printing functions. *)
81
82 (** {2 List kernels in kerneldb} *)
83
84 val list_kernels : pathname -> info list
85   (** Return a list of all the kernels in the kerneldb at [path]. *)
86
87 (** {2 Load kernel structures} *)
88
89 val load_structures : info -> string list -> (string * structure) list
90   (** [load_structures info names] loads the named kernel structures
91       from a particular kernel.
92
93       The returned list is not necessarily in the same order, or the
94       same length, as the [names] list.  Check the first field in each
95       pair for the structure name.  Structures which don't actually
96       occur in the given kernel are not loaded and not present in the
97       final list.
98
99       The fields list in {!structure} is always sorted by field offset.
100   *)
101
102 (** {2 Transpose and check field types}
103
104     After we've used {!load_structures} for each kernel, we end
105     up with a list of kernels, and within that a list of structures
106     supported by the kernel.  What we really want is to see how
107     each structure changes over time, and also to check if field
108     types have changed between versions (which we currently disallow).
109
110     The {!transpose} operation transposes the original list
111     of kernels to a list of structures.
112
113     The {!get_fields} operation gets a complete list of fields
114     and their types, and checks that the types haven't changed over
115     kernel versions.  (Note that particular fields can be missing from
116     some kernel version, but that is OK).
117 *)
118
119 val transpose : string list ->
120   (info * (string * structure) list) list ->
121   (string * (info * structure) list) list
122   (** Transpose list of kernels to list of structures.  The result
123       shows, for each structure, how it changed over kernel versions.
124
125       The first parameter is the list of structure names of interest,
126       and should be the same as was passed to {!load_structures}. *)
127
128 val get_fields : (info * structure) list -> (string * f_type) list
129   (** This gets a complete list of fields which have appeared in
130       any kernel version, and the type of those fields.
131
132       Fields must not change type between kernel versions - if
133       so this function prints an error and exits. (We may support
134       fields which change type in future, but we don't right now).
135       "Type" is quite widely defined here, see {!f_type}, and so
136       certain changes such as between sizes of ints are allowed,
137       but you can't have a field which once was a pointer and then
138       became a string or anything like that.
139
140       Note that a field may not be present in particular kernel
141       versions, but if it appears at all in any version, then it
142       will be in the result list. *)