diff options
Diffstat (limited to 'scripts/genksyms/genksyms.c')
| -rw-r--r-- | scripts/genksyms/genksyms.c | 77 |
1 files changed, 51 insertions, 26 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c index 5b0344e20d61..b0381823e404 100644 --- a/scripts/genksyms/genksyms.c +++ b/scripts/genksyms/genksyms.c | |||
| @@ -42,7 +42,7 @@ 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_warnings; | 45 | static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings; |
| 46 | static const char *arch = ""; | 46 | static const char *arch = ""; |
| 47 | static const char *mod_prefix = ""; | 47 | static const char *mod_prefix = ""; |
| 48 | 48 | ||
| @@ -50,6 +50,7 @@ static int errors; | |||
| 50 | static int nsyms; | 50 | static int nsyms; |
| 51 | 51 | ||
| 52 | static struct symbol *expansion_trail; | 52 | static struct symbol *expansion_trail; |
| 53 | static struct symbol *visited_symbols; | ||
| 53 | 54 | ||
| 54 | static const char *const symbol_type_name[] = { | 55 | static const char *const symbol_type_name[] = { |
| 55 | "normal", "typedef", "enum", "struct", "union" | 56 | "normal", "typedef", "enum", "struct", "union" |
| @@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *name, enum symbol_type type, | |||
| 176 | sym->type = type; | 177 | sym->type = type; |
| 177 | sym->defn = defn; | 178 | sym->defn = defn; |
| 178 | sym->expansion_trail = NULL; | 179 | sym->expansion_trail = NULL; |
| 180 | sym->visited = NULL; | ||
| 179 | sym->is_extern = is_extern; | 181 | sym->is_extern = is_extern; |
| 180 | 182 | ||
| 181 | sym->hash_next = symtab[h]; | 183 | sym->hash_next = symtab[h]; |
| @@ -236,26 +238,11 @@ static int equal_list(struct string_list *a, struct string_list *b) | |||
| 236 | 238 | ||
| 237 | static void print_node(FILE * f, struct string_list *list) | 239 | static void print_node(FILE * f, struct string_list *list) |
| 238 | { | 240 | { |
| 239 | switch (list->tag) { | 241 | if (list->tag != SYM_NORMAL) { |
| 240 | case SYM_STRUCT: | 242 | putc(symbol_type_name[list->tag][0], f); |
| 241 | putc('s', f); | ||
| 242 | goto printit; | ||
| 243 | case SYM_UNION: | ||
| 244 | putc('u', f); | ||
| 245 | goto printit; | ||
| 246 | case SYM_ENUM: | ||
| 247 | putc('e', f); | ||
| 248 | goto printit; | ||
| 249 | case SYM_TYPEDEF: | ||
| 250 | putc('t', f); | ||
| 251 | goto printit; | ||
| 252 | |||
| 253 | printit: | ||
| 254 | putc('#', f); | 243 | putc('#', f); |
| 255 | case SYM_NORMAL: | ||
| 256 | fputs(list->string, f); | ||
| 257 | break; | ||
| 258 | } | 244 | } |
| 245 | fputs(list->string, f); | ||
| 259 | } | 246 | } |
| 260 | 247 | ||
| 261 | static void print_list(FILE * f, struct string_list *list) | 248 | static void print_list(FILE * f, struct string_list *list) |
| @@ -287,9 +274,9 @@ static void print_list(FILE * f, struct string_list *list) | |||
| 287 | } | 274 | } |
| 288 | } | 275 | } |
| 289 | 276 | ||
| 290 | static unsigned long expand_and_crc_list(struct string_list *list, | 277 | static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc) |
| 291 | unsigned long crc) | ||
| 292 | { | 278 | { |
| 279 | struct string_list *list = sym->defn; | ||
| 293 | struct string_list **e, **b; | 280 | struct string_list **e, **b; |
| 294 | struct string_list *tmp, **tmp2; | 281 | struct string_list *tmp, **tmp2; |
| 295 | int elem = 1; | 282 | int elem = 1; |
| @@ -332,7 +319,7 @@ static unsigned long expand_and_crc_list(struct string_list *list, | |||
| 332 | } else { | 319 | } else { |
| 333 | subsym->expansion_trail = expansion_trail; | 320 | subsym->expansion_trail = expansion_trail; |
| 334 | expansion_trail = subsym; | 321 | expansion_trail = subsym; |
| 335 | crc = expand_and_crc_list(subsym->defn, crc); | 322 | crc = expand_and_crc_sym(subsym, crc); |
| 336 | } | 323 | } |
| 337 | break; | 324 | break; |
| 338 | 325 | ||
| @@ -382,12 +369,22 @@ static unsigned long expand_and_crc_list(struct string_list *list, | |||
| 382 | } else { | 369 | } else { |
| 383 | subsym->expansion_trail = expansion_trail; | 370 | subsym->expansion_trail = expansion_trail; |
| 384 | expansion_trail = subsym; | 371 | expansion_trail = subsym; |
| 385 | crc = expand_and_crc_list(subsym->defn, crc); | 372 | crc = expand_and_crc_sym(subsym, crc); |
| 386 | } | 373 | } |
| 387 | break; | 374 | break; |
| 388 | } | 375 | } |
| 389 | } | 376 | } |
| 390 | 377 | ||
| 378 | { | ||
| 379 | static struct symbol **end = &visited_symbols; | ||
| 380 | |||
| 381 | if (!sym->visited) { | ||
| 382 | *end = sym; | ||
| 383 | end = &sym->visited; | ||
| 384 | sym->visited = (struct symbol *)-1L; | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 391 | return crc; | 388 | return crc; |
| 392 | } | 389 | } |
| 393 | 390 | ||
| @@ -406,7 +403,7 @@ void export_symbol(const char *name) | |||
| 406 | 403 | ||
| 407 | expansion_trail = (struct symbol *)-1L; | 404 | expansion_trail = (struct symbol *)-1L; |
| 408 | 405 | ||
| 409 | crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; | 406 | crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; |
| 410 | 407 | ||
| 411 | sym = expansion_trail; | 408 | sym = expansion_trail; |
| 412 | while (sym != (struct symbol *)-1L) { | 409 | while (sym != (struct symbol *)-1L) { |
| @@ -464,6 +461,7 @@ static void genksyms_usage(void) | |||
| 464 | 461 | ||
| 465 | int main(int argc, char **argv) | 462 | int main(int argc, char **argv) |
| 466 | { | 463 | { |
| 464 | FILE *dumpfile = NULL; | ||
| 467 | int o; | 465 | int o; |
| 468 | 466 | ||
| 469 | #ifdef __GNU_LIBRARY__ | 467 | #ifdef __GNU_LIBRARY__ |
| @@ -473,15 +471,16 @@ int main(int argc, char **argv) | |||
| 473 | {"warnings", 0, 0, 'w'}, | 471 | {"warnings", 0, 0, 'w'}, |
| 474 | {"quiet", 0, 0, 'q'}, | 472 | {"quiet", 0, 0, 'q'}, |
| 475 | {"dump", 0, 0, 'D'}, | 473 | {"dump", 0, 0, 'D'}, |
| 474 | {"dump-types", 1, 0, 'T'}, | ||
| 476 | {"version", 0, 0, 'V'}, | 475 | {"version", 0, 0, 'V'}, |
| 477 | {"help", 0, 0, 'h'}, | 476 | {"help", 0, 0, 'h'}, |
| 478 | {0, 0, 0, 0} | 477 | {0, 0, 0, 0} |
| 479 | }; | 478 | }; |
| 480 | 479 | ||
| 481 | while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", | 480 | while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:", |
| 482 | &long_opts[0], NULL)) != EOF) | 481 | &long_opts[0], NULL)) != EOF) |
| 483 | #else /* __GNU_LIBRARY__ */ | 482 | #else /* __GNU_LIBRARY__ */ |
| 484 | while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) | 483 | while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF) |
| 485 | #endif /* __GNU_LIBRARY__ */ | 484 | #endif /* __GNU_LIBRARY__ */ |
| 486 | switch (o) { | 485 | switch (o) { |
| 487 | case 'a': | 486 | case 'a': |
| @@ -502,6 +501,14 @@ int main(int argc, char **argv) | |||
| 502 | case 'D': | 501 | case 'D': |
| 503 | flag_dump_defs = 1; | 502 | flag_dump_defs = 1; |
| 504 | break; | 503 | break; |
| 504 | case 'T': | ||
| 505 | flag_dump_types = 1; | ||
| 506 | dumpfile = fopen(optarg, "w"); | ||
| 507 | if (!dumpfile) { | ||
| 508 | perror(optarg); | ||
| 509 | return 1; | ||
| 510 | } | ||
| 511 | break; | ||
| 505 | case 'h': | 512 | case 'h': |
| 506 | genksyms_usage(); | 513 | genksyms_usage(); |
| 507 | return 0; | 514 | return 0; |
| @@ -524,6 +531,24 @@ int main(int argc, char **argv) | |||
| 524 | 531 | ||
| 525 | yyparse(); | 532 | yyparse(); |
| 526 | 533 | ||
| 534 | if (flag_dump_types && visited_symbols) { | ||
| 535 | while (visited_symbols != (struct symbol *)-1L) { | ||
| 536 | struct symbol *sym = visited_symbols; | ||
| 537 | |||
| 538 | if (sym->type != SYM_NORMAL) { | ||
| 539 | putc(symbol_type_name[sym->type][0], dumpfile); | ||
| 540 | putc('#', dumpfile); | ||
| 541 | } | ||
| 542 | fputs(sym->name, dumpfile); | ||
| 543 | putc(' ', dumpfile); | ||
| 544 | print_list(dumpfile, sym->defn); | ||
| 545 | putc('\n', dumpfile); | ||
| 546 | |||
| 547 | visited_symbols = sym->visited; | ||
| 548 | sym->visited = NULL; | ||
| 549 | } | ||
| 550 | } | ||
| 551 | |||
| 527 | if (flag_debug) { | 552 | if (flag_debug) { |
| 528 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", | 553 | fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", |
| 529 | nsyms, HASH_BUCKETS, | 554 | nsyms, HASH_BUCKETS, |
