diff options
Diffstat (limited to 'scripts/genksyms')
-rw-r--r-- | scripts/genksyms/genksyms.c | 277 | ||||
-rw-r--r-- | scripts/genksyms/genksyms.h | 7 | ||||
-rw-r--r-- | scripts/genksyms/keywords.c_shipped | 189 | ||||
-rw-r--r-- | scripts/genksyms/keywords.gperf | 2 |
4 files changed, 363 insertions, 112 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index c249274e005a..f8bb4cabd62d 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c | |||
@@ -42,7 +42,8 @@ static FILE *debugfile; | |||
42 | int cur_line = 1; | 42 | int cur_line = 1; |
43 | char *cur_filename; | 43 | char *cur_filename; |
44 | 44 | ||
45 | static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings; | 45 | static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, |
46 | flag_preserve, flag_warnings, flag_asm; | ||
46 | static const char *arch = ""; | 47 | static const char *arch = ""; |
47 | static const char *mod_prefix = ""; | 48 | static const char *mod_prefix = ""; |
48 | 49 | ||
@@ -58,6 +59,8 @@ static const char *const symbol_type_name[] = { | |||
58 | 59 | ||
59 | static int equal_list(struct string_list *a, struct string_list *b); | 60 | static int equal_list(struct string_list *a, struct string_list *b); |
60 | static void print_list(FILE * f, struct string_list *list); | 61 | static void print_list(FILE * f, struct string_list *list); |
62 | static void print_location(void); | ||
63 | static void print_type_name(enum symbol_type type, const char *name); | ||
61 | 64 | ||
62 | /*----------------------------------------------------------------------*/ | 65 | /*----------------------------------------------------------------------*/ |
63 | 66 | ||
@@ -151,27 +154,83 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns) | |||
151 | 154 | ||
152 | for (sym = symtab[h]; sym; sym = sym->hash_next) | 155 | for (sym = symtab[h]; sym; sym = sym->hash_next) |
153 | if (map_to_ns(sym->type) == map_to_ns(ns) && | 156 | if (map_to_ns(sym->type) == map_to_ns(ns) && |
154 | strcmp(name, sym->name) == 0) | 157 | strcmp(name, sym->name) == 0 && |
158 | sym->is_declared) | ||
155 | break; | 159 | break; |
156 | 160 | ||
157 | return sym; | 161 | return sym; |
158 | } | 162 | } |
159 | 163 | ||
160 | struct symbol *add_symbol(const char *name, enum symbol_type type, | 164 | static int is_unknown_symbol(struct symbol *sym) |
161 | struct string_list *defn, int is_extern) | 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 | |||
179 | struct symbol *__add_symbol(const char *name, enum symbol_type type, | ||
180 | struct string_list *defn, int is_extern, | ||
181 | int is_reference) | ||
162 | { | 182 | { |
163 | unsigned long h = crc32(name) % HASH_BUCKETS; | 183 | unsigned long h = crc32(name) % HASH_BUCKETS; |
164 | struct symbol *sym; | 184 | struct symbol *sym; |
185 | enum symbol_status status = STATUS_UNCHANGED; | ||
165 | 186 | ||
166 | for (sym = symtab[h]; sym; sym = sym->hash_next) { | 187 | for (sym = symtab[h]; sym; sym = sym->hash_next) { |
167 | if (map_to_ns(sym->type) == map_to_ns(type) | 188 | if (map_to_ns(sym->type) == map_to_ns(type) && |
168 | && strcmp(name, sym->name) == 0) { | 189 | strcmp(name, sym->name) == 0) { |
169 | if (!equal_list(sym->defn, defn)) | 190 | if (is_reference) |
191 | /* fall through */ ; | ||
192 | else if (sym->type == type && | ||
193 | equal_list(sym->defn, defn)) { | ||
194 | if (!sym->is_declared && sym->is_override) { | ||
195 | print_location(); | ||
196 | print_type_name(type, name); | ||
197 | fprintf(stderr, " modversion is " | ||
198 | "unchanged\n"); | ||
199 | } | ||
200 | sym->is_declared = 1; | ||
201 | return sym; | ||
202 | } else if (!sym->is_declared) { | ||
203 | if (sym->is_override && flag_preserve) { | ||
204 | print_location(); | ||
205 | fprintf(stderr, "ignoring "); | ||
206 | print_type_name(type, name); | ||
207 | fprintf(stderr, " modversion change\n"); | ||
208 | sym->is_declared = 1; | ||
209 | return sym; | ||
210 | } else { | ||
211 | status = is_unknown_symbol(sym) ? | ||
212 | STATUS_DEFINED : STATUS_MODIFIED; | ||
213 | } | ||
214 | } else { | ||
170 | error_with_pos("redefinition of %s", name); | 215 | error_with_pos("redefinition of %s", name); |
171 | return sym; | 216 | return sym; |
217 | } | ||
218 | break; | ||
172 | } | 219 | } |
173 | } | 220 | } |
174 | 221 | ||
222 | if (sym) { | ||
223 | struct symbol **psym; | ||
224 | |||
225 | for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) { | ||
226 | if (*psym == sym) { | ||
227 | *psym = sym->hash_next; | ||
228 | break; | ||
229 | } | ||
230 | } | ||
231 | --nsyms; | ||
232 | } | ||
233 | |||
175 | sym = xmalloc(sizeof(*sym)); | 234 | sym = xmalloc(sizeof(*sym)); |
176 | sym->name = name; | 235 | sym->name = name; |
177 | sym->type = type; | 236 | sym->type = type; |
@@ -183,6 +242,10 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, | |||
183 | sym->hash_next = symtab[h]; | 242 | sym->hash_next = symtab[h]; |
184 | symtab[h] = sym; | 243 | symtab[h] = sym; |
185 | 244 | ||
245 | sym->is_declared = !is_reference; | ||
246 | sym->status = status; | ||
247 | sym->is_override = 0; | ||
248 | |||
186 | if (flag_debug) { | 249 | if (flag_debug) { |
187 | fprintf(debugfile, "Defn for %s %s == <", | 250 | fprintf(debugfile, "Defn for %s %s == <", |
188 | symbol_type_name[type], name); | 251 | symbol_type_name[type], name); |
@@ -196,6 +259,18 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, | |||
196 | return sym; | 259 | return sym; |
197 | } | 260 | } |
198 | 261 | ||
262 | struct symbol *add_symbol(const char *name, enum symbol_type type, | ||
263 | struct string_list *defn, int is_extern) | ||
264 | { | ||
265 | return __add_symbol(name, type, defn, is_extern, 0); | ||
266 | } | ||
267 | |||
268 | struct symbol *add_reference_symbol(const char *name, enum symbol_type type, | ||
269 | struct string_list *defn, int is_extern) | ||
270 | { | ||
271 | return __add_symbol(name, type, defn, is_extern, 1); | ||
272 | } | ||
273 | |||
199 | /*----------------------------------------------------------------------*/ | 274 | /*----------------------------------------------------------------------*/ |
200 | 275 | ||
201 | void free_node(struct string_list *node) | 276 | void free_node(struct string_list *node) |
@@ -236,6 +311,90 @@ static int equal_list(struct string_list *a, struct string_list *b) | |||
236 | return !a && !b; | 311 | return !a && !b; |
237 | } | 312 | } |
238 | 313 | ||
314 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) | ||
315 | |||
316 | struct string_list *read_node(FILE *f) | ||
317 | { | ||
318 | char buffer[256]; | ||
319 | struct string_list node = { | ||
320 | .string = buffer, | ||
321 | .tag = SYM_NORMAL }; | ||
322 | int c; | ||
323 | |||
324 | while ((c = fgetc(f)) != EOF) { | ||
325 | if (c == ' ') { | ||
326 | if (node.string == buffer) | ||
327 | continue; | ||
328 | break; | ||
329 | } else if (c == '\n') { | ||
330 | if (node.string == buffer) | ||
331 | return NULL; | ||
332 | ungetc(c, f); | ||
333 | break; | ||
334 | } | ||
335 | if (node.string >= buffer + sizeof(buffer) - 1) { | ||
336 | fprintf(stderr, "Token too long\n"); | ||
337 | exit(1); | ||
338 | } | ||
339 | *node.string++ = c; | ||
340 | } | ||
341 | if (node.string == buffer) | ||
342 | return NULL; | ||
343 | *node.string = 0; | ||
344 | node.string = buffer; | ||
345 | |||
346 | if (node.string[1] == '#') { | ||
347 | int n; | ||
348 | |||
349 | for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) { | ||
350 | if (node.string[0] == symbol_type_name[n][0]) { | ||
351 | node.tag = n; | ||
352 | node.string += 2; | ||
353 | return copy_node(&node); | ||
354 | } | ||
355 | } | ||
356 | fprintf(stderr, "Unknown type %c\n", node.string[0]); | ||
357 | exit(1); | ||
358 | } | ||
359 | return copy_node(&node); | ||
360 | } | ||
361 | |||
362 | static void read_reference(FILE *f) | ||
363 | { | ||
364 | while (!feof(f)) { | ||
365 | struct string_list *defn = NULL; | ||
366 | struct string_list *sym, *def; | ||
367 | int is_extern = 0, is_override = 0; | ||
368 | struct symbol *subsym; | ||
369 | |||
370 | sym = read_node(f); | ||
371 | if (sym && sym->tag == SYM_NORMAL && | ||
372 | !strcmp(sym->string, "override")) { | ||
373 | is_override = 1; | ||
374 | free_node(sym); | ||
375 | sym = read_node(f); | ||
376 | } | ||
377 | if (!sym) | ||
378 | continue; | ||
379 | def = read_node(f); | ||
380 | if (def && def->tag == SYM_NORMAL && | ||
381 | !strcmp(def->string, "extern")) { | ||
382 | is_extern = 1; | ||
383 | free_node(def); | ||
384 | def = read_node(f); | ||
385 | } | ||
386 | while (def) { | ||
387 | def->next = defn; | ||
388 | defn = def; | ||
389 | def = read_node(f); | ||
390 | } | ||
391 | subsym = add_reference_symbol(xstrdup(sym->string), sym->tag, | ||
392 | defn, is_extern); | ||
393 | subsym->is_override = is_override; | ||
394 | free_node(sym); | ||
395 | } | ||
396 | } | ||
397 | |||
239 | static void print_node(FILE * f, struct string_list *list) | 398 | static void print_node(FILE * f, struct string_list *list) |
240 | { | 399 | { |
241 | if (list->tag != SYM_NORMAL) { | 400 | if (list->tag != SYM_NORMAL) { |
@@ -311,6 +470,7 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) | |||
311 | 470 | ||
312 | case SYM_TYPEDEF: | 471 | case SYM_TYPEDEF: |
313 | subsym = find_symbol(cur->string, cur->tag); | 472 | subsym = find_symbol(cur->string, cur->tag); |
473 | /* FIXME: Bad reference files can segfault here. */ | ||
314 | if (subsym->expansion_trail) { | 474 | if (subsym->expansion_trail) { |
315 | if (flag_dump_defs) | 475 | if (flag_dump_defs) |
316 | fprintf(debugfile, "%s ", cur->string); | 476 | fprintf(debugfile, "%s ", cur->string); |
@@ -347,9 +507,22 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) | |||
347 | t = n; | 507 | t = n; |
348 | 508 | ||
349 | n = xmalloc(sizeof(*n)); | 509 | n = xmalloc(sizeof(*n)); |
350 | n->string = xstrdup("{ UNKNOWN }"); | 510 | n->string = xstrdup("{"); |
511 | n->tag = SYM_NORMAL; | ||
512 | n->next = t; | ||
513 | t = n; | ||
514 | |||
515 | n = xmalloc(sizeof(*n)); | ||
516 | n->string = xstrdup("UNKNOWN"); | ||
517 | n->tag = SYM_NORMAL; | ||
518 | n->next = t; | ||
519 | t = n; | ||
520 | |||
521 | n = xmalloc(sizeof(*n)); | ||
522 | n->string = xstrdup("}"); | ||
351 | n->tag = SYM_NORMAL; | 523 | n->tag = SYM_NORMAL; |
352 | n->next = t; | 524 | n->next = t; |
525 | t = n; | ||
353 | 526 | ||
354 | subsym = | 527 | subsym = |
355 | add_symbol(cur->string, cur->tag, n, 0); | 528 | add_symbol(cur->string, cur->tag, n, 0); |
@@ -397,37 +570,75 @@ void export_symbol(const char *name) | |||
397 | error_with_pos("export undefined symbol %s", name); | 570 | error_with_pos("export undefined symbol %s", name); |
398 | else { | 571 | else { |
399 | unsigned long crc; | 572 | unsigned long crc; |
573 | int has_changed = 0; | ||
400 | 574 | ||
401 | if (flag_dump_defs) | 575 | if (flag_dump_defs) |
402 | fprintf(debugfile, "Export %s == <", name); | 576 | fprintf(debugfile, "Export %s == <", name); |
403 | 577 | ||
404 | expansion_trail = (struct symbol *)-1L; | 578 | expansion_trail = (struct symbol *)-1L; |
405 | 579 | ||
580 | sym->expansion_trail = expansion_trail; | ||
581 | expansion_trail = sym; | ||
406 | crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; | 582 | crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; |
407 | 583 | ||
408 | sym = expansion_trail; | 584 | sym = expansion_trail; |
409 | while (sym != (struct symbol *)-1L) { | 585 | while (sym != (struct symbol *)-1L) { |
410 | struct symbol *n = sym->expansion_trail; | 586 | struct symbol *n = sym->expansion_trail; |
587 | |||
588 | if (sym->status != STATUS_UNCHANGED) { | ||
589 | if (!has_changed) { | ||
590 | print_location(); | ||
591 | fprintf(stderr, "%s: %s: modversion " | ||
592 | "changed because of changes " | ||
593 | "in ", flag_preserve ? "error" : | ||
594 | "warning", name); | ||
595 | } else | ||
596 | fprintf(stderr, ", "); | ||
597 | print_type_name(sym->type, sym->name); | ||
598 | if (sym->status == STATUS_DEFINED) | ||
599 | fprintf(stderr, " (became defined)"); | ||
600 | has_changed = 1; | ||
601 | if (flag_preserve) | ||
602 | errors++; | ||
603 | } | ||
411 | sym->expansion_trail = 0; | 604 | sym->expansion_trail = 0; |
412 | sym = n; | 605 | sym = n; |
413 | } | 606 | } |
607 | if (has_changed) | ||
608 | fprintf(stderr, "\n"); | ||
414 | 609 | ||
415 | if (flag_dump_defs) | 610 | if (flag_dump_defs) |
416 | fputs(">\n", debugfile); | 611 | fputs(">\n", debugfile); |
417 | 612 | ||
418 | /* Used as a linker script. */ | 613 | /* Used as assembly source or a linker script. */ |
419 | printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); | 614 | printf(flag_asm |
615 | ? ".equiv %s__crc_%s, %#08lx\n" | ||
616 | : "%s__crc_%s = %#08lx ;\n", | ||
617 | mod_prefix, name, crc); | ||
420 | } | 618 | } |
421 | } | 619 | } |
422 | 620 | ||
423 | /*----------------------------------------------------------------------*/ | 621 | /*----------------------------------------------------------------------*/ |
622 | |||
623 | static void print_location(void) | ||
624 | { | ||
625 | fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line); | ||
626 | } | ||
627 | |||
628 | static void print_type_name(enum symbol_type type, const char *name) | ||
629 | { | ||
630 | if (type != SYM_NORMAL) | ||
631 | fprintf(stderr, "%s %s", symbol_type_name[type], name); | ||
632 | else | ||
633 | fprintf(stderr, "%s", name); | ||
634 | } | ||
635 | |||
424 | void error_with_pos(const char *fmt, ...) | 636 | void error_with_pos(const char *fmt, ...) |
425 | { | 637 | { |
426 | va_list args; | 638 | va_list args; |
427 | 639 | ||
428 | if (flag_warnings) { | 640 | if (flag_warnings) { |
429 | fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", | 641 | print_location(); |
430 | cur_line); | ||
431 | 642 | ||
432 | va_start(args, fmt); | 643 | va_start(args, fmt); |
433 | vfprintf(stderr, fmt, args); | 644 | vfprintf(stderr, fmt, args); |
@@ -440,21 +651,27 @@ void error_with_pos(const char *fmt, ...) | |||
440 | 651 | ||
441 | static void genksyms_usage(void) | 652 | static void genksyms_usage(void) |
442 | { | 653 | { |
443 | fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" | 654 | fputs("Usage:\n" "genksyms [-aAdDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" |
444 | #ifdef __GNU_LIBRARY__ | 655 | #ifdef __GNU_LIBRARY__ |
445 | " -a, --arch Select architecture\n" | 656 | " -a, --arch Select architecture\n" |
657 | " -A, --asm Generate assembly rather than linker script\n" | ||
446 | " -d, --debug Increment the debug level (repeatable)\n" | 658 | " -d, --debug Increment the debug level (repeatable)\n" |
447 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" | 659 | " -D, --dump Dump expanded symbol defs (for debugging only)\n" |
448 | " -T, --dump-types file Dump expanded types into file (for debugging only)\n" | 660 | " -r, --reference file Read reference symbols from a file\n" |
661 | " -T, --dump-types file Dump expanded types into file\n" | ||
662 | " -p, --preserve Preserve reference modversions or fail\n" | ||
449 | " -w, --warnings Enable warnings\n" | 663 | " -w, --warnings Enable warnings\n" |
450 | " -q, --quiet Disable warnings (default)\n" | 664 | " -q, --quiet Disable warnings (default)\n" |
451 | " -h, --help Print this message\n" | 665 | " -h, --help Print this message\n" |
452 | " -V, --version Print the release version\n" | 666 | " -V, --version Print the release version\n" |
453 | #else /* __GNU_LIBRARY__ */ | 667 | #else /* __GNU_LIBRARY__ */ |
454 | " -a Select architecture\n" | 668 | " -a Select architecture\n" |
669 | " -A Generate assembly rather than linker script\n" | ||
455 | " -d Increment the debug level (repeatable)\n" | 670 | " -d Increment the debug level (repeatable)\n" |
456 | " -D Dump expanded symbol defs (for debugging only)\n" | 671 | " -D Dump expanded symbol defs (for debugging only)\n" |
457 | " -T file Dump expanded types into file (for debugging only)\n" | 672 | " -r file Read reference symbols from a file\n" |
673 | " -T file Dump expanded types into file\n" | ||
674 | " -p Preserve reference modversions or fail\n" | ||
458 | " -w Enable warnings\n" | 675 | " -w Enable warnings\n" |
459 | " -q Disable warnings (default)\n" | 676 | " -q Disable warnings (default)\n" |
460 | " -h Print this message\n" | 677 | " -h Print this message\n" |
@@ -465,26 +682,29 @@ static void genksyms_usage(void) | |||
465 | 682 | ||
466 | int main(int argc, char **argv) | 683 | int main(int argc, char **argv) |
467 | { | 684 | { |
468 | FILE *dumpfile = NULL; | 685 | FILE *dumpfile = NULL, *ref_file = NULL; |
469 | int o; | 686 | int o; |
470 | 687 | ||
471 | #ifdef __GNU_LIBRARY__ | 688 | #ifdef __GNU_LIBRARY__ |
472 | struct option long_opts[] = { | 689 | struct option long_opts[] = { |
473 | {"arch", 1, 0, 'a'}, | 690 | {"arch", 1, 0, 'a'}, |
691 | {"asm", 0, 0, 'A'}, | ||
474 | {"debug", 0, 0, 'd'}, | 692 | {"debug", 0, 0, 'd'}, |
475 | {"warnings", 0, 0, 'w'}, | 693 | {"warnings", 0, 0, 'w'}, |
476 | {"quiet", 0, 0, 'q'}, | 694 | {"quiet", 0, 0, 'q'}, |
477 | {"dump", 0, 0, 'D'}, | 695 | {"dump", 0, 0, 'D'}, |
696 | {"reference", 1, 0, 'r'}, | ||
478 | {"dump-types", 1, 0, 'T'}, | 697 | {"dump-types", 1, 0, 'T'}, |
698 | {"preserve", 0, 0, 'p'}, | ||
479 | {"version", 0, 0, 'V'}, | 699 | {"version", 0, 0, 'V'}, |
480 | {"help", 0, 0, 'h'}, | 700 | {"help", 0, 0, 'h'}, |
481 | {0, 0, 0, 0} | 701 | {0, 0, 0, 0} |
482 | }; | 702 | }; |
483 | 703 | ||
484 | while ((o = getopt_long(argc, argv, "a:dwqVDT:h", | 704 | while ((o = getopt_long(argc, argv, "a:dwqVADr:T:ph", |
485 | &long_opts[0], NULL)) != EOF) | 705 | &long_opts[0], NULL)) != EOF) |
486 | #else /* __GNU_LIBRARY__ */ | 706 | #else /* __GNU_LIBRARY__ */ |
487 | while ((o = getopt(argc, argv, "a:dwqVDT:h")) != EOF) | 707 | while ((o = getopt(argc, argv, "a:dwqVADr:T:ph")) != EOF) |
488 | #endif /* __GNU_LIBRARY__ */ | 708 | #endif /* __GNU_LIBRARY__ */ |
489 | switch (o) { | 709 | switch (o) { |
490 | case 'a': | 710 | case 'a': |
@@ -502,9 +722,20 @@ int main(int argc, char **argv) | |||
502 | case 'V': | 722 | case 'V': |
503 | fputs("genksyms version 2.5.60\n", stderr); | 723 | fputs("genksyms version 2.5.60\n", stderr); |
504 | break; | 724 | break; |
725 | case 'A': | ||
726 | flag_asm = 1; | ||
727 | break; | ||
505 | case 'D': | 728 | case 'D': |
506 | flag_dump_defs = 1; | 729 | flag_dump_defs = 1; |
507 | break; | 730 | break; |
731 | case 'r': | ||
732 | flag_reference = 1; | ||
733 | ref_file = fopen(optarg, "r"); | ||
734 | if (!ref_file) { | ||
735 | perror(optarg); | ||
736 | return 1; | ||
737 | } | ||
738 | break; | ||
508 | case 'T': | 739 | case 'T': |
509 | flag_dump_types = 1; | 740 | flag_dump_types = 1; |
510 | dumpfile = fopen(optarg, "w"); | 741 | dumpfile = fopen(optarg, "w"); |
@@ -513,6 +744,9 @@ int main(int argc, char **argv) | |||
513 | return 1; | 744 | return 1; |
514 | } | 745 | } |
515 | break; | 746 | break; |
747 | case 'p': | ||
748 | flag_preserve = 1; | ||
749 | break; | ||
516 | case 'h': | 750 | case 'h': |
517 | genksyms_usage(); | 751 | genksyms_usage(); |
518 | return 0; | 752 | return 0; |
@@ -533,12 +767,17 @@ int main(int argc, char **argv) | |||
533 | /* setlinebuf(debugfile); */ | 767 | /* setlinebuf(debugfile); */ |
534 | } | 768 | } |
535 | 769 | ||
770 | if (flag_reference) | ||
771 | read_reference(ref_file); | ||
772 | |||
536 | yyparse(); | 773 | yyparse(); |
537 | 774 | ||
538 | if (flag_dump_types && visited_symbols) { | 775 | if (flag_dump_types && visited_symbols) { |
539 | while (visited_symbols != (struct symbol *)-1L) { | 776 | while (visited_symbols != (struct symbol *)-1L) { |
540 | struct symbol *sym = visited_symbols; | 777 | struct symbol *sym = visited_symbols; |
541 | 778 | ||
779 | if (sym->is_override) | ||
780 | fputs("override ", dumpfile); | ||
542 | if (sym->type != SYM_NORMAL) { | 781 | if (sym->type != SYM_NORMAL) { |
543 | putc(symbol_type_name[sym->type][0], dumpfile); | 782 | putc(symbol_type_name[sym->type][0], dumpfile); |
544 | putc('#', dumpfile); | 783 | putc('#', dumpfile); |
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h index 2668287aa498..25c4d40cefc1 100644 --- a/scripts/genksyms/genksyms.h +++ b/scripts/genksyms/genksyms.h | |||
@@ -29,6 +29,10 @@ enum symbol_type { | |||
29 | SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION | 29 | SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION |
30 | }; | 30 | }; |
31 | 31 | ||
32 | enum symbol_status { | ||
33 | STATUS_UNCHANGED, STATUS_DEFINED, STATUS_MODIFIED | ||
34 | }; | ||
35 | |||
32 | struct string_list { | 36 | struct string_list { |
33 | struct string_list *next; | 37 | struct string_list *next; |
34 | enum symbol_type tag; | 38 | enum symbol_type tag; |
@@ -43,6 +47,9 @@ struct symbol { | |||
43 | struct symbol *expansion_trail; | 47 | struct symbol *expansion_trail; |
44 | struct symbol *visited; | 48 | struct symbol *visited; |
45 | int is_extern; | 49 | int is_extern; |
50 | int is_declared; | ||
51 | enum symbol_status status; | ||
52 | int is_override; | ||
46 | }; | 53 | }; |
47 | 54 | ||
48 | typedef struct string_list **yystype; | 55 | typedef struct string_list **yystype; |
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped index 971e0113ae7a..83484fe93ede 100644 --- a/scripts/genksyms/keywords.c_shipped +++ b/scripts/genksyms/keywords.c_shipped | |||
@@ -1,4 +1,4 @@ | |||
1 | /* ANSI-C code produced by gperf version 3.0.2 */ | 1 | /* ANSI-C code produced by gperf version 3.0.1 */ |
2 | /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ | 2 | /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ |
3 | 3 | ||
4 | #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ | 4 | #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ |
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #line 3 "scripts/genksyms/keywords.gperf" | 33 | #line 3 "scripts/genksyms/keywords.gperf" |
34 | struct resword { const char *name; int token; }; | 34 | struct resword { const char *name; int token; }; |
35 | /* maximum key range = 62, duplicates = 0 */ | 35 | /* maximum key range = 64, duplicates = 0 */ |
36 | 36 | ||
37 | #ifdef __GNUC__ | 37 | #ifdef __GNUC__ |
38 | __inline | 38 | __inline |
@@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len) | |||
46 | { | 46 | { |
47 | static const unsigned char asso_values[] = | 47 | static const unsigned char asso_values[] = |
48 | { | 48 | { |
49 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 49 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
50 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 50 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
51 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 51 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
52 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 52 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
53 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 53 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
54 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 54 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
55 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, | 55 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 0, |
56 | 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, | 56 | 67, 67, 67, 67, 67, 67, 15, 67, 67, 67, |
57 | 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 57 | 0, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
58 | 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, | 58 | 67, 67, 67, 67, 67, 0, 67, 0, 67, 5, |
59 | 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, | 59 | 25, 20, 15, 30, 67, 15, 67, 67, 10, 0, |
60 | 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, | 60 | 10, 40, 20, 67, 10, 5, 0, 10, 15, 67, |
61 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 61 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
62 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 62 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
63 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 63 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
64 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 64 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
65 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 65 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
66 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 66 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
67 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 67 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
68 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 68 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
69 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 69 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
70 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 70 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
71 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 71 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
72 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 72 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
73 | 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, | 73 | 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, |
74 | 65, 65, 65, 65, 65, 65 | 74 | 67, 67, 67, 67, 67, 67 |
75 | }; | 75 | }; |
76 | return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; | 76 | return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; |
77 | } | 77 | } |
@@ -84,116 +84,119 @@ is_reserved_word (register const char *str, register unsigned int len) | |||
84 | { | 84 | { |
85 | enum | 85 | enum |
86 | { | 86 | { |
87 | TOTAL_KEYWORDS = 43, | 87 | TOTAL_KEYWORDS = 45, |
88 | MIN_WORD_LENGTH = 3, | 88 | MIN_WORD_LENGTH = 3, |
89 | MAX_WORD_LENGTH = 24, | 89 | MAX_WORD_LENGTH = 24, |
90 | MIN_HASH_VALUE = 3, | 90 | MIN_HASH_VALUE = 3, |
91 | MAX_HASH_VALUE = 64 | 91 | MAX_HASH_VALUE = 66 |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static const struct resword wordlist[] = | 94 | static const struct resword wordlist[] = |
95 | { | 95 | { |
96 | {""}, {""}, {""}, | 96 | {""}, {""}, {""}, |
97 | #line 26 "scripts/genksyms/keywords.gperf" | 97 | #line 28 "scripts/genksyms/keywords.gperf" |
98 | {"asm", ASM_KEYW}, | 98 | {"asm", ASM_KEYW}, |
99 | {""}, | 99 | {""}, |
100 | #line 8 "scripts/genksyms/keywords.gperf" | 100 | #line 10 "scripts/genksyms/keywords.gperf" |
101 | {"__asm", ASM_KEYW}, | 101 | {"__asm", ASM_KEYW}, |
102 | {""}, | 102 | {""}, |
103 | #line 9 "scripts/genksyms/keywords.gperf" | 103 | #line 11 "scripts/genksyms/keywords.gperf" |
104 | {"__asm__", ASM_KEYW}, | 104 | {"__asm__", ASM_KEYW}, |
105 | {""}, {""}, | 105 | {""}, {""}, |
106 | #line 52 "scripts/genksyms/keywords.gperf" | 106 | #line 54 "scripts/genksyms/keywords.gperf" |
107 | {"__typeof__", TYPEOF_KEYW}, | 107 | {"__typeof__", TYPEOF_KEYW}, |
108 | {""}, | 108 | {""}, |
109 | #line 12 "scripts/genksyms/keywords.gperf" | 109 | #line 14 "scripts/genksyms/keywords.gperf" |
110 | {"__const", CONST_KEYW}, | 110 | {"__const", CONST_KEYW}, |
111 | #line 11 "scripts/genksyms/keywords.gperf" | ||
112 | {"__attribute__", ATTRIBUTE_KEYW}, | ||
113 | #line 13 "scripts/genksyms/keywords.gperf" | 111 | #line 13 "scripts/genksyms/keywords.gperf" |
112 | {"__attribute__", ATTRIBUTE_KEYW}, | ||
113 | #line 15 "scripts/genksyms/keywords.gperf" | ||
114 | {"__const__", CONST_KEYW}, | 114 | {"__const__", CONST_KEYW}, |
115 | #line 18 "scripts/genksyms/keywords.gperf" | 115 | #line 20 "scripts/genksyms/keywords.gperf" |
116 | {"__signed__", SIGNED_KEYW}, | 116 | {"__signed__", SIGNED_KEYW}, |
117 | #line 44 "scripts/genksyms/keywords.gperf" | 117 | #line 46 "scripts/genksyms/keywords.gperf" |
118 | {"static", STATIC_KEYW}, | 118 | {"static", STATIC_KEYW}, |
119 | #line 20 "scripts/genksyms/keywords.gperf" | 119 | {""}, |
120 | {"__volatile__", VOLATILE_KEYW}, | 120 | #line 41 "scripts/genksyms/keywords.gperf" |
121 | #line 39 "scripts/genksyms/keywords.gperf" | ||
122 | {"int", INT_KEYW}, | 121 | {"int", INT_KEYW}, |
123 | #line 32 "scripts/genksyms/keywords.gperf" | 122 | #line 34 "scripts/genksyms/keywords.gperf" |
124 | {"char", CHAR_KEYW}, | 123 | {"char", CHAR_KEYW}, |
125 | #line 33 "scripts/genksyms/keywords.gperf" | 124 | #line 35 "scripts/genksyms/keywords.gperf" |
126 | {"const", CONST_KEYW}, | 125 | {"const", CONST_KEYW}, |
127 | #line 45 "scripts/genksyms/keywords.gperf" | 126 | #line 47 "scripts/genksyms/keywords.gperf" |
128 | {"struct", STRUCT_KEYW}, | 127 | {"struct", STRUCT_KEYW}, |
129 | #line 24 "scripts/genksyms/keywords.gperf" | 128 | #line 26 "scripts/genksyms/keywords.gperf" |
130 | {"__restrict__", RESTRICT_KEYW}, | 129 | {"__restrict__", RESTRICT_KEYW}, |
131 | #line 25 "scripts/genksyms/keywords.gperf" | 130 | #line 27 "scripts/genksyms/keywords.gperf" |
132 | {"restrict", RESTRICT_KEYW}, | 131 | {"restrict", RESTRICT_KEYW}, |
133 | #line 23 "scripts/genksyms/keywords.gperf" | 132 | #line 7 "scripts/genksyms/keywords.gperf" |
134 | {"_restrict", RESTRICT_KEYW}, | 133 | {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, |
135 | #line 16 "scripts/genksyms/keywords.gperf" | 134 | #line 18 "scripts/genksyms/keywords.gperf" |
136 | {"__inline__", INLINE_KEYW}, | 135 | {"__inline__", INLINE_KEYW}, |
137 | #line 10 "scripts/genksyms/keywords.gperf" | ||
138 | {"__attribute", ATTRIBUTE_KEYW}, | ||
139 | {""}, | 136 | {""}, |
140 | #line 14 "scripts/genksyms/keywords.gperf" | 137 | #line 22 "scripts/genksyms/keywords.gperf" |
138 | {"__volatile__", VOLATILE_KEYW}, | ||
139 | #line 5 "scripts/genksyms/keywords.gperf" | ||
140 | {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, | ||
141 | #line 25 "scripts/genksyms/keywords.gperf" | ||
142 | {"_restrict", RESTRICT_KEYW}, | ||
143 | {""}, | ||
144 | #line 12 "scripts/genksyms/keywords.gperf" | ||
145 | {"__attribute", ATTRIBUTE_KEYW}, | ||
146 | #line 6 "scripts/genksyms/keywords.gperf" | ||
147 | {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, | ||
148 | #line 16 "scripts/genksyms/keywords.gperf" | ||
141 | {"__extension__", EXTENSION_KEYW}, | 149 | {"__extension__", EXTENSION_KEYW}, |
142 | #line 35 "scripts/genksyms/keywords.gperf" | 150 | #line 37 "scripts/genksyms/keywords.gperf" |
143 | {"enum", ENUM_KEYW}, | 151 | {"enum", ENUM_KEYW}, |
144 | #line 19 "scripts/genksyms/keywords.gperf" | 152 | #line 8 "scripts/genksyms/keywords.gperf" |
145 | {"__volatile", VOLATILE_KEYW}, | 153 | {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, |
146 | #line 36 "scripts/genksyms/keywords.gperf" | 154 | #line 38 "scripts/genksyms/keywords.gperf" |
147 | {"extern", EXTERN_KEYW}, | 155 | {"extern", EXTERN_KEYW}, |
148 | {""}, | 156 | {""}, |
149 | #line 17 "scripts/genksyms/keywords.gperf" | 157 | #line 19 "scripts/genksyms/keywords.gperf" |
150 | {"__signed", SIGNED_KEYW}, | 158 | {"__signed", SIGNED_KEYW}, |
151 | #line 7 "scripts/genksyms/keywords.gperf" | 159 | #line 9 "scripts/genksyms/keywords.gperf" |
152 | {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, | 160 | {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, |
153 | {""}, | 161 | #line 49 "scripts/genksyms/keywords.gperf" |
154 | #line 51 "scripts/genksyms/keywords.gperf" | 162 | {"union", UNION_KEYW}, |
163 | #line 53 "scripts/genksyms/keywords.gperf" | ||
155 | {"typeof", TYPEOF_KEYW}, | 164 | {"typeof", TYPEOF_KEYW}, |
156 | #line 46 "scripts/genksyms/keywords.gperf" | 165 | #line 48 "scripts/genksyms/keywords.gperf" |
157 | {"typedef", TYPEDEF_KEYW}, | 166 | {"typedef", TYPEDEF_KEYW}, |
158 | #line 15 "scripts/genksyms/keywords.gperf" | 167 | #line 17 "scripts/genksyms/keywords.gperf" |
159 | {"__inline", INLINE_KEYW}, | 168 | {"__inline", INLINE_KEYW}, |
160 | #line 31 "scripts/genksyms/keywords.gperf" | 169 | #line 33 "scripts/genksyms/keywords.gperf" |
161 | {"auto", AUTO_KEYW}, | 170 | {"auto", AUTO_KEYW}, |
162 | #line 47 "scripts/genksyms/keywords.gperf" | 171 | #line 21 "scripts/genksyms/keywords.gperf" |
163 | {"union", UNION_KEYW}, | 172 | {"__volatile", VOLATILE_KEYW}, |
164 | {""}, {""}, | ||
165 | #line 48 "scripts/genksyms/keywords.gperf" | ||
166 | {"unsigned", UNSIGNED_KEYW}, | ||
167 | #line 49 "scripts/genksyms/keywords.gperf" | ||
168 | {"void", VOID_KEYW}, | ||
169 | #line 42 "scripts/genksyms/keywords.gperf" | ||
170 | {"short", SHORT_KEYW}, | ||
171 | {""}, {""}, | 173 | {""}, {""}, |
172 | #line 50 "scripts/genksyms/keywords.gperf" | 174 | #line 50 "scripts/genksyms/keywords.gperf" |
173 | {"volatile", VOLATILE_KEYW}, | 175 | {"unsigned", UNSIGNED_KEYW}, |
174 | {""}, | ||
175 | #line 37 "scripts/genksyms/keywords.gperf" | ||
176 | {"float", FLOAT_KEYW}, | ||
177 | #line 34 "scripts/genksyms/keywords.gperf" | ||
178 | {"double", DOUBLE_KEYW}, | ||
179 | {""}, | 176 | {""}, |
180 | #line 5 "scripts/genksyms/keywords.gperf" | 177 | #line 44 "scripts/genksyms/keywords.gperf" |
181 | {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, | 178 | {"short", SHORT_KEYW}, |
182 | {""}, {""}, | 179 | #line 40 "scripts/genksyms/keywords.gperf" |
183 | #line 38 "scripts/genksyms/keywords.gperf" | ||
184 | {"inline", INLINE_KEYW}, | 180 | {"inline", INLINE_KEYW}, |
185 | #line 6 "scripts/genksyms/keywords.gperf" | ||
186 | {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, | ||
187 | #line 41 "scripts/genksyms/keywords.gperf" | ||
188 | {"register", REGISTER_KEYW}, | ||
189 | {""}, | 181 | {""}, |
190 | #line 22 "scripts/genksyms/keywords.gperf" | 182 | #line 52 "scripts/genksyms/keywords.gperf" |
183 | {"volatile", VOLATILE_KEYW}, | ||
184 | #line 42 "scripts/genksyms/keywords.gperf" | ||
185 | {"long", LONG_KEYW}, | ||
186 | #line 24 "scripts/genksyms/keywords.gperf" | ||
191 | {"_Bool", BOOL_KEYW}, | 187 | {"_Bool", BOOL_KEYW}, |
192 | #line 43 "scripts/genksyms/keywords.gperf" | ||
193 | {"signed", SIGNED_KEYW}, | ||
194 | {""}, {""}, | 188 | {""}, {""}, |
195 | #line 40 "scripts/genksyms/keywords.gperf" | 189 | #line 43 "scripts/genksyms/keywords.gperf" |
196 | {"long", LONG_KEYW} | 190 | {"register", REGISTER_KEYW}, |
191 | #line 51 "scripts/genksyms/keywords.gperf" | ||
192 | {"void", VOID_KEYW}, | ||
193 | #line 39 "scripts/genksyms/keywords.gperf" | ||
194 | {"float", FLOAT_KEYW}, | ||
195 | #line 36 "scripts/genksyms/keywords.gperf" | ||
196 | {"double", DOUBLE_KEYW}, | ||
197 | {""}, {""}, {""}, {""}, | ||
198 | #line 45 "scripts/genksyms/keywords.gperf" | ||
199 | {"signed", SIGNED_KEYW} | ||
197 | }; | 200 | }; |
198 | 201 | ||
199 | if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) | 202 | if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) |
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf index 5ef3733225fb..8abe7ab8d88f 100644 --- a/scripts/genksyms/keywords.gperf +++ b/scripts/genksyms/keywords.gperf | |||
@@ -5,6 +5,8 @@ struct resword { const char *name; int token; } | |||
5 | EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW | 5 | EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW |
6 | EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW | 6 | EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW |
7 | EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW | 7 | EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW |
8 | EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW | ||
9 | EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW | ||
8 | __asm, ASM_KEYW | 10 | __asm, ASM_KEYW |
9 | __asm__, ASM_KEYW | 11 | __asm__, ASM_KEYW |
10 | __attribute, ATTRIBUTE_KEYW | 12 | __attribute, ATTRIBUTE_KEYW |