0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #include <sys/types.h>
0046
0047 #include "aicdb.h"
0048 #include <fcntl.h>
0049 #include <inttypes.h>
0050 #include <regex.h>
0051 #include <stdio.h>
0052 #include <stdlib.h>
0053 #include <string.h>
0054 #include <sysexits.h>
0055
0056 #include "aicasm_symbol.h"
0057 #include "aicasm.h"
0058
0059 static DB *symtable;
0060
0061 symbol_t *
0062 symbol_create(char *name)
0063 {
0064 symbol_t *new_symbol;
0065
0066 new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
0067 if (new_symbol == NULL) {
0068 perror("Unable to create new symbol");
0069 exit(EX_SOFTWARE);
0070 }
0071 memset(new_symbol, 0, sizeof(*new_symbol));
0072 new_symbol->name = strdup(name);
0073 if (new_symbol->name == NULL)
0074 stop("Unable to strdup symbol name", EX_SOFTWARE);
0075 new_symbol->type = UNINITIALIZED;
0076 new_symbol->count = 1;
0077 return (new_symbol);
0078 }
0079
0080 void
0081 symbol_delete(symbol_t *symbol)
0082 {
0083 if (symtable != NULL) {
0084 DBT key;
0085
0086 key.data = symbol->name;
0087 key.size = strlen(symbol->name);
0088 symtable->del(symtable, &key, 0);
0089 }
0090 switch(symbol->type) {
0091 case SCBLOC:
0092 case SRAMLOC:
0093 case REGISTER:
0094 if (symbol->info.rinfo != NULL)
0095 free(symbol->info.rinfo);
0096 break;
0097 case ALIAS:
0098 if (symbol->info.ainfo != NULL)
0099 free(symbol->info.ainfo);
0100 break;
0101 case MASK:
0102 case FIELD:
0103 case ENUM:
0104 case ENUM_ENTRY:
0105 if (symbol->info.finfo != NULL) {
0106 symlist_free(&symbol->info.finfo->symrefs);
0107 free(symbol->info.finfo);
0108 }
0109 break;
0110 case DOWNLOAD_CONST:
0111 case CONST:
0112 if (symbol->info.cinfo != NULL)
0113 free(symbol->info.cinfo);
0114 break;
0115 case LABEL:
0116 if (symbol->info.linfo != NULL)
0117 free(symbol->info.linfo);
0118 break;
0119 case UNINITIALIZED:
0120 default:
0121 break;
0122 }
0123 free(symbol->name);
0124 free(symbol);
0125 }
0126
0127 void
0128 symtable_open()
0129 {
0130 symtable = dbopen(NULL,
0131 O_CREAT | O_NONBLOCK | O_RDWR, 0, DB_HASH,
0132 NULL);
0133
0134 if (symtable == NULL) {
0135 perror("Symbol table creation failed");
0136 exit(EX_SOFTWARE);
0137
0138 }
0139 }
0140
0141 void
0142 symtable_close()
0143 {
0144 if (symtable != NULL) {
0145 DBT key;
0146 DBT data;
0147
0148 while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
0149 symbol_t *stored_ptr;
0150
0151 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
0152 symbol_delete(stored_ptr);
0153 }
0154 symtable->close(symtable);
0155 }
0156 }
0157
0158
0159
0160
0161
0162 symbol_t *
0163 symtable_get(char *name)
0164 {
0165 symbol_t *stored_ptr;
0166 DBT key;
0167 DBT data;
0168 int retval;
0169
0170 key.data = (void *)name;
0171 key.size = strlen(name);
0172
0173 if ((retval = symtable->get(symtable, &key, &data, 0)) != 0) {
0174 if (retval == -1) {
0175 perror("Symbol table get operation failed");
0176 exit(EX_SOFTWARE);
0177
0178 } else if (retval == 1) {
0179
0180 symbol_t *new_symbol;
0181
0182 new_symbol = symbol_create(name);
0183 data.data = &new_symbol;
0184 data.size = sizeof(new_symbol);
0185 if (symtable->put(symtable, &key, &data,
0186 0) !=0) {
0187 perror("Symtable put failed");
0188 exit(EX_SOFTWARE);
0189 }
0190 return (new_symbol);
0191 } else {
0192 perror("Unexpected return value from db get routine");
0193 exit(EX_SOFTWARE);
0194
0195 }
0196 }
0197 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
0198 stored_ptr->count++;
0199 data.data = &stored_ptr;
0200 if (symtable->put(symtable, &key, &data, 0) !=0) {
0201 perror("Symtable put failed");
0202 exit(EX_SOFTWARE);
0203 }
0204 return (stored_ptr);
0205 }
0206
0207 symbol_node_t *
0208 symlist_search(symlist_t *symlist, char *symname)
0209 {
0210 symbol_node_t *curnode;
0211
0212 curnode = SLIST_FIRST(symlist);
0213 while(curnode != NULL) {
0214 if (strcmp(symname, curnode->symbol->name) == 0)
0215 break;
0216 curnode = SLIST_NEXT(curnode, links);
0217 }
0218 return (curnode);
0219 }
0220
0221 void
0222 symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
0223 {
0224 symbol_node_t *newnode;
0225
0226 newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
0227 if (newnode == NULL) {
0228 stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
0229
0230 }
0231 newnode->symbol = symbol;
0232 if (how == SYMLIST_SORT) {
0233 symbol_node_t *curnode;
0234 int field;
0235
0236 field = FALSE;
0237 switch(symbol->type) {
0238 case REGISTER:
0239 case SCBLOC:
0240 case SRAMLOC:
0241 break;
0242 case FIELD:
0243 case MASK:
0244 case ENUM:
0245 case ENUM_ENTRY:
0246 field = TRUE;
0247 break;
0248 default:
0249 stop("symlist_add: Invalid symbol type for sorting",
0250 EX_SOFTWARE);
0251
0252 }
0253
0254 curnode = SLIST_FIRST(symlist);
0255 if (curnode == NULL
0256 || (field
0257 && (curnode->symbol->type > newnode->symbol->type
0258 || (curnode->symbol->type == newnode->symbol->type
0259 && (curnode->symbol->info.finfo->value >
0260 newnode->symbol->info.finfo->value))))
0261 || (!field && (curnode->symbol->info.rinfo->address >
0262 newnode->symbol->info.rinfo->address))) {
0263 SLIST_INSERT_HEAD(symlist, newnode, links);
0264 return;
0265 }
0266
0267 while (1) {
0268 if (SLIST_NEXT(curnode, links) == NULL) {
0269 SLIST_INSERT_AFTER(curnode, newnode,
0270 links);
0271 break;
0272 } else {
0273 symbol_t *cursymbol;
0274
0275 cursymbol = SLIST_NEXT(curnode, links)->symbol;
0276 if ((field
0277 && (cursymbol->type > symbol->type
0278 || (cursymbol->type == symbol->type
0279 && (cursymbol->info.finfo->value >
0280 symbol->info.finfo->value))))
0281 || (!field
0282 && (cursymbol->info.rinfo->address >
0283 symbol->info.rinfo->address))) {
0284 SLIST_INSERT_AFTER(curnode, newnode,
0285 links);
0286 break;
0287 }
0288 }
0289 curnode = SLIST_NEXT(curnode, links);
0290 }
0291 } else {
0292 SLIST_INSERT_HEAD(symlist, newnode, links);
0293 }
0294 }
0295
0296 void
0297 symlist_free(symlist_t *symlist)
0298 {
0299 symbol_node_t *node1, *node2;
0300
0301 node1 = SLIST_FIRST(symlist);
0302 while (node1 != NULL) {
0303 node2 = SLIST_NEXT(node1, links);
0304 free(node1);
0305 node1 = node2;
0306 }
0307 SLIST_INIT(symlist);
0308 }
0309
0310 void
0311 symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
0312 symlist_t *symlist_src2)
0313 {
0314 symbol_node_t *node;
0315
0316 *symlist_dest = *symlist_src1;
0317 while((node = SLIST_FIRST(symlist_src2)) != NULL) {
0318 SLIST_REMOVE_HEAD(symlist_src2, links);
0319 SLIST_INSERT_HEAD(symlist_dest, node, links);
0320 }
0321
0322
0323 SLIST_INIT(symlist_src1);
0324 SLIST_INIT(symlist_src2);
0325 }
0326
0327 void
0328 aic_print_file_prologue(FILE *ofile)
0329 {
0330
0331 if (ofile == NULL)
0332 return;
0333
0334 fprintf(ofile,
0335 "/*\n"
0336 " * DO NOT EDIT - This file is automatically generated\n"
0337 " * from the following source files:\n"
0338 " *\n"
0339 "%s */\n",
0340 versions);
0341 }
0342
0343 void
0344 aic_print_include(FILE *dfile, char *include_file)
0345 {
0346
0347 if (dfile == NULL)
0348 return;
0349 fprintf(dfile, "\n#include \"%s\"\n\n", include_file);
0350 }
0351
0352 void
0353 aic_print_reg_dump_types(FILE *ofile)
0354 {
0355 if (ofile == NULL)
0356 return;
0357
0358 fprintf(ofile,
0359 "typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n"
0360 "typedef struct %sreg_parse_entry {\n"
0361 " char *name;\n"
0362 " uint8_t value;\n"
0363 " uint8_t mask;\n"
0364 "} %sreg_parse_entry_t;\n"
0365 "\n",
0366 prefix, prefix, prefix);
0367 }
0368
0369 static void
0370 aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
0371 {
0372 if (dfile == NULL)
0373 return;
0374
0375 fprintf(dfile,
0376 "static const %sreg_parse_entry_t %s_parse_table[] = {\n",
0377 prefix,
0378 regnode->symbol->name);
0379 }
0380
0381 static void
0382 aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
0383 symbol_node_t *regnode, u_int num_entries)
0384 {
0385 char *lower_name;
0386 char *letter;
0387
0388 lower_name = strdup(regnode->symbol->name);
0389 if (lower_name == NULL)
0390 stop("Unable to strdup symbol name", EX_SOFTWARE);
0391
0392 for (letter = lower_name; *letter != '\0'; letter++)
0393 *letter = tolower(*letter);
0394
0395 if (dfile != NULL) {
0396 if (num_entries != 0)
0397 fprintf(dfile,
0398 "\n"
0399 "};\n"
0400 "\n");
0401
0402 fprintf(dfile,
0403 "int\n"
0404 "%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n"
0405 "{\n"
0406 " return (%sprint_register(%s%s, %d, \"%s\",\n"
0407 " 0x%02x, regvalue, cur_col, wrap));\n"
0408 "}\n"
0409 "\n",
0410 prefix,
0411 lower_name,
0412 prefix,
0413 num_entries != 0 ? regnode->symbol->name : "NULL",
0414 num_entries != 0 ? "_parse_table" : "",
0415 num_entries,
0416 regnode->symbol->name,
0417 regnode->symbol->info.rinfo->address);
0418 }
0419
0420 fprintf(ofile,
0421 "#if AIC_DEBUG_REGISTERS\n"
0422 "%sreg_print_t %s%s_print;\n"
0423 "#else\n"
0424 "#define %s%s_print(regvalue, cur_col, wrap) \\\n"
0425 " %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n"
0426 "#endif\n"
0427 "\n",
0428 prefix,
0429 prefix,
0430 lower_name,
0431 prefix,
0432 lower_name,
0433 prefix,
0434 regnode->symbol->name,
0435 regnode->symbol->info.rinfo->address);
0436 }
0437
0438 static void
0439 aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode)
0440 {
0441 int num_tabs;
0442
0443 if (dfile == NULL)
0444 return;
0445
0446 fprintf(dfile,
0447 " { \"%s\",",
0448 curnode->symbol->name);
0449
0450 num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8;
0451
0452 while (num_tabs-- > 0)
0453 fputc('\t', dfile);
0454 fprintf(dfile, "0x%02x, 0x%02x }",
0455 curnode->symbol->info.finfo->value,
0456 curnode->symbol->info.finfo->mask);
0457 }
0458
0459 void
0460 symtable_dump(FILE *ofile, FILE *dfile)
0461 {
0462
0463
0464
0465
0466
0467 symlist_t registers;
0468 symlist_t masks;
0469 symlist_t constants;
0470 symlist_t download_constants;
0471 symlist_t aliases;
0472 symlist_t exported_labels;
0473 symbol_node_t *curnode;
0474 symbol_node_t *regnode;
0475 DBT key;
0476 DBT data;
0477 int flag;
0478 int reg_count = 0, reg_used = 0;
0479 u_int i;
0480
0481 if (symtable == NULL)
0482 return;
0483
0484 SLIST_INIT(®isters);
0485 SLIST_INIT(&masks);
0486 SLIST_INIT(&constants);
0487 SLIST_INIT(&download_constants);
0488 SLIST_INIT(&aliases);
0489 SLIST_INIT(&exported_labels);
0490 flag = R_FIRST;
0491 while (symtable->seq(symtable, &key, &data, flag) == 0) {
0492 symbol_t *cursym;
0493
0494 memcpy(&cursym, data.data, sizeof(cursym));
0495 switch(cursym->type) {
0496 case REGISTER:
0497 case SCBLOC:
0498 case SRAMLOC:
0499 symlist_add(®isters, cursym, SYMLIST_SORT);
0500 break;
0501 case MASK:
0502 case FIELD:
0503 case ENUM:
0504 case ENUM_ENTRY:
0505 symlist_add(&masks, cursym, SYMLIST_SORT);
0506 break;
0507 case CONST:
0508 symlist_add(&constants, cursym,
0509 SYMLIST_INSERT_HEAD);
0510 break;
0511 case DOWNLOAD_CONST:
0512 symlist_add(&download_constants, cursym,
0513 SYMLIST_INSERT_HEAD);
0514 break;
0515 case ALIAS:
0516 symlist_add(&aliases, cursym,
0517 SYMLIST_INSERT_HEAD);
0518 break;
0519 case LABEL:
0520 if (cursym->info.linfo->exported == 0)
0521 break;
0522 symlist_add(&exported_labels, cursym,
0523 SYMLIST_INSERT_HEAD);
0524 break;
0525 default:
0526 break;
0527 }
0528 flag = R_NEXT;
0529 }
0530
0531
0532 aic_print_file_prologue(ofile);
0533 aic_print_reg_dump_types(ofile);
0534 aic_print_file_prologue(dfile);
0535 aic_print_include(dfile, stock_include_file);
0536 SLIST_FOREACH(curnode, ®isters, links) {
0537
0538 if (curnode->symbol->dont_generate_debug_code)
0539 continue;
0540
0541 switch(curnode->symbol->type) {
0542 case REGISTER:
0543 case SCBLOC:
0544 case SRAMLOC:
0545 {
0546 symlist_t *fields;
0547 symbol_node_t *fieldnode;
0548 int num_entries;
0549
0550 num_entries = 0;
0551 reg_count++;
0552 if (curnode->symbol->count == 1)
0553 break;
0554 fields = &curnode->symbol->info.rinfo->fields;
0555 SLIST_FOREACH(fieldnode, fields, links) {
0556 if (num_entries == 0)
0557 aic_print_reg_dump_start(dfile,
0558 curnode);
0559 else if (dfile != NULL)
0560 fputs(",\n", dfile);
0561 num_entries++;
0562 aic_print_reg_dump_entry(dfile, fieldnode);
0563 }
0564 aic_print_reg_dump_end(ofile, dfile,
0565 curnode, num_entries);
0566 reg_used++;
0567 }
0568 default:
0569 break;
0570 }
0571 }
0572 fprintf(stderr, "%s: %d of %d register definitions used\n", appname,
0573 reg_used, reg_count);
0574
0575
0576 while (SLIST_FIRST(&masks) != NULL) {
0577 char *regname;
0578
0579 curnode = SLIST_FIRST(&masks);
0580 SLIST_REMOVE_HEAD(&masks, links);
0581
0582 regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs);
0583 regname = regnode->symbol->name;
0584 regnode = symlist_search(®isters, regname);
0585 SLIST_INSERT_AFTER(regnode, curnode, links);
0586 }
0587
0588
0589 while (SLIST_FIRST(&aliases) != NULL) {
0590 char *regname;
0591
0592 curnode = SLIST_FIRST(&aliases);
0593 SLIST_REMOVE_HEAD(&aliases, links);
0594
0595 regname = curnode->symbol->info.ainfo->parent->name;
0596 regnode = symlist_search(®isters, regname);
0597 SLIST_INSERT_AFTER(regnode, curnode, links);
0598 }
0599
0600
0601 while (SLIST_FIRST(®isters) != NULL) {
0602 symbol_node_t *curnode;
0603 u_int value;
0604 char *tab_str;
0605 char *tab_str2;
0606
0607 curnode = SLIST_FIRST(®isters);
0608 SLIST_REMOVE_HEAD(®isters, links);
0609 switch(curnode->symbol->type) {
0610 case REGISTER:
0611 case SCBLOC:
0612 case SRAMLOC:
0613 fprintf(ofile, "\n");
0614 value = curnode->symbol->info.rinfo->address;
0615 tab_str = "\t";
0616 tab_str2 = "\t\t";
0617 break;
0618 case ALIAS:
0619 {
0620 symbol_t *parent;
0621
0622 parent = curnode->symbol->info.ainfo->parent;
0623 value = parent->info.rinfo->address;
0624 tab_str = "\t";
0625 tab_str2 = "\t\t";
0626 break;
0627 }
0628 case MASK:
0629 case FIELD:
0630 case ENUM:
0631 case ENUM_ENTRY:
0632 value = curnode->symbol->info.finfo->value;
0633 tab_str = "\t\t";
0634 tab_str2 = "\t";
0635 break;
0636 default:
0637 value = 0;
0638 tab_str = NULL;
0639 tab_str2 = NULL;
0640 stop("symtable_dump: Invalid symbol type "
0641 "encountered", EX_SOFTWARE);
0642 break;
0643 }
0644 fprintf(ofile, "#define%s%-16s%s0x%02x\n",
0645 tab_str, curnode->symbol->name, tab_str2,
0646 value);
0647 free(curnode);
0648 }
0649 fprintf(ofile, "\n\n");
0650
0651 while (SLIST_FIRST(&constants) != NULL) {
0652 symbol_node_t *curnode;
0653
0654 curnode = SLIST_FIRST(&constants);
0655 SLIST_REMOVE_HEAD(&constants, links);
0656 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
0657 curnode->symbol->name,
0658 curnode->symbol->info.cinfo->value);
0659 free(curnode);
0660 }
0661
0662 fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
0663
0664 for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
0665 symbol_node_t *curnode;
0666
0667 curnode = SLIST_FIRST(&download_constants);
0668 SLIST_REMOVE_HEAD(&download_constants, links);
0669 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
0670 curnode->symbol->name,
0671 curnode->symbol->info.cinfo->value);
0672 free(curnode);
0673 }
0674 fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i);
0675
0676 fprintf(ofile, "\n\n/* Exported Labels */\n");
0677
0678 while (SLIST_FIRST(&exported_labels) != NULL) {
0679 symbol_node_t *curnode;
0680
0681 curnode = SLIST_FIRST(&exported_labels);
0682 SLIST_REMOVE_HEAD(&exported_labels, links);
0683 fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n",
0684 curnode->symbol->name,
0685 curnode->symbol->info.linfo->address);
0686 free(curnode);
0687 }
0688 }
0689