diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /scripts/genksyms/genksyms.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'scripts/genksyms/genksyms.c')
-rw-r--r-- | scripts/genksyms/genksyms.c | 591 |
1 files changed, 591 insertions, 0 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c new file mode 100644 index 000000000000..416a694b0998 --- /dev/null +++ b/scripts/genksyms/genksyms.c | |||
@@ -0,0 +1,591 @@ | |||
1 | /* Generate kernel symbol version hashes. | ||
2 | Copyright 1996, 1997 Linux International. | ||
3 | |||
4 | New implementation contributed by Richard Henderson <rth@tamu.edu> | ||
5 | Based on original work by Bjorn Ekwall <bj0rn@blox.se> | ||
6 | |||
7 | This file was part of the Linux modutils 2.4.22: moved back into the | ||
8 | kernel sources by Rusty Russell/Kai Germaschewski. | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify it | ||
11 | under the terms of the GNU General Public License as published by the | ||
12 | Free Software Foundation; either version 2 of the License, or (at your | ||
13 | option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, but | ||
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software Foundation, | ||
22 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
23 | |||
24 | #include <stdio.h> | ||
25 | #include <string.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <unistd.h> | ||
28 | #include <assert.h> | ||
29 | #include <stdarg.h> | ||
30 | #ifdef __GNU_LIBRARY__ | ||
31 | #include <getopt.h> | ||
32 | #endif /* __GNU_LIBRARY__ */ | ||
33 | |||
34 | #include "genksyms.h" | ||
35 | |||
36 | /*----------------------------------------------------------------------*/ | ||
37 | |||
38 | #define HASH_BUCKETS 4096 | ||
39 | |||
40 | static struct symbol *symtab[HASH_BUCKETS]; | ||
41 | FILE *debugfile; | ||
42 | |||
43 | int cur_line = 1; | ||
44 | char *cur_filename, *output_directory; | ||
45 | |||
46 | int flag_debug, flag_dump_defs, flag_warnings; | ||
47 | |||
48 | static int errors; | ||
49 | static int nsyms; | ||
50 | |||
51 | static struct symbol *expansion_trail; | ||
52 | |||
53 | static const char * const symbol_type_name[] = { | ||
54 | "normal", "typedef", "enum", "struct", "union" | ||
55 | }; | ||
56 | |||
57 | /*----------------------------------------------------------------------*/ | ||
58 | |||
59 | static const unsigned int crctab32[] = | ||
60 | { | ||
61 | 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, | ||
62 | 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, | ||
63 | 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, | ||
64 | 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, | ||
65 | 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, | ||
66 | 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, | ||
67 | 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, | ||
68 | 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, | ||
69 | 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, | ||
70 | 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, | ||
71 | 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, | ||
72 | 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, | ||
73 | 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, | ||
74 | 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, | ||
75 | 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, | ||
76 | 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, | ||
77 | 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, | ||
78 | 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, | ||
79 | 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, | ||
80 | 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, | ||
81 | 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, | ||
82 | 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, | ||
83 | 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, | ||
84 | 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, | ||
85 | 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, | ||
86 | 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, | ||
87 | 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, | ||
88 | 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, | ||
89 | 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, | ||
90 | 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, | ||
91 | 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, | ||
92 | 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, | ||
93 | 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, | ||
94 | 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, | ||
95 | 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, | ||
96 | 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, | ||
97 | 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, | ||
98 | 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, | ||
99 | 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, | ||
100 | 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, | ||
101 | 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, | ||
102 | 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, | ||
103 | 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, | ||
104 | 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, | ||
105 | 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, | ||
106 | 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, | ||
107 | 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, | ||
108 | 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, | ||
109 | 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, | ||
110 | 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, | ||
111 | 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, | ||
112 | 0x2d02ef8dU | ||
113 | }; | ||
114 | |||
115 | static inline unsigned long | ||
116 | partial_crc32_one(unsigned char c, unsigned long crc) | ||
117 | { | ||
118 | return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); | ||
119 | } | ||
120 | |||
121 | static inline unsigned long | ||
122 | partial_crc32(const char *s, unsigned long crc) | ||
123 | { | ||
124 | while (*s) | ||
125 | crc = partial_crc32_one(*s++, crc); | ||
126 | return crc; | ||
127 | } | ||
128 | |||
129 | static inline unsigned long | ||
130 | crc32(const char *s) | ||
131 | { | ||
132 | return partial_crc32(s, 0xffffffff) ^ 0xffffffff; | ||
133 | } | ||
134 | |||
135 | |||
136 | /*----------------------------------------------------------------------*/ | ||
137 | |||
138 | static inline enum symbol_type | ||
139 | map_to_ns(enum symbol_type t) | ||
140 | { | ||
141 | if (t == SYM_TYPEDEF) | ||
142 | t = SYM_NORMAL; | ||
143 | else if (t == SYM_UNION) | ||
144 | t = SYM_STRUCT; | ||
145 | return t; | ||
146 | } | ||
147 | |||
148 | struct symbol * | ||
149 | find_symbol(const char *name, enum symbol_type ns) | ||
150 | { | ||
151 | unsigned long h = crc32(name) % HASH_BUCKETS; | ||
152 | struct symbol *sym; | ||
153 | |||
154 | for (sym = symtab[h]; sym ; sym = sym->hash_next) | ||
155 | if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0) | ||
156 | break; | ||
157 | |||
158 | return sym; | ||
159 | } | ||
160 | |||
161 | struct symbol * | ||
162 | add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern) | ||
163 | { | ||
164 | unsigned long h = crc32(name) % HASH_BUCKETS; | ||
165 | struct symbol *sym; | ||
166 | |||
167 | for (sym = symtab[h]; sym ; sym = sym->hash_next) | ||
168 | if (map_to_ns(sym->type) == map_to_ns(type) | ||
169 | && strcmp(name, sym->name) == 0) | ||
170 | { | ||
171 | if (!equal_list(sym->defn, defn)) | ||
172 | error_with_pos("redefinition of %s", name); | ||
173 | return sym; | ||
174 | } | ||
175 | |||
176 | sym = xmalloc(sizeof(*sym)); | ||
177 | sym->name = name; | ||
178 | sym->type = type; | ||
179 | sym->defn = defn; | ||
180 | sym->expansion_trail = NULL; | ||
181 | sym->is_extern = is_extern; | ||
182 | |||
183 | sym->hash_next = symtab[h]; | ||
184 | symtab[h] = sym; | ||
185 | |||
186 | if (flag_debug) | ||
187 | { | ||
188 | fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name); | ||
189 | if (is_extern) | ||
190 | fputs("extern ", debugfile); | ||
191 | print_list(debugfile, defn); | ||
192 | fputs(">\n", debugfile); | ||
193 | } | ||
194 | |||
195 | ++nsyms; | ||
196 | return sym; | ||
197 | } | ||
198 | |||
199 | |||
200 | /*----------------------------------------------------------------------*/ | ||
201 | |||
202 | inline void | ||
203 | free_node(struct string_list *node) | ||
204 | { | ||
205 | free(node->string); | ||
206 | free(node); | ||
207 | } | ||
208 | |||
209 | void | ||
210 | free_list(struct string_list *s, struct string_list *e) | ||
211 | { | ||
212 | while (s != e) | ||
213 | { | ||
214 | struct string_list *next = s->next; | ||
215 | free_node(s); | ||
216 | s = next; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | inline struct string_list * | ||
221 | copy_node(struct string_list *node) | ||
222 | { | ||
223 | struct string_list *newnode; | ||
224 | |||
225 | newnode = xmalloc(sizeof(*newnode)); | ||
226 | newnode->string = xstrdup(node->string); | ||
227 | newnode->tag = node->tag; | ||
228 | |||
229 | return newnode; | ||
230 | } | ||
231 | |||
232 | struct string_list * | ||
233 | copy_list(struct string_list *s, struct string_list *e) | ||
234 | { | ||
235 | struct string_list *h, *p; | ||
236 | |||
237 | if (s == e) | ||
238 | return NULL; | ||
239 | |||
240 | p = h = copy_node(s); | ||
241 | while ((s = s->next) != e) | ||
242 | p = p->next = copy_node(s); | ||
243 | p->next = NULL; | ||
244 | |||
245 | return h; | ||
246 | } | ||
247 | |||
248 | int | ||
249 | equal_list(struct string_list *a, struct string_list *b) | ||
250 | { | ||
251 | while (a && b) | ||
252 | { | ||
253 | if (a->tag != b->tag || strcmp(a->string, b->string)) | ||
254 | return 0; | ||
255 | a = a->next; | ||
256 | b = b->next; | ||
257 | } | ||
258 | |||
259 | return !a && !b; | ||
260 | } | ||
261 | |||
262 | static inline void | ||
263 | print_node(FILE *f, struct string_list *list) | ||
264 | { | ||
265 | switch (list->tag) | ||
266 | { | ||
267 | case SYM_STRUCT: | ||
268 | putc('s', f); | ||
269 | goto printit; | ||
270 | case SYM_UNION: | ||
271 | putc('u', f); | ||
272 | goto printit; | ||
273 | case SYM_ENUM: | ||
274 | putc('e', f); | ||
275 | goto printit; | ||
276 | case SYM_TYPEDEF: | ||
277 | putc('t', f); | ||
278 | goto printit; | ||
279 | |||
280 | printit: | ||
281 | putc('#', f); | ||
282 | case SYM_NORMAL: | ||
283 | fputs(list->string, f); | ||
284 | break; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | void | ||
289 | print_list(FILE *f, struct string_list *list) | ||
290 | { | ||
291 | struct string_list **e, **b; | ||
292 | struct string_list *tmp, **tmp2; | ||
293 | int elem = 1; | ||
294 | |||
295 | if (list == NULL) | ||
296 | { | ||
297 | fputs("(nil)", f); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | tmp = list; | ||
302 | while((tmp = tmp->next) != NULL) | ||
303 | elem++; | ||
304 | |||
305 | b = alloca(elem * sizeof(*e)); | ||
306 | e = b + elem; | ||
307 | tmp2 = e - 1; | ||
308 | |||
309 | (*tmp2--) = list; | ||
310 | while((list = list->next) != NULL) | ||
311 | *(tmp2--) = list; | ||
312 | |||
313 | while (b != e) | ||
314 | { | ||
315 | print_node(f, *b++); | ||
316 | putc(' ', f); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | static unsigned long | ||
321 | expand_and_crc_list(struct string_list *list, unsigned long crc) | ||
322 | { | ||
323 | struct string_list **e, **b; | ||
324 | struct string_list *tmp, **tmp2; | ||
325 | int elem = 1; | ||
326 | |||
327 | if (!list) | ||
328 | return crc; | ||
329 | |||
330 | tmp = list; | ||
331 | while((tmp = tmp->next) != NULL) | ||
332 | elem++; | ||
333 | |||
334 | b = alloca(elem * sizeof(*e)); | ||
335 | e = b + elem; | ||
336 | tmp2 = e - 1; | ||
337 | |||
338 | *(tmp2--) = list; | ||
339 | while ((list = list->next) != NULL) | ||
340 | *(tmp2--) = list; | ||
341 | |||
342 | while (b != e) | ||
343 | { | ||
344 | struct string_list *cur; | ||
345 | struct symbol *subsym; | ||
346 | |||
347 | cur = *(b++); | ||
348 | switch (cur->tag) | ||
349 | { | ||
350 | case SYM_NORMAL: | ||
351 | if (flag_dump_defs) | ||
352 | fprintf(debugfile, "%s ", cur->string); | ||
353 | crc = partial_crc32(cur->string, crc); | ||
354 | crc = partial_crc32_one(' ', crc); | ||
355 | break; | ||
356 | |||
357 | case SYM_TYPEDEF: | ||
358 | subsym = find_symbol(cur->string, cur->tag); | ||
359 | if (subsym->expansion_trail) | ||
360 | { | ||
361 | if (flag_dump_defs) | ||
362 | fprintf(debugfile, "%s ", cur->string); | ||
363 | crc = partial_crc32(cur->string, crc); | ||
364 | crc = partial_crc32_one(' ', crc); | ||
365 | } | ||
366 | else | ||
367 | { | ||
368 | subsym->expansion_trail = expansion_trail; | ||
369 | expansion_trail = subsym; | ||
370 | crc = expand_and_crc_list(subsym->defn, crc); | ||
371 | } | ||
372 | break; | ||
373 | |||
374 | case SYM_STRUCT: | ||
375 | case SYM_UNION: | ||
376 | case SYM_ENUM: | ||
377 | subsym = find_symbol(cur->string, cur->tag); | ||
378 | if (!subsym) | ||
379 | { | ||
380 | struct string_list *n, *t = NULL; | ||
381 | |||
382 | error_with_pos("expand undefined %s %s", | ||
383 | symbol_type_name[cur->tag], cur->string); | ||
384 | |||
385 | n = xmalloc(sizeof(*n)); | ||
386 | n->string = xstrdup(symbol_type_name[cur->tag]); | ||
387 | n->tag = SYM_NORMAL; | ||
388 | n->next = t; | ||
389 | t = n; | ||
390 | |||
391 | n = xmalloc(sizeof(*n)); | ||
392 | n->string = xstrdup(cur->string); | ||
393 | n->tag = SYM_NORMAL; | ||
394 | n->next = t; | ||
395 | t = n; | ||
396 | |||
397 | n = xmalloc(sizeof(*n)); | ||
398 | n->string = xstrdup("{ UNKNOWN }"); | ||
399 | n->tag = SYM_NORMAL; | ||
400 | n->next = t; | ||
401 | |||
402 | subsym = add_symbol(cur->string, cur->tag, n, 0); | ||
403 | } | ||
404 | if (subsym->expansion_trail) | ||
405 | { | ||
406 | if (flag_dump_defs) | ||
407 | { | ||
408 | fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag], | ||
409 | cur->string); | ||
410 | } | ||
411 | |||
412 | crc = partial_crc32(symbol_type_name[cur->tag], crc); | ||
413 | crc = partial_crc32_one(' ', crc); | ||
414 | crc = partial_crc32(cur->string, crc); | ||
415 | crc = partial_crc32_one(' ', crc); | ||
416 | } | ||
417 | else | ||
418 | { | ||
419 | subsym->expansion_trail = expansion_trail; | ||
420 | expansion_trail = subsym; | ||
421 | crc = expand_and_crc_list(subsym->defn, crc); | ||
422 | } | ||
423 | break; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | return crc; | ||
428 | } | ||
429 | |||
430 | void | ||
431 | export_symbol(const char *name) | ||
432 | { | ||
433 | struct symbol *sym; | ||
434 | |||
435 | sym = find_symbol(name, SYM_NORMAL); | ||
436 | if (!sym) | ||
437 | error_with_pos("export undefined symbol %s", name); | ||
438 | else | ||
439 | { | ||
440 | unsigned long crc; | ||
441 | |||
442 | if (flag_dump_defs) | ||
443 | fprintf(debugfile, "Export %s == <", name); | ||
444 | |||
445 | expansion_trail = (struct symbol *)-1L; | ||
446 | |||
447 | crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; | ||
448 | |||
449 | sym = expansion_trail; | ||
450 | while (sym != (struct symbol *)-1L) | ||
451 | { | ||
452 | struct symbol *n = sym->expansion_trail; | ||
453 | sym->expansion_trail = 0; | ||
454 | sym = n; | ||
455 | } | ||
456 | |||
457 | if (flag_dump_defs) | ||
458 | fputs(">\n", debugfile); | ||
459 | |||
460 | /* Used as a linker script. */ | ||
461 | printf("__crc_%s = 0x%08lx ;\n", name, crc); | ||
462 | } | ||
463 | } | ||
464 | |||
465 | /*----------------------------------------------------------------------*/ | ||
466 | |||
467 | void | ||
468 | error(const char *fmt, ...) | ||
469 | { | ||
470 | va_list args; | ||
471 | |||
472 | if (flag_warnings) | ||
473 | { | ||
474 | va_start(args, fmt); | ||
475 | vfprintf(stderr, fmt, args); | ||
476 | va_end(args); | ||
477 | putc('\n', stderr); | ||
478 | |||
479 | errors++; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | void | ||
484 | error_with_pos(const char *fmt, ...) | ||
485 | { | ||
486 | va_list args; | ||
487 | |||
488 | if (flag_warnings) | ||
489 | { | ||
490 | fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line); | ||
491 | |||
492 | va_start(args, fmt); | ||
493 | vfprintf(stderr, fmt, args); | ||
494 | va_end(args); | ||
495 | putc('\n', stderr); | ||
496 | |||
497 | errors++; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | |||
502 | void genksyms_usage(void) | ||
503 | { | ||
504 | fputs("Usage:\n" | ||
505 | "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" | ||
506 | "\n" | ||
507 | #ifdef __GNU_LIBRARY__ | ||
508 | " -d, --debug Increment the debug level (repeatable)\n" | ||
509 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" | ||
510 | " -w, --warnings Enable warnings\n" | ||
511 | " -q, --quiet Disable warnings (default)\n" | ||
512 | " -h, --help Print this message\n" | ||
513 | " -V, --version Print the release version\n" | ||
514 | #else /* __GNU_LIBRARY__ */ | ||
515 | " -d Increment the debug level (repeatable)\n" | ||
516 | " -D Dump expanded symbol defs (for debugging only)\n" | ||
517 | " -w Enable warnings\n" | ||
518 | " -q Disable warnings (default)\n" | ||
519 | " -h Print this message\n" | ||
520 | " -V Print the release version\n" | ||
521 | #endif /* __GNU_LIBRARY__ */ | ||
522 | , stderr); | ||
523 | } | ||
524 | |||
525 | int | ||
526 | main(int argc, char **argv) | ||
527 | { | ||
528 | int o; | ||
529 | |||
530 | #ifdef __GNU_LIBRARY__ | ||
531 | struct option long_opts[] = { | ||
532 | {"debug", 0, 0, 'd'}, | ||
533 | {"warnings", 0, 0, 'w'}, | ||
534 | {"quiet", 0, 0, 'q'}, | ||
535 | {"dump", 0, 0, 'D'}, | ||
536 | {"version", 0, 0, 'V'}, | ||
537 | {"help", 0, 0, 'h'}, | ||
538 | {0, 0, 0, 0} | ||
539 | }; | ||
540 | |||
541 | while ((o = getopt_long(argc, argv, "dwqVDk:p:", | ||
542 | &long_opts[0], NULL)) != EOF) | ||
543 | #else /* __GNU_LIBRARY__ */ | ||
544 | while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF) | ||
545 | #endif /* __GNU_LIBRARY__ */ | ||
546 | switch (o) | ||
547 | { | ||
548 | case 'd': | ||
549 | flag_debug++; | ||
550 | break; | ||
551 | case 'w': | ||
552 | flag_warnings = 1; | ||
553 | break; | ||
554 | case 'q': | ||
555 | flag_warnings = 0; | ||
556 | break; | ||
557 | case 'V': | ||
558 | fputs("genksyms version 2.5.60\n", stderr); | ||
559 | break; | ||
560 | case 'D': | ||
561 | flag_dump_defs = 1; | ||
562 | break; | ||
563 | case 'h': | ||
564 | genksyms_usage(); | ||
565 | return 0; | ||
566 | default: | ||
567 | genksyms_usage(); | ||
568 | return 1; | ||
569 | } | ||
570 | |||
571 | { | ||
572 | extern int yydebug; | ||
573 | extern int yy_flex_debug; | ||
574 | |||
575 | yydebug = (flag_debug > 1); | ||
576 | yy_flex_debug = (flag_debug > 2); | ||
577 | |||
578 | debugfile = stderr; | ||
579 | /* setlinebuf(debugfile); */ | ||
580 | } | ||
581 | |||
582 | yyparse(); | ||
583 | |||
584 | if (flag_debug) | ||
585 | { | ||
586 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | ||
587 | nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS); | ||
588 | } | ||
589 | |||
590 | return errors != 0; | ||
591 | } | ||