genksyms: track symbol checksum changes
[deliverable/linux.git] / scripts / genksyms / genksyms.c
CommitLineData
1da177e4
LT
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>
78c04153 32#endif /* __GNU_LIBRARY__ */
1da177e4
LT
33
34#include "genksyms.h"
1da177e4
LT
35/*----------------------------------------------------------------------*/
36
37#define HASH_BUCKETS 4096
38
39static struct symbol *symtab[HASH_BUCKETS];
ce560686 40static FILE *debugfile;
1da177e4
LT
41
42int cur_line = 1;
ce560686 43char *cur_filename;
1da177e4 44
64e6c1e1
AG
45static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
46 flag_preserve, flag_warnings;
ce560686
SR
47static const char *arch = "";
48static const char *mod_prefix = "";
1da177e4
LT
49
50static int errors;
51static int nsyms;
52
53static struct symbol *expansion_trail;
15fde675 54static struct symbol *visited_symbols;
1da177e4 55
78c04153
SR
56static const char *const symbol_type_name[] = {
57 "normal", "typedef", "enum", "struct", "union"
1da177e4
LT
58};
59
ce560686
SR
60static int equal_list(struct string_list *a, struct string_list *b);
61static void print_list(FILE * f, struct string_list *list);
64e6c1e1
AG
62static void print_location(void);
63static void print_type_name(enum symbol_type type, const char *name);
ce560686 64
1da177e4
LT
65/*----------------------------------------------------------------------*/
66
78c04153
SR
67static const unsigned int crctab32[] = {
68 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
69 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
70 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
71 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
72 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
73 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
74 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
75 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
76 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
77 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
78 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
79 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
80 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
81 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
82 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
83 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
84 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
85 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
86 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
87 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
88 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
89 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
90 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
91 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
92 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
93 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
94 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
95 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
96 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
97 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
98 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
99 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
100 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
101 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
102 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
103 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
104 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
105 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
106 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
107 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
108 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
109 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
110 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
111 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
112 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
113 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
114 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
115 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
116 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
117 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
118 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
119 0x2d02ef8dU
1da177e4
LT
120};
121
ce560686 122static unsigned long partial_crc32_one(unsigned char c, unsigned long crc)
1da177e4 123{
78c04153 124 return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
1da177e4
LT
125}
126
ce560686 127static unsigned long partial_crc32(const char *s, unsigned long crc)
1da177e4 128{
78c04153
SR
129 while (*s)
130 crc = partial_crc32_one(*s++, crc);
131 return crc;
1da177e4
LT
132}
133
ce560686 134static unsigned long crc32(const char *s)
1da177e4 135{
78c04153 136 return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
1da177e4
LT
137}
138
1da177e4
LT
139/*----------------------------------------------------------------------*/
140
ce560686 141static enum symbol_type map_to_ns(enum symbol_type t)
1da177e4 142{
78c04153
SR
143 if (t == SYM_TYPEDEF)
144 t = SYM_NORMAL;
145 else if (t == SYM_UNION)
146 t = SYM_STRUCT;
147 return t;
1da177e4
LT
148}
149
78c04153 150struct symbol *find_symbol(const char *name, enum symbol_type ns)
1da177e4 151{
78c04153
SR
152 unsigned long h = crc32(name) % HASH_BUCKETS;
153 struct symbol *sym;
1da177e4 154
78c04153 155 for (sym = symtab[h]; sym; sym = sym->hash_next)
ce560686 156 if (map_to_ns(sym->type) == map_to_ns(ns) &&
64e6c1e1
AG
157 strcmp(name, sym->name) == 0 &&
158 sym->is_declared)
78c04153 159 break;
1da177e4 160
78c04153 161 return sym;
1da177e4
LT
162}
163
64e6c1e1
AG
164static int is_unknown_symbol(struct symbol *sym)
165{
166 struct string_list *defn;
167
168 return ((sym->type == SYM_STRUCT ||
169 sym->type == SYM_UNION ||
170 sym->type == SYM_ENUM) &&
171 (defn = sym->defn) && defn->tag == SYM_NORMAL &&
172 strcmp(defn->string, "}") == 0 &&
173 (defn = defn->next) && defn->tag == SYM_NORMAL &&
174 strcmp(defn->string, "UNKNOWN") == 0 &&
175 (defn = defn->next) && defn->tag == SYM_NORMAL &&
176 strcmp(defn->string, "{") == 0);
177}
178
179struct symbol *__add_symbol(const char *name, enum symbol_type type,
180 struct string_list *defn, int is_extern,
181 int is_reference)
1da177e4 182{
78c04153
SR
183 unsigned long h = crc32(name) % HASH_BUCKETS;
184 struct symbol *sym;
64e6c1e1 185 enum symbol_status status = STATUS_UNCHANGED;
78c04153 186
ce560686 187 for (sym = symtab[h]; sym; sym = sym->hash_next) {
64e6c1e1
AG
188 if (map_to_ns(sym->type) == map_to_ns(type) &&
189 strcmp(name, sym->name) == 0) {
190 if (is_reference)
191 /* fall through */ ;
192 else if (sym->type == type &&
193 equal_list(sym->defn, defn)) {
194 sym->is_declared = 1;
195 return sym;
196 } else if (!sym->is_declared) {
197 status = is_unknown_symbol(sym) ?
198 STATUS_DEFINED : STATUS_MODIFIED;
199 } else {
78c04153 200 error_with_pos("redefinition of %s", name);
64e6c1e1
AG
201 return sym;
202 }
203 break;
78c04153 204 }
ce560686 205 }
78c04153 206
64e6c1e1
AG
207 if (sym) {
208 struct symbol **psym;
209
210 for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) {
211 if (*psym == sym) {
212 *psym = sym->hash_next;
213 break;
214 }
215 }
216 --nsyms;
217 }
218
78c04153
SR
219 sym = xmalloc(sizeof(*sym));
220 sym->name = name;
221 sym->type = type;
222 sym->defn = defn;
223 sym->expansion_trail = NULL;
15fde675 224 sym->visited = NULL;
78c04153
SR
225 sym->is_extern = is_extern;
226
227 sym->hash_next = symtab[h];
228 symtab[h] = sym;
229
64e6c1e1
AG
230 sym->is_declared = !is_reference;
231 sym->status = status;
232
78c04153
SR
233 if (flag_debug) {
234 fprintf(debugfile, "Defn for %s %s == <",
235 symbol_type_name[type], name);
236 if (is_extern)
237 fputs("extern ", debugfile);
238 print_list(debugfile, defn);
239 fputs(">\n", debugfile);
240 }
241
242 ++nsyms;
1da177e4 243 return sym;
1da177e4
LT
244}
245
64e6c1e1
AG
246struct symbol *add_symbol(const char *name, enum symbol_type type,
247 struct string_list *defn, int is_extern)
248{
249 return __add_symbol(name, type, defn, is_extern, 0);
250}
251
252struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
253 struct string_list *defn, int is_extern)
254{
255 return __add_symbol(name, type, defn, is_extern, 1);
256}
257
1da177e4
LT
258/*----------------------------------------------------------------------*/
259
ce560686 260void free_node(struct string_list *node)
1da177e4 261{
78c04153
SR
262 free(node->string);
263 free(node);
1da177e4
LT
264}
265
78c04153 266void free_list(struct string_list *s, struct string_list *e)
1da177e4 267{
78c04153
SR
268 while (s != e) {
269 struct string_list *next = s->next;
270 free_node(s);
271 s = next;
272 }
1da177e4
LT
273}
274
ce560686 275struct string_list *copy_node(struct string_list *node)
1da177e4 276{
78c04153 277 struct string_list *newnode;
1da177e4 278
78c04153
SR
279 newnode = xmalloc(sizeof(*newnode));
280 newnode->string = xstrdup(node->string);
281 newnode->tag = node->tag;
1da177e4 282
78c04153 283 return newnode;
1da177e4
LT
284}
285
ce560686 286static int equal_list(struct string_list *a, struct string_list *b)
1da177e4 287{
78c04153
SR
288 while (a && b) {
289 if (a->tag != b->tag || strcmp(a->string, b->string))
290 return 0;
291 a = a->next;
292 b = b->next;
293 }
1da177e4 294
78c04153 295 return !a && !b;
1da177e4
LT
296}
297
64e6c1e1
AG
298#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
299
300struct string_list *read_node(FILE *f)
301{
302 char buffer[256];
303 struct string_list node = {
304 .string = buffer,
305 .tag = SYM_NORMAL };
306 int c;
307
308 while ((c = fgetc(f)) != EOF) {
309 if (c == ' ') {
310 if (node.string == buffer)
311 continue;
312 break;
313 } else if (c == '\n') {
314 if (node.string == buffer)
315 return NULL;
316 ungetc(c, f);
317 break;
318 }
319 if (node.string >= buffer + sizeof(buffer) - 1) {
320 fprintf(stderr, "Token too long\n");
321 exit(1);
322 }
323 *node.string++ = c;
324 }
325 if (node.string == buffer)
326 return NULL;
327 *node.string = 0;
328 node.string = buffer;
329
330 if (node.string[1] == '#') {
331 int n;
332
333 for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) {
334 if (node.string[0] == symbol_type_name[n][0]) {
335 node.tag = n;
336 node.string += 2;
337 return copy_node(&node);
338 }
339 }
340 fprintf(stderr, "Unknown type %c\n", node.string[0]);
341 exit(1);
342 }
343 return copy_node(&node);
344}
345
346static void read_reference(FILE *f)
347{
348 while (!feof(f)) {
349 struct string_list *defn = NULL;
350 struct string_list *sym, *def;
351 int is_extern = 0;
352
353 sym = read_node(f);
354 if (!sym)
355 continue;
356 def = read_node(f);
357 if (def && def->tag == SYM_NORMAL &&
358 !strcmp(def->string, "extern")) {
359 is_extern = 1;
360 free_node(def);
361 def = read_node(f);
362 }
363 while (def) {
364 def->next = defn;
365 defn = def;
366 def = read_node(f);
367 }
368 add_reference_symbol(xstrdup(sym->string), sym->tag,
369 defn, is_extern);
370 free_node(sym);
371 }
372}
373
ce560686 374static void print_node(FILE * f, struct string_list *list)
1da177e4 375{
15fde675
AG
376 if (list->tag != SYM_NORMAL) {
377 putc(symbol_type_name[list->tag][0], f);
78c04153 378 putc('#', f);
78c04153 379 }
15fde675 380 fputs(list->string, f);
1da177e4
LT
381}
382
ce560686 383static void print_list(FILE * f, struct string_list *list)
1da177e4 384{
78c04153
SR
385 struct string_list **e, **b;
386 struct string_list *tmp, **tmp2;
387 int elem = 1;
1da177e4 388
78c04153
SR
389 if (list == NULL) {
390 fputs("(nil)", f);
391 return;
392 }
1da177e4 393
78c04153
SR
394 tmp = list;
395 while ((tmp = tmp->next) != NULL)
396 elem++;
1da177e4 397
78c04153
SR
398 b = alloca(elem * sizeof(*e));
399 e = b + elem;
400 tmp2 = e - 1;
1da177e4 401
78c04153
SR
402 (*tmp2--) = list;
403 while ((list = list->next) != NULL)
404 *(tmp2--) = list;
1da177e4 405
78c04153
SR
406 while (b != e) {
407 print_node(f, *b++);
408 putc(' ', f);
409 }
410}
1da177e4 411
15fde675 412static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
78c04153 413{
15fde675 414 struct string_list *list = sym->defn;
78c04153
SR
415 struct string_list **e, **b;
416 struct string_list *tmp, **tmp2;
417 int elem = 1;
418
419 if (!list)
420 return crc;
421
422 tmp = list;
423 while ((tmp = tmp->next) != NULL)
424 elem++;
425
426 b = alloca(elem * sizeof(*e));
427 e = b + elem;
428 tmp2 = e - 1;
429
430 *(tmp2--) = list;
431 while ((list = list->next) != NULL)
432 *(tmp2--) = list;
433
434 while (b != e) {
435 struct string_list *cur;
436 struct symbol *subsym;
437
438 cur = *(b++);
439 switch (cur->tag) {
440 case SYM_NORMAL:
441 if (flag_dump_defs)
442 fprintf(debugfile, "%s ", cur->string);
443 crc = partial_crc32(cur->string, crc);
444 crc = partial_crc32_one(' ', crc);
445 break;
446
447 case SYM_TYPEDEF:
448 subsym = find_symbol(cur->string, cur->tag);
64e6c1e1 449 /* FIXME: Bad reference files can segfault here. */
78c04153
SR
450 if (subsym->expansion_trail) {
451 if (flag_dump_defs)
452 fprintf(debugfile, "%s ", cur->string);
453 crc = partial_crc32(cur->string, crc);
454 crc = partial_crc32_one(' ', crc);
455 } else {
456 subsym->expansion_trail = expansion_trail;
457 expansion_trail = subsym;
15fde675 458 crc = expand_and_crc_sym(subsym, crc);
78c04153
SR
459 }
460 break;
461
462 case SYM_STRUCT:
463 case SYM_UNION:
464 case SYM_ENUM:
465 subsym = find_symbol(cur->string, cur->tag);
466 if (!subsym) {
467 struct string_list *n, *t = NULL;
468
469 error_with_pos("expand undefined %s %s",
470 symbol_type_name[cur->tag],
471 cur->string);
472
473 n = xmalloc(sizeof(*n));
474 n->string = xstrdup(symbol_type_name[cur->tag]);
475 n->tag = SYM_NORMAL;
476 n->next = t;
477 t = n;
478
479 n = xmalloc(sizeof(*n));
480 n->string = xstrdup(cur->string);
481 n->tag = SYM_NORMAL;
482 n->next = t;
483 t = n;
484
485 n = xmalloc(sizeof(*n));
64e6c1e1 486 n->string = xstrdup("{");
78c04153
SR
487 n->tag = SYM_NORMAL;
488 n->next = t;
64e6c1e1
AG
489 t = n;
490
491 n = xmalloc(sizeof(*n));
492 n->string = xstrdup("UNKNOWN");
493 n->tag = SYM_NORMAL;
494 n->next = t;
495 t = n;
496
497 n = xmalloc(sizeof(*n));
498 n->string = xstrdup("}");
499 n->tag = SYM_NORMAL;
500 n->next = t;
501 t = n;
78c04153
SR
502
503 subsym =
504 add_symbol(cur->string, cur->tag, n, 0);
505 }
506 if (subsym->expansion_trail) {
507 if (flag_dump_defs) {
508 fprintf(debugfile, "%s %s ",
509 symbol_type_name[cur->tag],
510 cur->string);
511 }
512
ce560686
SR
513 crc = partial_crc32(symbol_type_name[cur->tag],
514 crc);
78c04153
SR
515 crc = partial_crc32_one(' ', crc);
516 crc = partial_crc32(cur->string, crc);
517 crc = partial_crc32_one(' ', crc);
518 } else {
519 subsym->expansion_trail = expansion_trail;
520 expansion_trail = subsym;
15fde675 521 crc = expand_and_crc_sym(subsym, crc);
78c04153
SR
522 }
523 break;
1da177e4 524 }
1da177e4 525 }
1da177e4 526
15fde675
AG
527 {
528 static struct symbol **end = &visited_symbols;
529
530 if (!sym->visited) {
531 *end = sym;
532 end = &sym->visited;
533 sym->visited = (struct symbol *)-1L;
534 }
535 }
536
78c04153 537 return crc;
1da177e4
LT
538}
539
78c04153 540void export_symbol(const char *name)
1da177e4 541{
78c04153 542 struct symbol *sym;
1da177e4 543
78c04153
SR
544 sym = find_symbol(name, SYM_NORMAL);
545 if (!sym)
546 error_with_pos("export undefined symbol %s", name);
547 else {
548 unsigned long crc;
64e6c1e1 549 int has_changed = 0;
1da177e4 550
78c04153
SR
551 if (flag_dump_defs)
552 fprintf(debugfile, "Export %s == <", name);
1da177e4 553
78c04153 554 expansion_trail = (struct symbol *)-1L;
1da177e4 555
64e6c1e1
AG
556 sym->expansion_trail = expansion_trail;
557 expansion_trail = sym;
15fde675 558 crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
1da177e4 559
78c04153
SR
560 sym = expansion_trail;
561 while (sym != (struct symbol *)-1L) {
562 struct symbol *n = sym->expansion_trail;
64e6c1e1
AG
563
564 if (sym->status != STATUS_UNCHANGED) {
565 if (!has_changed) {
566 print_location();
567 fprintf(stderr, "%s: %s: modversion "
568 "changed because of changes "
569 "in ", flag_preserve ? "error" :
570 "warning", name);
571 } else
572 fprintf(stderr, ", ");
573 print_type_name(sym->type, sym->name);
574 if (sym->status == STATUS_DEFINED)
575 fprintf(stderr, " (became defined)");
576 has_changed = 1;
577 if (flag_preserve)
578 errors++;
579 }
78c04153
SR
580 sym->expansion_trail = 0;
581 sym = n;
582 }
64e6c1e1
AG
583 if (has_changed)
584 fprintf(stderr, "\n");
1da177e4 585
78c04153
SR
586 if (flag_dump_defs)
587 fputs(">\n", debugfile);
1da177e4 588
78c04153
SR
589 /* Used as a linker script. */
590 printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc);
591 }
1da177e4
LT
592}
593
594/*----------------------------------------------------------------------*/
64e6c1e1
AG
595
596static void print_location(void)
597{
598 fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
599}
600
601static void print_type_name(enum symbol_type type, const char *name)
602{
603 if (type != SYM_NORMAL)
604 fprintf(stderr, "%s %s", symbol_type_name[type], name);
605 else
606 fprintf(stderr, "%s", name);
607}
608
78c04153 609void error_with_pos(const char *fmt, ...)
1da177e4 610{
78c04153 611 va_list args;
1da177e4 612
78c04153 613 if (flag_warnings) {
64e6c1e1 614 print_location();
1da177e4 615
78c04153
SR
616 va_start(args, fmt);
617 vfprintf(stderr, fmt, args);
618 va_end(args);
619 putc('\n', stderr);
1da177e4 620
78c04153
SR
621 errors++;
622 }
1da177e4
LT
623}
624
ce560686 625static void genksyms_usage(void)
1da177e4 626{
36091fd3 627 fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
1da177e4 628#ifdef __GNU_LIBRARY__
36091fd3 629 " -a, --arch Select architecture\n"
1da177e4
LT
630 " -d, --debug Increment the debug level (repeatable)\n"
631 " -D, --dump Dump expanded symbol defs (for debugging only)\n"
64e6c1e1
AG
632 " -r, --reference file Read reference symbols from a file\n"
633 " -T, --dump-types file Dump expanded types into file\n"
634 " -p, --preserve Preserve reference modversions or fail\n"
1da177e4
LT
635 " -w, --warnings Enable warnings\n"
636 " -q, --quiet Disable warnings (default)\n"
637 " -h, --help Print this message\n"
638 " -V, --version Print the release version\n"
78c04153 639#else /* __GNU_LIBRARY__ */
36091fd3 640 " -a Select architecture\n"
78c04153
SR
641 " -d Increment the debug level (repeatable)\n"
642 " -D Dump expanded symbol defs (for debugging only)\n"
64e6c1e1
AG
643 " -r file Read reference symbols from a file\n"
644 " -T file Dump expanded types into file\n"
645 " -p Preserve reference modversions or fail\n"
78c04153
SR
646 " -w Enable warnings\n"
647 " -q Disable warnings (default)\n"
648 " -h Print this message\n"
649 " -V Print the release version\n"
650#endif /* __GNU_LIBRARY__ */
1da177e4
LT
651 , stderr);
652}
653
78c04153 654int main(int argc, char **argv)
1da177e4 655{
64e6c1e1 656 FILE *dumpfile = NULL, *ref_file = NULL;
78c04153 657 int o;
1da177e4
LT
658
659#ifdef __GNU_LIBRARY__
78c04153
SR
660 struct option long_opts[] = {
661 {"arch", 1, 0, 'a'},
662 {"debug", 0, 0, 'd'},
663 {"warnings", 0, 0, 'w'},
664 {"quiet", 0, 0, 'q'},
665 {"dump", 0, 0, 'D'},
64e6c1e1 666 {"reference", 1, 0, 'r'},
15fde675 667 {"dump-types", 1, 0, 'T'},
64e6c1e1 668 {"preserve", 0, 0, 'p'},
78c04153
SR
669 {"version", 0, 0, 'V'},
670 {"help", 0, 0, 'h'},
671 {0, 0, 0, 0}
672 };
673
64e6c1e1 674 while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph",
78c04153
SR
675 &long_opts[0], NULL)) != EOF)
676#else /* __GNU_LIBRARY__ */
64e6c1e1 677 while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF)
78c04153
SR
678#endif /* __GNU_LIBRARY__ */
679 switch (o) {
680 case 'a':
681 arch = optarg;
682 break;
683 case 'd':
684 flag_debug++;
685 break;
686 case 'w':
687 flag_warnings = 1;
688 break;
689 case 'q':
690 flag_warnings = 0;
691 break;
692 case 'V':
693 fputs("genksyms version 2.5.60\n", stderr);
694 break;
695 case 'D':
696 flag_dump_defs = 1;
697 break;
64e6c1e1
AG
698 case 'r':
699 flag_reference = 1;
700 ref_file = fopen(optarg, "r");
701 if (!ref_file) {
702 perror(optarg);
703 return 1;
704 }
705 break;
15fde675
AG
706 case 'T':
707 flag_dump_types = 1;
708 dumpfile = fopen(optarg, "w");
709 if (!dumpfile) {
710 perror(optarg);
711 return 1;
712 }
713 break;
64e6c1e1
AG
714 case 'p':
715 flag_preserve = 1;
716 break;
78c04153
SR
717 case 'h':
718 genksyms_usage();
719 return 0;
720 default:
721 genksyms_usage();
722 return 1;
723 }
f606ddf4 724 if ((strcmp(arch, "h8300") == 0) || (strcmp(arch, "blackfin") == 0))
78c04153
SR
725 mod_prefix = "_";
726 {
727 extern int yydebug;
728 extern int yy_flex_debug;
729
730 yydebug = (flag_debug > 1);
731 yy_flex_debug = (flag_debug > 2);
732
733 debugfile = stderr;
734 /* setlinebuf(debugfile); */
735 }
736
64e6c1e1
AG
737 if (flag_reference)
738 read_reference(ref_file);
739
78c04153
SR
740 yyparse();
741
15fde675
AG
742 if (flag_dump_types && visited_symbols) {
743 while (visited_symbols != (struct symbol *)-1L) {
744 struct symbol *sym = visited_symbols;
745
746 if (sym->type != SYM_NORMAL) {
747 putc(symbol_type_name[sym->type][0], dumpfile);
748 putc('#', dumpfile);
749 }
750 fputs(sym->name, dumpfile);
751 putc(' ', dumpfile);
3b40d381
AG
752 if (sym->is_extern)
753 fputs("extern ", dumpfile);
15fde675
AG
754 print_list(dumpfile, sym->defn);
755 putc('\n', dumpfile);
756
757 visited_symbols = sym->visited;
758 sym->visited = NULL;
759 }
760 }
761
78c04153
SR
762 if (flag_debug) {
763 fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
764 nsyms, HASH_BUCKETS,
765 (double)nsyms / (double)HASH_BUCKETS);
766 }
767
768 return errors != 0;
1da177e4 769}
This page took 0.386228 seconds and 5 git commands to generate.