Stupid bug - extract the content fields correctly.
[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   kernel_version : string;             (** Kernel version that this matches. *)
36   arch : string;                       (** Architecture, eg. "i686", "ppc64". *)
37   basename : string;                   (** [basename.info] is the info
38                                            file and [basename.data*] is
39                                            the data file. *)
40 }
41   (** Kernel metainformation, extracted from the [*.info] file. *)
42
43 type structure = {
44   struct_name : string;                 (** Structure name. *)
45   struct_total_size : int;              (** Total size in bytes. *)
46   struct_fields : field list;           (** Fields in the structure. *)
47 }
48   (** A kernel structure, eg. [task_struct]. *)
49
50 and field = {
51   field_name : string;                  (** Field name. *)
52   field_type : f_type;                  (** Field type. *)
53   field_offset : int;                   (** Offset within the structure. *)
54   field_size : int;                     (** Size of the field (bytes). *)
55 }
56   (** A kernel structure field.
57
58       Note that nested fields are flattened with single quotes (')
59       between elements, so you get names like [tasks'next]. *)
60
61 and f_type =
62   | FStructPointer of string            (** A pointer to a named struct. *)
63   | FVoidPointer                        (** A [void*] pointer. *)
64   | FAnonListHeadPointer                (** A pointer to an unknown
65                                             [list_head]. *)
66   | FListHeadPointer of (string * string) option
67       (** A pointer to a [list_head].  If the value is not [None] then
68           this relates to another named struct/field, else it relates
69           to this struct/field. *)
70   | FInteger                            (** An integer. *)
71   | FString of int                      (** A char array of given width. *)
72   (** Type of a kernel field. *)
73
74 val string_of_info : info -> string
75 val string_of_structure : structure -> string
76 val string_of_field : field -> string
77 val string_of_f_type : f_type -> string
78   (** Printing functions. *)
79
80 (** {2 List kernels in kerneldb} *)
81
82 val list_kernels : pathname -> info list
83   (** Return a list of all the kernels in the kerneldb at [path]. *)
84
85 (** {2 Load kernel structures} *)
86
87 val load_structures : info -> string list -> (string * structure) list
88   (** [load_structures info names] loads the named kernel structures
89       from a particular kernel.
90
91       The returned list is not necessarily in the same order, or the
92       same length, as the [names] list.  Check the first field in each
93       pair for the structure name.  Structures which don't actually
94       occur in the given kernel are not loaded and not present in the
95       final list.
96
97       The fields list in {!structure} is always sorted by field offset.
98   *)
99
100 (** {2 Transpose and check field types}
101
102     After we've used {!load_structures} for each kernel, we end
103     up with a list of kernels, and within that a list of structures
104     supported by the kernel.  What we really want is to see how
105     each structure changes over time, and also to check if field
106     types have changed between versions (which we currently disallow).
107
108     The {!transpose} operation transposes the original list
109     of kernels to a list of structures.
110
111     The {!get_fields} operation gets a complete list of fields
112     and their types, and checks that the types haven't changed over
113     kernel versions.  (Note that particular fields can be missing from
114     some kernel version, but that is OK).
115 *)
116
117 val transpose : string list ->
118   (info * (string * structure) list) list ->
119   (string * (info * structure) list) list
120   (** Transpose list of kernels to list of structures.  The result
121       shows, for each structure, how it changed over kernel versions.
122
123       The first parameter is the list of structure names of interest,
124       and should be the same as was passed to {!load_structures}. *)
125
126 val get_fields : (info * structure) list -> (string * f_type) list
127   (** This gets a complete list of fields which have appeared in
128       any kernel version, and the type of those fields.
129
130       Fields must not change type between kernel versions - if
131       so this function prints an error and exits. (We may support
132       fields which change type in future, but we don't right now).
133       "Type" is quite widely defined here, see {!f_type}, and so
134       certain changes such as between sizes of ints are allowed,
135       but you can't have a field which once was a pointer and then
136       became a string or anything like that.
137
138       Note that a field may not be present in particular kernel
139       versions, but if it appears at all in any version, then it
140       will be in the result list. *)