1 # $OpenBSD: parse_structinfo.awk,v 1.1 2009/08/09 23:04:49 miod Exp $
3 # Copyright (c) 2009 Miodrag Vallat.
5 # Permission to use, copy, modify, and distribute this software for any
6 # purpose with or without fee is hereby granted, provided that the above
7 # copyright notice and this permission notice appear in all copies.
9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 # This ugly script parses the output of objdump -g in order to extract
19 # structure layout information, to be used by ddb.
21 # The output of this script is the following static data:
24 # - its size (individual element size if an array)
25 # - the number of elements in the array (1 if not)
26 # - its first and last field indexes
29 # - its offset and size
30 # - the index of the struct it is member of
31 # This allows fast struct -> field information retrieval.
33 # To retrieve information from a field size or offset, we also output
34 # the following reverse arrays:
35 # - for each offset, in ascending order, a variable length list of field
37 # - for each size, in ascending order, a variable length list of field
40 # The compromise here is that I want to minimize linear searches. Memory
41 # use is considered secondary, hence the back `pointer' to the struct in the
44 # No attempt is made to share name pointers when multiple fields share
45 # the same name. Rewriting this script in perl, or any other language
46 # with hash data structures, would be a good time to add this.
51 scnt =
0; # current struct count
52 sidx =
-1; # current struct index
53 # field index #0 is used as a sentinel.
54 fcnt =
1; # current field count
55 fidx =
0; # current field index
56 ocnt =
0; # current offset count
57 zcnt =
0; # current size count
65 sfieldmin
[sidx
] = fcnt
;
67 #printf("struct %d %s (size %d)\n", sidx, $2, $6);
73 if (fcnt == sfieldmin
[sidx
]) # empty struct, ignore it
76 sfieldmax
[sidx
] = fidx
;
111 # Bitfields are a PITA... From a ddb point of view, we can't really
112 # access storage units smaller than a byte.
113 # So we'll report all bitfields as having size 0, and the
114 # rounded down byte position where they start.
115 cursize = int
($
(NF - 3));
116 curoffs = int
($
(NF - 1) / 8);
117 if ((cursize %
8) != 0)
122 # try and gather the field name.
125 # anonymous union. discard it.
128 if (field ==
"*/);") {
129 field = $
(NF - 9); # function pointer
130 # remove enclosing braces
131 field =
substr(field
, 2, length(field
) - 2);
133 colon =
index(field
, ":");
135 field =
substr(field
, 1, colon
- 1);
136 else if (substr(field
, length(field
), 1) ==
";")
137 field =
substr(field
, 1, length(field
) - 1);
139 while (index(field
, "*") ==
1)
140 field =
substr(field
, 2);
142 # This could be an array. If it is, we need to trim the field
143 # name and update its size to a single member size.
144 obracket =
index(field
, "[");
145 cbracket =
index(field
, "]");
148 nitems =
substr(field
, obracket
, cbracket
- obracket
);
149 field =
substr(field
, 1, obracket
- 2);
156 foffs
[fidx
] = curoffs
;
157 fsize
[fidx
] = cursize
;
158 fitems
[fidx
] = nitems
;
159 fstruct
[fidx
] = sidx
;
161 #printf(" %s at %d len %d\n", field, curoffs, cursize);
163 # Remember size and offset if not found yet
165 for (i =
0; i
< ocnt
; i
++)
166 if (offs
[i
] == curoffs
)
170 for (i =
0; i
< ocnt
; i
++)
171 if (offs
[i
] > curoffs
)
174 for (j = ocnt
+ 1; j
> i
; j
--)
175 offs
[j
] = offs
[j
- 1];
181 for (i =
0; i
< zcnt
; i
++)
182 if (sizes
[i
] == cursize
)
186 for (i =
0; i
< zcnt
; i
++)
187 if (sizes
[i
] > cursize
)
190 for (j = zcnt
+ 1; j
> i
; j
--)
191 sizes
[j
] = sizes
[j
- 1];
199 printf(" * THIS IS A GENERATED FILE. DO NOT EDIT!\n");
202 printf("#include <sys/param.h>\n");
203 printf("#include <sys/types.h>\n");
206 # structure definitions
208 printf("struct ddb_struct_info {\n");
209 printf("\tconst char *name;\n");
210 printf("\tsize_t size;\n");
211 printf("\tuint fmin, fmax;\n");
214 printf("struct ddb_field_info {\n");
215 printf("\tconst char *name;\n");
216 printf("\tuint sidx;\n");
217 printf("\tsize_t offs;\n");
218 printf("\tsize_t size;\n");
219 printf("\tuint nitems;\n");
222 printf("struct ddb_field_offsets {\n");
223 printf("\tsize_t offs;\n");
224 printf("\tconst uint *list;\n");
227 printf("struct ddb_field_sizes {\n");
228 printf("\tsize_t size;\n");
229 printf("\tconst uint *list;\n");
234 printf("#define NSTRUCT %d\n", scnt
);
235 printf("static const struct ddb_struct_info ddb_struct_info[NSTRUCT] = {\n");
236 for (i =
0; i
< scnt
; i
++) {
237 printf("\t{ \"%s\", %d, %d, %d },\n",
238 sname
[i
], ssize
[i
], sfieldmin
[i
], sfieldmax
[i
]);
242 printf("#define NFIELD %d\n", fcnt
);
243 printf("static const struct ddb_field_info ddb_field_info[NFIELD] = {\n");
244 printf("\t{ NULL, 0, 0, 0 },\n");
245 for (i =
1; i
< fcnt
; i
++) {
246 printf("\t{ \"%s\", %d, %d, %d, %d },\n",
247 fname
[i
], fstruct
[i
], foffs
[i
], fsize
[i
], fitems
[i
]);
253 printf("static const uint ddb_fields_by_offset[] = {\n");
255 for (i =
0; i
< ocnt
; i
++) {
258 for (f =
1; f
< fcnt
; f
++)
259 if (foffs
[f
] == cmp
) {
278 printf("#define NOFFS %d\n", ocnt
);
279 printf("static const struct ddb_field_offsets ddb_field_offsets[NOFFS] = {\n");
280 for (i =
0; i
< ocnt
; i
++) {
281 printf("\t{ %d, ddb_fields_by_offset + %d },\n",
286 printf("static const uint ddb_fields_by_size[] = {\n");
288 for (i =
0; i
< zcnt
; i
++) {
291 for (f =
1; f
< fcnt
; f
++)
292 if (fsize
[f
] == cmp
) {
311 printf("#define NSIZES %d\n", zcnt
);
312 printf("static const struct ddb_field_sizes ddb_field_sizes[NSIZES] = {\n");
313 for (i =
0; i
< zcnt
; i
++) {
314 printf("\t{ %d, ddb_fields_by_size + %d },\n",