1 (** Structure classification. *)
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.
24 There's no getting around it, this is complicated.
26 {!Pahole_parser} has parsed in a limited set of structures from
27 each available kernel. We now aim to take a holistic view of
28 a structure as it changed over time, though different kernel
29 versions and also on different architectures.
31 {3 Shape fields and content fields}
33 A structure is a list of fields.
35 Fields fall into two classifications, as far as we are interested:
37 (i) 'Shape' fields define the relationship between different
38 structures. Shape fields are all pointers to other structures
39 that we care about. They have type {!Pahole_parser.FStructPointer}
40 and {!Pahole_parser.FListHeadPointer}.
42 (ii) 'Content' fields are fields in a structure that contain
43 some data, like ints and strings. (In the current implementation,
44 it's anything left which isn't a shape field).
46 So we can easily take a structure and place its fields into two
47 buckets. For example, with [task_struct] it might be:
49 [task_struct] shape fields:
50 - [tasks'next] (the linked list of tasks)
52 - [parent] (points to the parent task)
54 [task_struct] content fields:
59 {3 Shape fields and iterator functions}
61 For each kernel/structure we can build a list of shape fields, but
62 in fact in many kernels they will be the same, so we also
63 performing a {i sharing} operation to minimize the number of
66 We also write (by hand) iterator functions. These iterator
67 functions are matched to the corresponding shape field structure,
68 by setting up some prerequisites that the function needs, then
69 matching on those prerequisites with the available shape
72 {3 Content fields and printing functions}
74 The same (minimization & matching) applies to hand-written printing
75 functions over content field structures.
77 {3 Generated parsing functions}
79 A third form of minimization is required to find kernel
80 structures which happen to be similar - ie. all the fields
81 happen to be in the same place, with the same wordsize and
84 We can then generate a minimal set of parsing functions which
85 map the binary data from the kernel image into shape and
86 content field structures.
88 {3 Generated loading code}
90 Finally, we generate recursive loading code which recurses over
91 structures into order to load the kernel memory and invoke the
92 correct parsers on it, ensuring that when the program runs, all
93 known kernel structures are recursively reached and loaded in.
96 (** {2 Field classification} *)
98 type f_class = ShapeField | ContentField
100 val classify_field : string list -> Pahole_parser.f_type -> f_class
101 (** [classify_field names field] classifies a field as either
102 a shape field or a content field. [names] is a list of
103 all kernel structures that we care about. *)
105 (** {2 Minimization of shape field structures and content field structures} *)
107 type shape_field_struct = {
108 sf_i : int; (** Unique number. *)
109 sf_name : string; (** Structure name in output. *)
110 sf_fields : Pahole_parser.field list; (** Shape fields. *)
112 (** The type of a shape field structure. *)
114 and content_field_struct = {
115 cf_i : int; (** Unique number. *)
116 cf_name : string; (** Structure name in output. *)
117 cf_fields : Pahole_parser.field list; (** Content fields. *)
119 (** The type of a content field structure. *)
121 val minimize_shape_field_structs :
122 string -> string list ->
123 (Pahole_parser.info * Pahole_parser.structure) list ->
124 shape_field_struct list * (string, shape_field_struct) Hashtbl.t
125 (** [minimize_shape_field_structs struct_name names kernels] returns
126 a minimized list of shape field structures
127 (a hash table of kernel version to {!shape_field_struct}).
129 [struct_name] is the name of the structure.
131 [names] is the list of interesting kernel structures. *)
133 val minimize_content_field_structs :
134 string -> string list ->
135 (Pahole_parser.info * Pahole_parser.structure) list ->
136 content_field_struct list * (string, content_field_struct) Hashtbl.t
137 (** [minimize_content_field_structs struct_name names kernels] returns
138 a minimized list of content field structures
139 (a hash table of kernel version to {!content_field_struct}).
141 [struct_name] is the name of the structure.
143 [names] is the list of interesting kernel structures. *)
145 (** {2 Minimization of parsers} *)
147 type parser_ (* parser is a reserved word *) = {
148 pa_i : int; (** Unique number. *)
149 pa_name : string; (** Parser function name in output. *)
150 (* The input to the parser: *)
151 pa_endian : Bitstring.endian; (** Default field endianness. *)
152 pa_fields : Pahole_parser.field list; (** All fields. *)
153 (* The output of the parser: *)
154 pa_shape_field_struct : shape_field_struct;
155 pa_content_field_struct : content_field_struct;
157 (** The type of a parser. *)
159 val minimize_parsers :
161 (Pahole_parser.info * Pahole_parser.structure) list ->
162 (string, shape_field_struct) Hashtbl.t ->
163 (string, content_field_struct) Hashtbl.t ->
164 parser_ list * (string, parser_) Hashtbl.t
165 (** [minimize_parsers struct_name kernels sfhash cfhash] returns
166 a minimized list of parsers (a hash table of kernel version
169 [sfhash] and [cfhash] are the kernel version -> shape/content
170 field struct hashes returned by a previous call to
171 {!minimize_shape_field_structs} and {!minimize_content_field_structs}