1 (* Memory info command for virtual domains.
2 (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 module PP = Pahole_parser
27 type f_class = ShapeField | ContentField
29 let classify_field names = function
30 | (PP.FStructPointer struct_name | PP.FListHeadPointer struct_name)
31 when List.mem struct_name names -> ShapeField
32 (* .. anything else is a content field: *)
34 | PP.FListHeadPointer _
36 | PP.FAnonListHeadPointer
38 | PP.FString _ -> ContentField
40 type shape_field_struct = {
43 sf_fields : PP.field list;
46 and content_field_struct = {
49 cf_fields : PP.field list;
55 pa_endian : Bitstring.endian;
56 pa_fields : Pahole_parser.field list;
57 pa_shape_field_struct : shape_field_struct;
58 pa_content_field_struct : content_field_struct;
61 and sfhash = (string, shape_field_struct) Hashtbl.t
62 and cfhash = (string, content_field_struct) Hashtbl.t
63 and pahash = (string, parser_) Hashtbl.t
65 let endian_of_architecture arch =
66 if String.starts_with arch "i386" ||
67 String.starts_with arch "i486" ||
68 String.starts_with arch "i586" ||
69 String.starts_with arch "i686" ||
70 String.starts_with arch "x86_64" ||
71 String.starts_with arch "x86-64" then
72 Bitstring.LittleEndian
73 else if String.starts_with arch "ia64" then
74 Bitstring.LittleEndian (* XXX usually? *)
75 else if String.starts_with arch "ppc" then
77 else if String.starts_with arch "sparc" then
80 failwith (sprintf "endian_of_architecture: cannot parse %S" arch)
87 (* Minimization of shape fields & content fields. *)
89 let cmp { PP.field_name = n1 } { PP.field_name = n2 } = compare n1 n2
91 let hash_values h = Hashtbl.fold (fun _ v vs -> v :: vs) h []
93 let minimize_shape_field_structs struct_name names kernels =
94 let h = Hashtbl.create 13 in
95 let rh = Hashtbl.create 13 in
97 let only_shape_fields =
99 fun { PP.field_type = typ } ->
100 classify_field names typ = ShapeField
104 let name_of i = sprintf "%s_shape_fields_%d" struct_name i in
107 fun ({ PP.kernel_version = version },
108 { PP.struct_fields = fields; struct_name = name_check }) ->
109 assert (struct_name = name_check);
110 let fields = List.sort ~cmp (only_shape_fields fields) in
111 let key = List.map (fun { PP.field_name = name } -> name) fields in
113 try Hashtbl.find h key
116 let sf = { sf_i = i; sf_name = name_of i; sf_fields = fields } in
117 Hashtbl.add h key sf;
119 Hashtbl.add rh version sf
122 let sfs = hash_values h in
125 let minimize_content_field_structs struct_name names kernels =
126 let h = Hashtbl.create 13 in
127 let rh = Hashtbl.create 13 in
129 let only_content_fields =
131 fun { PP.field_type = typ } ->
132 classify_field names typ = ContentField
136 let name_of i = sprintf "%s_content_fields_%d" struct_name i in
139 fun ({ PP.kernel_version = version },
140 { PP.struct_fields = fields; struct_name = name_check }) ->
141 assert (struct_name = name_check);
142 let fields = List.sort ~cmp (only_content_fields fields) in
143 let key = List.map (fun { PP.field_name = name } -> name) fields in
145 try Hashtbl.find h key
148 let cf = { cf_i = i; cf_name = name_of i; cf_fields = fields } in
149 Hashtbl.add h key cf;
151 Hashtbl.add rh version cf
154 let cfs = hash_values h in
157 let minimize_parsers struct_name kernels sfhash cfhash =
158 let h = Hashtbl.create 13 in
159 let rh = Hashtbl.create 13 in
161 let name_of i = sprintf "%s_parser_%d" struct_name i in
164 fun ({ PP.kernel_version = version; arch = arch },
165 { PP.struct_fields = fields; struct_name = name_check }) ->
166 assert (struct_name = name_check);
167 let endian = endian_of_architecture arch in
168 let key = endian, fields in
170 try Hashtbl.find h key
174 try Hashtbl.find sfhash version
175 with Not_found -> assert false in
177 try Hashtbl.find cfhash version
178 with Not_found -> assert false in
179 let pa = { pa_i = i; pa_name = name_of i; pa_fields = fields;
181 pa_shape_field_struct = sf;
182 pa_content_field_struct = cf } in
183 Hashtbl.add h key pa;
185 Hashtbl.add rh version pa
188 let pas = hash_values h in