aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/genksyms/genksyms.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/genksyms/genksyms.c')
-rw-r--r--scripts/genksyms/genksyms.c192
1 files changed, 136 insertions, 56 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index f99115ebe925..f9e75531ea03 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -53,12 +53,22 @@ static int nsyms;
53static struct symbol *expansion_trail; 53static struct symbol *expansion_trail;
54static struct symbol *visited_symbols; 54static struct symbol *visited_symbols;
55 55
56static const char *const symbol_type_name[] = { 56static const struct {
57 "normal", "typedef", "enum", "struct", "union" 57 int n;
58 const char *name;
59} symbol_types[] = {
60 [SYM_NORMAL] = { 0, NULL},
61 [SYM_TYPEDEF] = {'t', "typedef"},
62 [SYM_ENUM] = {'e', "enum"},
63 [SYM_STRUCT] = {'s', "struct"},
64 [SYM_UNION] = {'u', "union"},
65 [SYM_ENUM_CONST] = {'E', "enum constant"},
58}; 66};
59 67
60static int equal_list(struct string_list *a, struct string_list *b); 68static int equal_list(struct string_list *a, struct string_list *b);
61static void print_list(FILE * f, struct string_list *list); 69static void print_list(FILE * f, struct string_list *list);
70static struct string_list *concat_list(struct string_list *start, ...);
71static struct string_list *mk_node(const char *string);
62static void print_location(void); 72static void print_location(void);
63static void print_type_name(enum symbol_type type, const char *name); 73static void print_type_name(enum symbol_type type, const char *name);
64 74
@@ -140,14 +150,20 @@ static unsigned long crc32(const char *s)
140 150
141static enum symbol_type map_to_ns(enum symbol_type t) 151static enum symbol_type map_to_ns(enum symbol_type t)
142{ 152{
143 if (t == SYM_TYPEDEF) 153 switch (t) {
144 t = SYM_NORMAL; 154 case SYM_ENUM_CONST:
145 else if (t == SYM_UNION) 155 case SYM_NORMAL:
146 t = SYM_STRUCT; 156 case SYM_TYPEDEF:
157 return SYM_NORMAL;
158 case SYM_ENUM:
159 case SYM_STRUCT:
160 case SYM_UNION:
161 return SYM_STRUCT;
162 }
147 return t; 163 return t;
148} 164}
149 165
150struct symbol *find_symbol(const char *name, enum symbol_type ns) 166struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact)
151{ 167{
152 unsigned long h = crc32(name) % HASH_BUCKETS; 168 unsigned long h = crc32(name) % HASH_BUCKETS;
153 struct symbol *sym; 169 struct symbol *sym;
@@ -158,6 +174,8 @@ struct symbol *find_symbol(const char *name, enum symbol_type ns)
158 sym->is_declared) 174 sym->is_declared)
159 break; 175 break;
160 176
177 if (exact && sym && sym->type != ns)
178 return NULL;
161 return sym; 179 return sym;
162} 180}
163 181
@@ -180,10 +198,47 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
180 struct string_list *defn, int is_extern, 198 struct string_list *defn, int is_extern,
181 int is_reference) 199 int is_reference)
182{ 200{
183 unsigned long h = crc32(name) % HASH_BUCKETS; 201 unsigned long h;
184 struct symbol *sym; 202 struct symbol *sym;
185 enum symbol_status status = STATUS_UNCHANGED; 203 enum symbol_status status = STATUS_UNCHANGED;
204 /* The parser adds symbols in the order their declaration completes,
205 * so it is safe to store the value of the previous enum constant in
206 * a static variable.
207 */
208 static int enum_counter;
209 static struct string_list *last_enum_expr;
210
211 if (type == SYM_ENUM_CONST) {
212 if (defn) {
213 free_list(last_enum_expr, NULL);
214 last_enum_expr = copy_list_range(defn, NULL);
215 enum_counter = 1;
216 } else {
217 struct string_list *expr;
218 char buf[20];
219
220 snprintf(buf, sizeof(buf), "%d", enum_counter++);
221 if (last_enum_expr) {
222 expr = copy_list_range(last_enum_expr, NULL);
223 defn = concat_list(mk_node("("),
224 expr,
225 mk_node(")"),
226 mk_node("+"),
227 mk_node(buf), NULL);
228 } else {
229 defn = mk_node(buf);
230 }
231 }
232 } else if (type == SYM_ENUM) {
233 free_list(last_enum_expr, NULL);
234 last_enum_expr = NULL;
235 enum_counter = 0;
236 if (!name)
237 /* Anonymous enum definition, nothing more to do */
238 return NULL;
239 }
186 240
241 h = crc32(name) % HASH_BUCKETS;
187 for (sym = symtab[h]; sym; sym = sym->hash_next) { 242 for (sym = symtab[h]; sym; sym = sym->hash_next) {
188 if (map_to_ns(sym->type) == map_to_ns(type) && 243 if (map_to_ns(sym->type) == map_to_ns(type) &&
189 strcmp(name, sym->name) == 0) { 244 strcmp(name, sym->name) == 0) {
@@ -247,8 +302,12 @@ static struct symbol *__add_symbol(const char *name, enum symbol_type type,
247 sym->is_override = 0; 302 sym->is_override = 0;
248 303
249 if (flag_debug) { 304 if (flag_debug) {
250 fprintf(debugfile, "Defn for %s %s == <", 305 if (symbol_types[type].name)
251 symbol_type_name[type], name); 306 fprintf(debugfile, "Defn for %s %s == <",
307 symbol_types[type].name, name);
308 else
309 fprintf(debugfile, "Defn for type%d %s == <",
310 type, name);
252 if (is_extern) 311 if (is_extern)
253 fputs("extern ", debugfile); 312 fputs("extern ", debugfile);
254 print_list(debugfile, defn); 313 print_list(debugfile, defn);
@@ -288,6 +347,35 @@ void free_list(struct string_list *s, struct string_list *e)
288 } 347 }
289} 348}
290 349
350static struct string_list *mk_node(const char *string)
351{
352 struct string_list *newnode;
353
354 newnode = xmalloc(sizeof(*newnode));
355 newnode->string = xstrdup(string);
356 newnode->tag = SYM_NORMAL;
357 newnode->next = NULL;
358
359 return newnode;
360}
361
362static struct string_list *concat_list(struct string_list *start, ...)
363{
364 va_list ap;
365 struct string_list *n, *n2;
366
367 if (!start)
368 return NULL;
369 for (va_start(ap, start); (n = va_arg(ap, struct string_list *));) {
370 for (n2 = n; n2->next; n2 = n2->next)
371 ;
372 n2->next = start;
373 start = n;
374 }
375 va_end(ap);
376 return start;
377}
378
291struct string_list *copy_node(struct string_list *node) 379struct string_list *copy_node(struct string_list *node)
292{ 380{
293 struct string_list *newnode; 381 struct string_list *newnode;
@@ -299,6 +387,22 @@ struct string_list *copy_node(struct string_list *node)
299 return newnode; 387 return newnode;
300} 388}
301 389
390struct string_list *copy_list_range(struct string_list *start,
391 struct string_list *end)
392{
393 struct string_list *res, *n;
394
395 if (start == end)
396 return NULL;
397 n = res = copy_node(start);
398 for (start = start->next; start != end; start = start->next) {
399 n->next = copy_node(start);
400 n = n->next;
401 }
402 n->next = NULL;
403 return res;
404}
405
302static int equal_list(struct string_list *a, struct string_list *b) 406static int equal_list(struct string_list *a, struct string_list *b)
303{ 407{
304 while (a && b) { 408 while (a && b) {
@@ -346,8 +450,8 @@ static struct string_list *read_node(FILE *f)
346 if (node.string[1] == '#') { 450 if (node.string[1] == '#') {
347 int n; 451 int n;
348 452
349 for (n = 0; n < ARRAY_SIZE(symbol_type_name); n++) { 453 for (n = 0; n < ARRAY_SIZE(symbol_types); n++) {
350 if (node.string[0] == symbol_type_name[n][0]) { 454 if (node.string[0] == symbol_types[n].n) {
351 node.tag = n; 455 node.tag = n;
352 node.string += 2; 456 node.string += 2;
353 return copy_node(&node); 457 return copy_node(&node);
@@ -397,8 +501,8 @@ static void read_reference(FILE *f)
397 501
398static void print_node(FILE * f, struct string_list *list) 502static void print_node(FILE * f, struct string_list *list)
399{ 503{
400 if (list->tag != SYM_NORMAL) { 504 if (symbol_types[list->tag].n) {
401 putc(symbol_type_name[list->tag][0], f); 505 putc(symbol_types[list->tag].n, f);
402 putc('#', f); 506 putc('#', f);
403 } 507 }
404 fputs(list->string, f); 508 fputs(list->string, f);
@@ -468,8 +572,9 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
468 crc = partial_crc32_one(' ', crc); 572 crc = partial_crc32_one(' ', crc);
469 break; 573 break;
470 574
575 case SYM_ENUM_CONST:
471 case SYM_TYPEDEF: 576 case SYM_TYPEDEF:
472 subsym = find_symbol(cur->string, cur->tag); 577 subsym = find_symbol(cur->string, cur->tag, 0);
473 /* FIXME: Bad reference files can segfault here. */ 578 /* FIXME: Bad reference files can segfault here. */
474 if (subsym->expansion_trail) { 579 if (subsym->expansion_trail) {
475 if (flag_dump_defs) 580 if (flag_dump_defs)
@@ -486,55 +591,30 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
486 case SYM_STRUCT: 591 case SYM_STRUCT:
487 case SYM_UNION: 592 case SYM_UNION:
488 case SYM_ENUM: 593 case SYM_ENUM:
489 subsym = find_symbol(cur->string, cur->tag); 594 subsym = find_symbol(cur->string, cur->tag, 0);
490 if (!subsym) { 595 if (!subsym) {
491 struct string_list *n, *t = NULL; 596 struct string_list *n;
492 597
493 error_with_pos("expand undefined %s %s", 598 error_with_pos("expand undefined %s %s",
494 symbol_type_name[cur->tag], 599 symbol_types[cur->tag].name,
495 cur->string); 600 cur->string);
496 601 n = concat_list(mk_node
497 n = xmalloc(sizeof(*n)); 602 (symbol_types[cur->tag].name),
498 n->string = xstrdup(symbol_type_name[cur->tag]); 603 mk_node(cur->string),
499 n->tag = SYM_NORMAL; 604 mk_node("{"),
500 n->next = t; 605 mk_node("UNKNOWN"),
501 t = n; 606 mk_node("}"), NULL);
502
503 n = xmalloc(sizeof(*n));
504 n->string = xstrdup(cur->string);
505 n->tag = SYM_NORMAL;
506 n->next = t;
507 t = n;
508
509 n = xmalloc(sizeof(*n));
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("}");
523 n->tag = SYM_NORMAL;
524 n->next = t;
525 t = n;
526
527 subsym = 607 subsym =
528 add_symbol(cur->string, cur->tag, n, 0); 608 add_symbol(cur->string, cur->tag, n, 0);
529 } 609 }
530 if (subsym->expansion_trail) { 610 if (subsym->expansion_trail) {
531 if (flag_dump_defs) { 611 if (flag_dump_defs) {
532 fprintf(debugfile, "%s %s ", 612 fprintf(debugfile, "%s %s ",
533 symbol_type_name[cur->tag], 613 symbol_types[cur->tag].name,
534 cur->string); 614 cur->string);
535 } 615 }
536 616
537 crc = partial_crc32(symbol_type_name[cur->tag], 617 crc = partial_crc32(symbol_types[cur->tag].name,
538 crc); 618 crc);
539 crc = partial_crc32_one(' ', crc); 619 crc = partial_crc32_one(' ', crc);
540 crc = partial_crc32(cur->string, crc); 620 crc = partial_crc32(cur->string, crc);
@@ -565,7 +645,7 @@ void export_symbol(const char *name)
565{ 645{
566 struct symbol *sym; 646 struct symbol *sym;
567 647
568 sym = find_symbol(name, SYM_NORMAL); 648 sym = find_symbol(name, SYM_NORMAL, 0);
569 if (!sym) 649 if (!sym)
570 error_with_pos("export undefined symbol %s", name); 650 error_with_pos("export undefined symbol %s", name);
571 else { 651 else {
@@ -624,8 +704,8 @@ static void print_location(void)
624 704
625static void print_type_name(enum symbol_type type, const char *name) 705static void print_type_name(enum symbol_type type, const char *name)
626{ 706{
627 if (type != SYM_NORMAL) 707 if (symbol_types[type].name)
628 fprintf(stderr, "%s %s", symbol_type_name[type], name); 708 fprintf(stderr, "%s %s", symbol_types[type].name, name);
629 else 709 else
630 fprintf(stderr, "%s", name); 710 fprintf(stderr, "%s", name);
631} 711}
@@ -771,8 +851,8 @@ int main(int argc, char **argv)
771 851
772 if (sym->is_override) 852 if (sym->is_override)
773 fputs("override ", dumpfile); 853 fputs("override ", dumpfile);
774 if (sym->type != SYM_NORMAL) { 854 if (symbol_types[sym->type].n) {
775 putc(symbol_type_name[sym->type][0], dumpfile); 855 putc(symbol_types[sym->type].n, dumpfile);
776 putc('#', dumpfile); 856 putc('#', dumpfile);
777 } 857 }
778 fputs(sym->name, dumpfile); 858 fputs(sym->name, dumpfile);