1 (** 'pahole' output parser. *)
2 (* Memory info command for virtual domains.
3 (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
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.
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.
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.
21 (** This parses the output of the pahole command, allowing us
22 to extract the layout of kernel structures for particular
25 Its primary input is the [*.info] and [*.data*] files found
26 in the [kernels/] subdirectory (ie. the kerneldb).
31 type pathname = string
32 (** Path and filenames. *)
35 kv_i : int; (** Each kernel is given a unique
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
43 (** Kernel metainformation, extracted from the [*.info] file. *)
46 struct_name : string; (** Structure name. *)
47 struct_total_size : int; (** Total size in bytes. *)
48 struct_fields : field list; (** Fields in the structure. *)
50 (** A kernel structure, eg. [task_struct]. *)
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). *)
58 (** A kernel structure field.
60 Note that nested fields are flattened with single quotes (')
61 between elements, so you get names like [tasks'next]. *)
64 | FStructPointer of string (** A pointer to a named struct. *)
65 | FVoidPointer (** A [void*] pointer. *)
66 | FAnonListHeadPointer (** A pointer to an unknown
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. *)
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. *)
82 (** {2 List kernels in kerneldb} *)
84 val list_kernels : pathname -> info list
85 (** Return a list of all the kernels in the kerneldb at [path]. *)
87 (** {2 Load kernel structures} *)
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.
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
99 The fields list in {!structure} is always sorted by field offset.
102 (** {2 Transpose and check field types}
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).
110 The {!transpose} operation transposes the original list
111 of kernels to a list of structures.
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).
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.
125 The first parameter is the list of structure names of interest,
126 and should be the same as was passed to {!load_structures}. *)
128 val get_fields : (info * structure) list -> (string * (f_type * bool)) list
129 (** This gets a complete list of fields which have appeared in
132 The return list contains [(field_name, (field_type,
133 always_present))] where [always_present] is a boolean flag which
134 is true if the field is present in every kernel version we
137 Fields must not change type between kernel versions - if
138 so this function prints an error and exits. (We may support
139 fields which change type in future, but we don't right now).
140 "Type" is quite widely defined here, see {!f_type}, and so
141 certain changes such as between sizes of ints are allowed,
142 but you can't have a field which once was a pointer and then
143 became a string or anything like that.
145 Note that a field may not be present in particular kernel
146 versions, but if it appears at all in any version, then it
147 will be in the result list. *)