Annotation of sys/dev/microcode/aic7xxx/aicasm_symbol.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: aicasm_symbol.c,v 1.9 2003/12/24 23:27:55 krw Exp $ */
! 2: /* $NetBSD: aicasm_symbol.c,v 1.4 2003/07/14 15:42:40 lukem Exp $ */
! 3:
! 4: /*
! 5: * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
! 6: *
! 7: * Copyright (c) 1997 Justin T. Gibbs.
! 8: * Copyright (c) 2002 Adaptec Inc.
! 9: * All rights reserved.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions, and the following disclaimer,
! 16: * without modification.
! 17: * 2. Redistributions in binary form must reproduce at minimum a disclaimer
! 18: * substantially similar to the "NO WARRANTY" disclaimer below
! 19: * ("Disclaimer") and any redistribution must be conditioned upon
! 20: * including a substantially similar Disclaimer requirement for further
! 21: * binary redistribution.
! 22: * 3. Neither the names of the above-listed copyright holders nor the names
! 23: * of any contributors may be used to endorse or promote products derived
! 24: * from this software without specific prior written permission.
! 25: *
! 26: * Alternatively, this software may be distributed under the terms of the
! 27: * GNU General Public License ("GPL") version 2 as published by the Free
! 28: * Software Foundation.
! 29: *
! 30: * NO WARRANTY
! 31: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! 32: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
! 33: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
! 34: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
! 35: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 36: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 37: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 38: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 39: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
! 40: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 41: * POSSIBILITY OF SUCH DAMAGES.
! 42: *
! 43: * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.23 2003/01/20 18:01:37 gibbs Exp $
! 44: */
! 45:
! 46: #include <sys/cdefs.h>
! 47: /* __RCSID("$NetBSD: aicasm_symbol.c,v 1.4 2003/07/14 15:42:40 lukem Exp $"); */
! 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, /*flags*/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(/*filename*/NULL,
! 138: O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
! 139: /*openinfo*/NULL);
! 140:
! 141: if (symtable == NULL) {
! 142: perror("Symbol table creation failed");
! 143: exit(EX_SOFTWARE);
! 144: /* NOTREACHED */
! 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: * The semantics of get is to return an uninitialized symbol entry
! 167: * if a lookup fails.
! 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, /*flags*/0)) != 0) {
! 181: if (retval == -1) {
! 182: perror("Symbol table get operation failed");
! 183: exit(EX_SOFTWARE);
! 184: /* NOTREACHED */
! 185: } else if (retval == 1) {
! 186: /* Symbol wasn't found, so create a new one */
! 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: /*flags*/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: /* NOTREACHED */
! 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: /* NOTREACHED */
! 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: /* NOTREACHED */
! 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: /* These are now empty */
! 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: * Sort the registers by address with a simple insertion sort.
! 465: * Put bitmasks next to the first register that defines them.
! 466: * Put constants at the end.
! 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: /* Register dianostic functions/declarations first. */
! 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: /* Fold in the masks and bits */
! 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: /* Add the aliases */
! 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: /* Output generated #defines. */
! 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; /* Quiet compiler */
! 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:
CVSweb