This source file includes following definitions.
- symbol_create
- symbol_delete
- symtable_open
- symtable_close
- symtable_get
- symlist_search
- symlist_add
- symlist_free
- symlist_merge
- aic_print_file_prologue
- aic_print_include
- aic_print_reg_dump_types
- aic_print_reg_dump_start
- aic_print_reg_dump_end
- aic_print_reg_dump_entry
- symtable_dump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 #include <sys/cdefs.h>
47
48
49 #include <sys/types.h>
50
51 #ifdef __linux__
52 #include "aicdb.h"
53 #else
54 #include <db.h>
55 #endif
56 #include <fcntl.h>
57 #include <inttypes.h>
58 #include <regex.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <sysexits.h>
63
64 #include "aicasm_symbol.h"
65 #include "aicasm.h"
66
67 static DB *symtable;
68
69 symbol_t *
70 symbol_create(char *name)
71 {
72 symbol_t *new_symbol;
73
74 new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
75 if (new_symbol == NULL) {
76 perror("Unable to create new symbol");
77 exit(EX_SOFTWARE);
78 }
79 memset(new_symbol, 0, sizeof(*new_symbol));
80 new_symbol->name = strdup(name);
81 if (new_symbol->name == NULL)
82 stop("Unable to strdup symbol name", EX_SOFTWARE);
83 new_symbol->type = UNINITIALIZED;
84 return (new_symbol);
85 }
86
87 void
88 symbol_delete(symbol_t *symbol)
89 {
90 if (symtable != NULL) {
91 DBT key;
92
93 key.data = symbol->name;
94 key.size = strlen(symbol->name);
95 symtable->del(symtable, &key, 0);
96 }
97 switch(symbol->type) {
98 case SCBLOC:
99 case SRAMLOC:
100 case REGISTER:
101 if (symbol->info.rinfo != NULL)
102 free(symbol->info.rinfo);
103 break;
104 case ALIAS:
105 if (symbol->info.ainfo != NULL)
106 free(symbol->info.ainfo);
107 break;
108 case MASK:
109 case FIELD:
110 case ENUM:
111 case ENUM_ENTRY:
112 if (symbol->info.finfo != NULL) {
113 symlist_free(&symbol->info.finfo->symrefs);
114 free(symbol->info.finfo);
115 }
116 break;
117 case DOWNLOAD_CONST:
118 case CONST:
119 if (symbol->info.cinfo != NULL)
120 free(symbol->info.cinfo);
121 break;
122 case LABEL:
123 if (symbol->info.linfo != NULL)
124 free(symbol->info.linfo);
125 break;
126 case UNINITIALIZED:
127 default:
128 break;
129 }
130 free(symbol->name);
131 free(symbol);
132 }
133
134 void
135 symtable_open()
136 {
137 symtable = dbopen(NULL,
138 O_CREAT | O_NONBLOCK | O_RDWR, 0, DB_HASH,
139 NULL);
140
141 if (symtable == NULL) {
142 perror("Symbol table creation failed");
143 exit(EX_SOFTWARE);
144
145 }
146 }
147
148 void
149 symtable_close()
150 {
151 if (symtable != NULL) {
152 DBT key;
153 DBT data;
154
155 while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
156 symbol_t *stored_ptr;
157
158 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
159 symbol_delete(stored_ptr);
160 }
161 symtable->close(symtable);
162 }
163 }
164
165
166
167
168
169 symbol_t *
170 symtable_get(char *name)
171 {
172 symbol_t *stored_ptr;
173 DBT key;
174 DBT data;
175 int retval;
176
177 key.data = (void *)name;
178 key.size = strlen(name);
179
180 if ((retval = symtable->get(symtable, &key, &data, 0)) != 0) {
181 if (retval == -1) {
182 perror("Symbol table get operation failed");
183 exit(EX_SOFTWARE);
184
185 } else if (retval == 1) {
186
187 symbol_t *new_symbol;
188
189 new_symbol = symbol_create(name);
190 data.data = &new_symbol;
191 data.size = sizeof(new_symbol);
192 if (symtable->put(symtable, &key, &data,
193 0) !=0) {
194 perror("Symtable put failed");
195 exit(EX_SOFTWARE);
196 }
197 return (new_symbol);
198 } else {
199 perror("Unexpected return value from db get routine");
200 exit(EX_SOFTWARE);
201
202 }
203 }
204 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
205 return (stored_ptr);
206 }
207
208 symbol_node_t *
209 symlist_search(symlist_t *symlist, char *symname)
210 {
211 symbol_node_t *curnode;
212
213 curnode = SLIST_FIRST(symlist);
214 while(curnode != NULL) {
215 if (strcmp(symname, curnode->symbol->name) == 0)
216 break;
217 curnode = SLIST_NEXT(curnode, links);
218 }
219 return (curnode);
220 }
221
222 void
223 symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
224 {
225 symbol_node_t *newnode;
226
227 newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
228 if (newnode == NULL) {
229 stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
230
231 }
232 newnode->symbol = symbol;
233 if (how == SYMLIST_SORT) {
234 symbol_node_t *curnode;
235 int field;
236
237 field = FALSE;
238 switch(symbol->type) {
239 case REGISTER:
240 case SCBLOC:
241 case SRAMLOC:
242 break;
243 case FIELD:
244 case MASK:
245 case ENUM:
246 case ENUM_ENTRY:
247 field = TRUE;
248 break;
249 default:
250 stop("symlist_add: Invalid symbol type for sorting",
251 EX_SOFTWARE);
252
253 }
254
255 curnode = SLIST_FIRST(symlist);
256 if (curnode == NULL
257 || (field
258 && (curnode->symbol->type > newnode->symbol->type
259 || (curnode->symbol->type == newnode->symbol->type
260 && (curnode->symbol->info.finfo->value >
261 newnode->symbol->info.finfo->value))))
262 || (!field && (curnode->symbol->info.rinfo->address >
263 newnode->symbol->info.rinfo->address))) {
264 SLIST_INSERT_HEAD(symlist, newnode, links);
265 return;
266 }
267
268 while (1) {
269 if (SLIST_NEXT(curnode, links) == NULL) {
270 SLIST_INSERT_AFTER(curnode, newnode,
271 links);
272 break;
273 } else {
274 symbol_t *cursymbol;
275
276 cursymbol = SLIST_NEXT(curnode, links)->symbol;
277 if ((field
278 && (cursymbol->type > symbol->type
279 || (cursymbol->type == symbol->type
280 && (cursymbol->info.finfo->value >
281 symbol->info.finfo->value))))
282 || (!field
283 && (cursymbol->info.rinfo->address >
284 symbol->info.rinfo->address))) {
285 SLIST_INSERT_AFTER(curnode, newnode,
286 links);
287 break;
288 }
289 }
290 curnode = SLIST_NEXT(curnode, links);
291 }
292 } else {
293 SLIST_INSERT_HEAD(symlist, newnode, links);
294 }
295 }
296
297 void
298 symlist_free(symlist_t *symlist)
299 {
300 symbol_node_t *node1, *node2;
301
302 node1 = SLIST_FIRST(symlist);
303 while (node1 != NULL) {
304 node2 = SLIST_NEXT(node1, links);
305 free(node1);
306 node1 = node2;
307 }
308 SLIST_INIT(symlist);
309 }
310
311 void
312 symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
313 symlist_t *symlist_src2)
314 {
315 symbol_node_t *node;
316
317 *symlist_dest = *symlist_src1;
318 while((node = SLIST_FIRST(symlist_src2)) != NULL) {
319 SLIST_REMOVE_HEAD(symlist_src2, links);
320 SLIST_INSERT_HEAD(symlist_dest, node, links);
321 }
322
323
324 SLIST_INIT(symlist_src1);
325 SLIST_INIT(symlist_src2);
326 }
327
328 void
329 aic_print_file_prologue(FILE *ofile)
330 {
331
332 if (ofile == NULL)
333 return;
334
335 fprintf(ofile,
336 "/*\n"
337 " * DO NOT EDIT - This file is automatically generated\n"
338 " * from the following source files:\n"
339 " *\n"
340 "%s */\n",
341 versions);
342 }
343
344 void
345 aic_print_include(FILE *dfile, char *include_file)
346 {
347
348 if (dfile == NULL)
349 return;
350 fprintf(dfile, "\n#include \"%s\"\n\n", include_file);
351 }
352
353 void
354 aic_print_reg_dump_types(FILE *ofile)
355 {
356 if (ofile == NULL)
357 return;
358
359 fprintf(ofile,
360 "typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n"
361 "typedef struct %sreg_parse_entry {\n"
362 " char *name;\n"
363 " uint8_t value;\n"
364 " uint8_t mask;\n"
365 "} %sreg_parse_entry_t;\n"
366 "\n",
367 prefix, prefix, prefix);
368 }
369
370 static void
371 aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
372 {
373 if (dfile == NULL)
374 return;
375
376 fprintf(dfile,
377 "static %sreg_parse_entry_t %s_parse_table[] = {\n",
378 prefix,
379 regnode->symbol->name);
380 }
381
382 static void
383 aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
384 symbol_node_t *regnode, u_int num_entries)
385 {
386 char *lower_name;
387 char *letter;
388
389 lower_name = strdup(regnode->symbol->name);
390 if (lower_name == NULL)
391 stop("Unable to strdup symbol name", EX_SOFTWARE);
392
393 for (letter = lower_name; *letter != '\0'; letter++)
394 *letter = tolower(*letter);
395
396 if (dfile != NULL) {
397 if (num_entries != 0)
398 fprintf(dfile,
399 "\n"
400 "};\n"
401 "\n");
402
403 fprintf(dfile,
404 "int\n"
405 "%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n"
406 "{\n"
407 " return (%sprint_register(%s%s, %d, \"%s\",\n"
408 " 0x%02x, regvalue, cur_col, wrap));\n"
409 "}\n"
410 "\n",
411 prefix,
412 lower_name,
413 prefix,
414 num_entries != 0 ? regnode->symbol->name : "NULL",
415 num_entries != 0 ? "_parse_table" : "",
416 num_entries,
417 regnode->symbol->name,
418 regnode->symbol->info.rinfo->address);
419 }
420
421 fprintf(ofile,
422 "#if AIC_DEBUG_REGISTERS\n"
423 "%sreg_print_t %s%s_print;\n"
424 "#else\n"
425 "#define %s%s_print(regvalue, cur_col, wrap) \\\n"
426 " %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n"
427 "#endif\n"
428 "\n",
429 prefix,
430 prefix,
431 lower_name,
432 prefix,
433 lower_name,
434 prefix,
435 regnode->symbol->name,
436 regnode->symbol->info.rinfo->address);
437 }
438
439 static void
440 aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode)
441 {
442 int num_tabs;
443
444 if (dfile == NULL)
445 return;
446
447 fprintf(dfile,
448 " { \"%s\",",
449 curnode->symbol->name);
450
451 num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8;
452
453 while (num_tabs-- > 0)
454 fputc('\t', dfile);
455 fprintf(dfile, "0x%02x, 0x%02x }",
456 curnode->symbol->info.finfo->value,
457 curnode->symbol->info.finfo->mask);
458 }
459
460 void
461 symtable_dump(FILE *ofile, FILE *dfile)
462 {
463
464
465
466
467
468 symlist_t registers;
469 symlist_t masks;
470 symlist_t constants;
471 symlist_t download_constants;
472 symlist_t aliases;
473 symlist_t exported_labels;
474 symbol_node_t *curnode;
475 symbol_node_t *regnode;
476 DBT key;
477 DBT data;
478 int flag;
479 u_int i;
480
481 if (symtable == NULL)
482 return;
483
484 SLIST_INIT(®isters);
485 SLIST_INIT(&masks);
486 SLIST_INIT(&constants);
487 SLIST_INIT(&download_constants);
488 SLIST_INIT(&aliases);
489 SLIST_INIT(&exported_labels);
490 flag = R_FIRST;
491 while (symtable->seq(symtable, &key, &data, flag) == 0) {
492 symbol_t *cursym;
493
494 memcpy(&cursym, data.data, sizeof(cursym));
495 switch(cursym->type) {
496 case REGISTER:
497 case SCBLOC:
498 case SRAMLOC:
499 symlist_add(®isters, cursym, SYMLIST_SORT);
500 break;
501 case MASK:
502 case FIELD:
503 case ENUM:
504 case ENUM_ENTRY:
505 symlist_add(&masks, cursym, SYMLIST_SORT);
506 break;
507 case CONST:
508 symlist_add(&constants, cursym,
509 SYMLIST_INSERT_HEAD);
510 break;
511 case DOWNLOAD_CONST:
512 symlist_add(&download_constants, cursym,
513 SYMLIST_INSERT_HEAD);
514 break;
515 case ALIAS:
516 symlist_add(&aliases, cursym,
517 SYMLIST_INSERT_HEAD);
518 break;
519 case LABEL:
520 if (cursym->info.linfo->exported == 0)
521 break;
522 symlist_add(&exported_labels, cursym,
523 SYMLIST_INSERT_HEAD);
524 break;
525 default:
526 break;
527 }
528 flag = R_NEXT;
529 }
530
531
532 aic_print_file_prologue(ofile);
533 aic_print_reg_dump_types(ofile);
534 aic_print_file_prologue(dfile);
535 aic_print_include(dfile, stock_include_file);
536 SLIST_FOREACH(curnode, ®isters, links) {
537
538 switch(curnode->symbol->type) {
539 case REGISTER:
540 case SCBLOC:
541 case SRAMLOC:
542 {
543 symlist_t *fields;
544 symbol_node_t *fieldnode;
545 int num_entries;
546
547 num_entries = 0;
548 fields = &curnode->symbol->info.rinfo->fields;
549 SLIST_FOREACH(fieldnode, fields, links) {
550 if (num_entries == 0)
551 aic_print_reg_dump_start(dfile,
552 curnode);
553 else if (dfile != NULL)
554 fputs(",\n", dfile);
555 num_entries++;
556 aic_print_reg_dump_entry(dfile, fieldnode);
557 }
558 aic_print_reg_dump_end(ofile, dfile,
559 curnode, num_entries);
560 }
561 default:
562 break;
563 }
564 }
565
566
567 while (SLIST_FIRST(&masks) != NULL) {
568 char *regname;
569
570 curnode = SLIST_FIRST(&masks);
571 SLIST_REMOVE_HEAD(&masks, links);
572
573 regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs);
574 regname = regnode->symbol->name;
575 regnode = symlist_search(®isters, regname);
576 SLIST_INSERT_AFTER(regnode, curnode, links);
577 }
578
579
580 while (SLIST_FIRST(&aliases) != NULL) {
581 char *regname;
582
583 curnode = SLIST_FIRST(&aliases);
584 SLIST_REMOVE_HEAD(&aliases, links);
585
586 regname = curnode->symbol->info.ainfo->parent->name;
587 regnode = symlist_search(®isters, regname);
588 SLIST_INSERT_AFTER(regnode, curnode, links);
589 }
590
591
592 while (SLIST_FIRST(®isters) != NULL) {
593 symbol_node_t *curnode;
594 u_int value;
595 char *tab_str;
596 char *tab_str2;
597
598 curnode = SLIST_FIRST(®isters);
599 SLIST_REMOVE_HEAD(®isters, links);
600 switch(curnode->symbol->type) {
601 case REGISTER:
602 case SCBLOC:
603 case SRAMLOC:
604 fprintf(ofile, "\n");
605 value = curnode->symbol->info.rinfo->address;
606 tab_str = "\t";
607 tab_str2 = "\t\t";
608 break;
609 case ALIAS:
610 {
611 symbol_t *parent;
612
613 parent = curnode->symbol->info.ainfo->parent;
614 value = parent->info.rinfo->address;
615 tab_str = "\t";
616 tab_str2 = "\t\t";
617 break;
618 }
619 case MASK:
620 case FIELD:
621 case ENUM:
622 case ENUM_ENTRY:
623 value = curnode->symbol->info.finfo->value;
624 tab_str = "\t\t";
625 tab_str2 = "\t";
626 break;
627 default:
628 value = 0;
629 tab_str = NULL;
630 tab_str2 = NULL;
631 stop("symtable_dump: Invalid symbol type "
632 "encountered", EX_SOFTWARE);
633 break;
634 }
635 fprintf(ofile, "#define%s%-16s%s0x%02x\n",
636 tab_str, curnode->symbol->name, tab_str2,
637 value);
638 free(curnode);
639 }
640 fprintf(ofile, "\n\n");
641
642 while (SLIST_FIRST(&constants) != NULL) {
643 symbol_node_t *curnode;
644
645 curnode = SLIST_FIRST(&constants);
646 SLIST_REMOVE_HEAD(&constants, links);
647 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
648 curnode->symbol->name,
649 curnode->symbol->info.cinfo->value);
650 free(curnode);
651 }
652
653
654 fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
655
656 for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
657 symbol_node_t *curnode;
658
659 curnode = SLIST_FIRST(&download_constants);
660 SLIST_REMOVE_HEAD(&download_constants, links);
661 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
662 curnode->symbol->name,
663 curnode->symbol->info.cinfo->value);
664 free(curnode);
665 }
666 fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i);
667
668 fprintf(ofile, "\n\n/* Exported Labels */\n");
669
670 while (SLIST_FIRST(&exported_labels) != NULL) {
671 symbol_node_t *curnode;
672
673 curnode = SLIST_FIRST(&exported_labels);
674 SLIST_REMOVE_HEAD(&exported_labels, links);
675 fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n",
676 curnode->symbol->name,
677 curnode->symbol->info.linfo->address);
678 free(curnode);
679 }
680 }
681